#1 6. April 2011 Modales JDialog in Thread Huhu, ich hab mal wieder nen Problem Folgendes: Ich will eine eigene Klasse schreiben die Runnable implementiert und somit Thread fähig ist! Die Klasse soll einen eigenen Thread starten, der ein JDialog öffnet, welches Modal ist und ein kleines Icon (ne gif Animation) in nem Label laufen lässt in der Mitte vom Screen. Also sprich, wenn das Programm beschäftigt ist und der Benutzer keinen Input mehr machen darf, soll die Oberfläche durch das Modale JDialog gesperrt werden! Jetzt mein Prob. hab die Klasse soweit Fertig, aber ich kann iwie den Thread nicht richtig starten. Hier mal ein paar Code Schnipsel: Code: public class WarteWorker implements Runnable { JDialog jDia; JLabel animation = new JLabel(""); JFrame frame; public WarteWorker(JFrame frame){ jDia = new JDialog(frame, true); this.frame = frame; jDia.setAlwaysOnTop(true); jDia.setEnabled(false); jDia.setResizable(false); jDia.setUndecorated(true); animation.setIcon(new ImageIcon(getClass().getResource("/loader.gif"))); jDia.add(animation); jDia.setSize(30, 30); center(jDia); } public void close(){ System.out.println("Closing WarteWorker"); jDia.setModal(false); jDia.setVisible(false); jDia = null; } @Override public void run() { jDia.setVisible(true); System.out.println("WarteThread gestartet!"); } void center(java.awt.Component com) { Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); int x = (int) (screen.getWidth() / 2) - com.getWidth() / 2; int y = (int) (screen.getHeight() / 2) - com.getHeight() / 2; com.setLocation(x, y); } } Starten tu ich den Thread auf ein ActionEvent für nen Button: So hatte ich mir das vorgestellt: Code: public static void connect(String arg1) { Thread warteThread = new Thread(new WarteWorker(mainFrame)); // mainFrame ist der zu sperrende Frame! System.out.println("Starting WarteThread"); warteThread.start(); // Thread für den JDialog wird gestartet! /* * Hier kommt elend langer Code :D der im Hintergrund abgearbeitet wird * Dabei werden auch kleine Veränderungen am mainFrame durchgeführt */ warteThread.stop(); } connect() wird nach nem Button Klick ausgeführt! So zum Problem: Der Thread wird erst am Ende der Methode connect() gestartet, wenn er eig. geschlossen werden soll! Sprich die Methode wird durchgearbeitet, ist fertig, der Thread startet das blöde gif wird in der Mitte angezeigt und sperrt die komplette GUI, obwohl das ja währen der Ausführung von connect() passieren sollte!!! Liegt es vllt. daran, dass der JDialog im neuen Thread modal ist, sprich der JFrame gesperrt ist, aber im Code noch Änderungen daran vorgenommen werden? Aber gesperrt sollte ja eig. nur heißen, dass der Benutzer nichts mehr machen darf? Die Klasse WarteWorker wollte ich halt auch noch für paar andere Auktionen verwenden. Ein Kollege meinte ich soll den mist grad umdrehen, sprich den HauptCode in nem eigenen Thread starten und im normalen den JDialog raushauen, aber das klappt auch nicht ganz! Merci fürs durchlesen und evt. Hilfe =) + Multi-Zitat Zitieren
#2 6. April 2011 AW: Modales JDialog in Thread Das wäre zumindest sauberer. Zeit- oder rechenaufwändigen Code solltest du in eigene Threads auslagern, und nicht im Main-Thread ausführen und die Anzeige auslagern. Zu deinem Prob: was in einem eigenen Thread läuft, ist die run() Methode und nicht die ganze Klasse. Die existiert (meines Wissens) im Kontext des Main-Threads, daher funktioniert das bei dir nicht. + Multi-Zitat Zitieren
#3 11. April 2011 AW: Modales JDialog in Thread Ok ich habs jetzt hingekriegt, dass der Hauptcode in nem eigenen Thread gestartet wird und dieses icon, dass die GUI sperrt im Main Thread dann läuft. Aber jetzt muss ich für jeden CodeTeil ne eigene Threading Klasse schreiben und der Code von diesem Wartefenster (der ja immer gleich bleibt) läuft immer schön im Main Thread ab. Ich dachte mehr an ne Klasse wo ich immer dieses Wartefenster aufrufen kann, habs jetzt auch versucht den Code in ne eigene Klasse zu schieben und dann auszuführen, klappt aber noch nich so ganz. Deswegen wollt ich eig. dieses Fenster in nem eigenen Thread laufen lassen, um mir Arbeit zu ersparen Ich habs jetzt noch veruscht mit 2 Threads das ganze zu machen. Sprich der Hauptcode läuft in nem eigenen Thread und dieses JDialog mit dem Icon läuft auch in nem eigenen Code. Dann wird auf den Thread mit dem Hauptcode mit join() gewartet und danach der JDialog Thread wieder geschlossen: Code: Thread ww = new Thread(new WarteWorker(mainFrame)); Thread t = new Thread(new ConnectionWorker(true)); try { t.start(); ww.start(); t.join(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } ww.stop(); Code: public class WarteWorker implements Runnable{ JFrame frame; public WarteWorker(JFrame frame){ this.frame = frame; } @Override public void run() { JDialog jDia = new JDialog(frame, true); jDia.setAlwaysOnTop(true); jDia.setEnabled(false); frame.setEnabled(false); jDia.setResizable(false); jDia.setUndecorated(true); JLabel animation = new JLabel(); animation.setIcon(new ImageIcon(jDia.getClass().getResource( "/loader.gif"))); jDia.add(animation); jDia.setSize(30, 30); center(jDia);//wird nur zentriert System.out.println("Sperre " + frame.getName()); jDia.setVisible(true); } } Aber mit den 2 Threads hab ich wieder den gleichen Stress wie am Anfang xD + Multi-Zitat Zitieren
#4 11. April 2011 AW: Modales JDialog in Thread GUI Elemente in einen eigenen Thread auslagern macht man nicht. Wenn du wirklich vorhast sowas nutzloses zu machen musst du dich viel tiefer in Swing einlesen, was aber absolut sinnlos wäre. Threads sind für Berechnungen da und dafür solltest du das auch nur einsetzen. "Multithreaded GUIs" gibt es nur in Webanwendungen + Multi-Zitat Zitieren
#5 11. April 2011 AW: Modales JDialog in Thread Da stimme ich dir ganz und garnicht zu, NOS. Ich gebe NOS da voll und ganz Recht (nachdem ichs nochmal gelesen habe). Guis gehören immer in einen eigenen Thread (Stichwort: SwingUtilities.invokeLater(new Runnable()...)) Man möchte nicht, dass die GUI blockiert, falls etwas anderes endlos läuft. Ansonsten wird es wohl SEHR schwer einen "Abbrechen"-Button für irgendwas zu haben. Da die GUI ja nicht reagiert (da nicht in einem eignen Thread). Klar - man kann alle Funktionen, die von der GUI aus aufgerufen werden auch in Threads auslagern. Ist aber nur bedingt Sinnvoll. (neuen Thread starten, nur weil man ne Datei speichern will ? (z.B.)). Aber da wünsche ich sehr viel Spaß mit der Synchronisierung und dergleichen. Genauso kann man dann natürlich auch die GUI etc aktualisieren, während andere Threads laufen etc. pp. Ansonsten ist da nicht viel mit aktuellen Infos auf der GUI. Generelle Faustregel: GUI Bekommt einen eigenen Thread. Genauso wie rechenintensive Funktionen welche bekommen. Oder eben auch Funktionen, welche man verteilt/nebenläufig haben will. (Erhöhung des Durchsatzes) + Multi-Zitat Zitieren
#6 11. April 2011 AW: Modales JDialog in Thread @test@private.co Du widersprichst mir, aber schreibst das gleiche nochmal hin? GUI hat einen Thread (im Normalfall der Main Thread) und nicht mehrere Threads? Genau das hab ich doch geschrieben. Der Threadersteller möchte die GUI in mehrere Threads aufsplitten und das halte ich für nicht sinnvoll. + Multi-Zitat Zitieren
#7 11. April 2011 AW: Modales JDialog in Thread Ah sorry. Habs falsch verstanden. - Ich dachte mit Elemente meinst du "nen komplettes Fenster". Ja natürlich. Einzelne Elemente kommen in den selben Thread. Nen weiteres Fenster wäre ggf auch nen eigener Thread. + Multi-Zitat Zitieren