[Java] Modales JDialog in Thread

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von unix, 6. April 2011 .

Schlagworte:
  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 =)
     
  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.
     
  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
     
  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
     
  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)
     
  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.
     
  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.
     
  8. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.