Ich habe ein Problem mit meinem Java Programm und hoffe, dass ihr mir weiterhelfen könnt.
Folgende Situation:
Ich habe ein Programm, welches die für uns in der Produktion wichtigen Daten zusammen sucht. Leider kommt es, je nach Auslastung des System, zu Ladezeiten von bis zu 15 Skeunden, deshalb wollte ich ein Startfenster programmieren.
Dieses Fenster sollte nichts anderes machen, als einen Text anzuzeigen (“Starte Programm .”) und dann immer wieder einen Punkt hinzufügen, bis zu einem maximum von 5 (“Starte Programm . . . . .”) und dann wieder bei einem Punkt beginnen. Das funktioniert für sich alleine stehend auch wunderbar, aber leider nicht, wenn ich es aus dem Hauptprogramm herraus aufrufen will.
Hier mal kurz ein wenig (gekürzten) Quellcode:
Das “Wartzeit-Frame”
* Create the frame.
*/
public OpenFrame() {
setTitle("Starte Programm");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(100, 100, 263, 84);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblStarteProgramm = new JLabel("Starte Programm");
lblStarteProgramm.setFont(new Font("Tahoma", Font.BOLD, 12));
lblStarteProgramm.setBounds(10, 11, 115, 24);
contentPane.add(lblStarteProgramm);
validate();
setVisible(true);
new Thread(this).start();
}```
Und das Hauptframe:
```/**
* Erstellet das Frame
*/
private void createFrame() {
[...]
//Erzeugung des Grundgerüstes (Tab Pane und Menüleiste)
[...]
//Abfrage von Benutzer und Passwort, der Dialog ist Modal, blockiert also die weitere Ausführung
PasswortDialog pd = new PasswortDialog();
pd.setVisible(true);
benutzer = pd.getUser();
passwort = pd.getPassword();
//Nach der Eingabe von Benutzername und Passwort soll das JFrame geöffnet werden
if(of == null) {
of = new OpenFrame();
}
of.start();
[...]
//Erzeugung der restlichen Panels
[...]
//Nach diesem Muster werden nun mehrere Threads angelegt, die die Daten zusammensuchen, die bereits
//beim Starten des Programms benötigt werden
Thread initMas = new Thread() {
@Override
public void run() {
masPanel = new SortPanel(true, benutzer, passwort);
masPanel.setBounds(10, 11, 1306, 910);
panel_1.add(masPanel);
}
};
[...]
//Hier werden alle Threads gestartet
initMas.start();
//Und anschließend wird gewartet, dass alle fertig sind
while(initMas.isAlive()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Um dann das oben geöffnete Fenster zu schließen und dieses Frame anzuzeigen
of.setVisible(false);
setVisible(true);
}```
Starte ich das Programm jetzt, sieht mein JFrame leider so aus:
Es wird also scheinbar blockiert, mein Versuch mit dem EventQueue.invokeLater() brachte auch keinen wirklichen Erfolg, da er das Fenster erst anzeigen würde, nachdem bereits das setVisibile(false) ausgeführt wurde.
Mit freundlichen Grüße
Gossi
ich verstehe nicht so ganz, was Du da versuchst …
Was soll das “new Thread(this).start();” am Ende von “OpenFrame” machen ??
Erzeuge doch einfach das Fenster und setzte es im Hauptprogramm solange es angezeigt werden soll mit “setVisible(true)” auf **sichtbar ** und anschließend auf **unsichtbar ** mit “setVisible(false)” (oder besser gleich “dispose”) !
ich verstehe nicht so ganz, was Du da versuchst …
Was soll das “new Thread(this).start();” am Ende von “OpenFrame” machen ??
Erzeuge doch einfach das Fenster und setzte es im Hauptprogramm solange es angezeigt werden soll mit “setVisible(true)” auf **sichtbar ** und anschließend auf **unsichtbar ** mit “setVisible(false)” (oder besser gleich “dispose”) !
Gruß Klaus[/QUOTE]
Zu Punkt 1 (new Thread(this).start(); )
Das Ruft die Run Methode auf, damit sich der Text ändert:
Starte Programm .
Starte Programm . .
[…]
Starte Programm . . . . .
Starte Programm .
usw.
Zu Punkt 2:
Genau das Versuche ich ja, aber dabei bekomme ich das leere Fenster, welches ich oben mit angehängt habe als Grafik.
Da dieses Fenster eigentlich angezeigt werden soll, bevor das Hauptfenster zu sehen ist, ist eine ProgressBar schlecht einzubinden
Aber ich bin grad dabei das etwas anders zu schreiben um diese Problematik zu umgehen.
Um ein Frame zu schließen sollte man lieber dispose() statt setVisible(false) nutzen. Auch lässt der Code auf extends JFrame/JDialog schließen > ganz böses Design. Dann denke ich so an den Klassiker: ernst anzeigen und dann zusammenbauen. Dann noch NullLayout …
Kurz und knapp: die paar Fetzen reichen schon um sagen zu können: dein GUI-Code scheint ziemlicher Mist zu sein und bedarf erstmal einem sauberen re-write. Dadurch dürfte sich dann das Problem sicher von selbst lösen.
Ansonsten: Spaghetti-code ahoi - du kannst es zwar sicher fixen, aber der Code der dann dabei raus kommt dürfte die absolute Katastrophe werden.
Alternative ist ein JFrame-Objekt zu erstellen und darauf aufzurufen,
je nach Strenge kann man diese Vererbung für unnötig halten,
du würdest ja sicher auch nicht von einer ArrayList erben nur weil du danach 20x add() und get() aufrufen musst,
aber Swing-Komponenten sind dafür irgendwie anfällig, mache ich auch häufig,
liegt auch etwas näher, jedes JFrame oder besonderes Unter-JPanel ist stark individualisiert, konfiguriert, ein Einzelstück
eine eigene Klasse muss oft so oder so her, zur Verwaltung aller enthaltenen Komponenten,
wenn nicht geerbt dann normalerweise keine Oberklasse und nur 1:1 Attribut mit komplizierteren Aufrufen…
aber gilt wiederum für ArrayList teils genauso, Objektivität spricht gegen Vererbung
oft genug setzten Moderatoren wie ich auf ‘Erledigt’,
und was immer hier das genaue Problem war außer der JFrame-Vererbungsfrage habe ich bis heute nicht genau verfolgt, aber entweder Standardproblem oder sonstiger individueller Fehler in simpler JFrame-Zusammensetzung,
das hilft so gut wie keinem, hier groß nachzuverfolgen, wo der Fehler lag,
keine eindeutige Fehlermeldung/ Suchbegriff der je wieder hierherführen wird
-> Moral von der Geschichte: ‘bitte an Lösung denken’-Postings sind für sich schon fragwürdig User belastend, hier vom Thema her unnötig und halbe Woche später unnötig Thread wiederbelebend,
bitte auf sowas eher verzichten, vorsichtig und defensiv einsetzen, keine Gieskanne,
zum Glück ja auch recht selten zu lesen, umso ungewöhnlicher warum in diesem Thema
Kurz zu meiner Verteidigung, ich hab das Thema nicht auf Erledigt gesetzt, da ich bis heute morgen das Problem noch nicht komplett gelöst hatte.
Die Lösung war in meinem Fall, dass ich die Oberfläche von Grund auf neu aufgesetzt habe.
Aber für alle die für sowas (wie ich in diesem Falle) den Eclipse WindowBuilder benutzen:
Der baut in der main-Methode ein Konstrukt was ungefähr so aussieht:
@Override
public void run() {
try{
ScanViewGui frame = new ScanViewGui();
frame.setVisible(true);
catch (Exception ex) {
ex.printStackTrace();
}
}
});```
Nachdem ich das umgeändert hatte in:
```ScanViewGui frame = new ScanViewGui();
frame.setVisible(true);```
Funktioniert die Geschichte mit dem Frame wunderbar. Naja, jetzt hab ich wenigstens ne sauber aufgesetzte GUI ohne extends JFrame :D
Mit einem anderen L&F (oder, THEORETISCH* auch schon mit der nächsten Java-Version) könnte das aber nicht mehr funktionieren. Das GUI muss normalerweise so (d.h. auf dem Event Dispatch Thread) aufgebaut werden.
THEORETISCH, weil es SO viele Snippets und Beispiele gibt (selbst von Sun/Oracle), wo das NICHT gemacht wird, dass klar ist, dass es “praktisch immer” auch anders funktionieren wird. Aber ich habe schon L&Fs gesehen, wo sowas schlicht abgekachelt ist.