Threads SWING mit EventQueue.invokeLater

zac12

Mitglied
Guten Tag Zusammen,
Ich programmiere zurzeit eine GUI Applikation bei welcher diverse Prozesse Parallel ablaufen sollen und arbeite deswegen mit der EventQueue.invokeLater.

Nun habe ich schon einiges programmiert, bin mir aber nicht 100% sicher ob Parallelität gegen ist, da z.B der eine Button wenn man Ihn drückt solange unten bleibt bis die grössere Funktion durchgearbeitet wurde und in dieser Zeit ein neuer Event zwar registriert wird aber die Funktion erst im Nachhinein ausgeführt wird, was mich etwas Irritiert.

Die Klasse ist ziemlich Gross, weshalb ich nicht alles Poste da es vermutlich nicht förderlich ist:
Die MAIN Methode welche das Hauptfenster mit allen Komponenten initialisiert:
Code:
public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.jtattoo.plaf.smart.SmartLookAndFeel");
                    MailClient window = new MailClient();
                    window.frmEmailClient.setVisible(true);

                } catch (Exception e) {
                    JOptionPane.showMessageDialog(frmEmailClient, e.getMessage(), "Meldung", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
    }

Die Meisten Buttons habe ich gleich aufgebaut etwa so, welche dann über den im Eventlistener die entsprechende Methode aufrufen:

Code:
// Definition des Buttons Senden/Empfangen für das senden und empfangen von Nachrichten
        JButton btnSendReceive = new JButton("Senden / Empfangen");
        btnSendReceive.setIcon(
                new ImageIcon(MailClient.class.getResource("/javax/swing/plaf/metal/icons/ocean/upFolder.gif")));
        menuBar.add(btnSendReceive);
        btnSendReceive.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //updateTitle();
                updateMail();
               
            }
        });

Die Methode welche Aufgerufen wird dann als runnable in die EventQueue eingeschleusst:

Code:
private void updateMail() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MailController controller = new MailController();
                    tableModel.empty();
                    tableModel.setMessages(controller.receiveMail());
                    System.out.println("updateMail");
                } catch (Exception e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(null, e.getMessage(), "Meldung", JOptionPane.ERROR_MESSAGE);
                }
               
            }
        });   
    }

Dies sieht etwas überall ähnlich aus.
Nun es funktioniert alles Perfekt und es gab auch niemals einen Deadlock oder sonst was, aber irgendwie bin ich mir bzgl. der Parallelität nicht sicher, ob das so korrekt ist?

Ich bedanke mich schon im Voraus für ein Feedback
Beste Grüsse
 
Bei invokeLater wird das übergebene Runnable ausgeführt, sobald der Event-Dispatch-Thread nichts mehr zu tun hat. Das heißt man kann nicht exakt sagen wann das Runnable ausgeführt wird.

In dem geposteten Beispielcode macht es jedenfalls keinen Sinn in der actionPerformed ein invokeLater aufzurufen, da actionPerformed sowieso schon im Event-Dispatch-Thread ausgeführt wird. Das Runnable wird also im selben Thread ausgeführt. Nur irgendwann später.

Bei der Verarbeitung von GUI-Events, wie z.B. das Drücken eines Buttons, möchte man rechenintensiven Code nicht im EDT ausführen, um die GUI nicht zu blockieren. Daher startet man in solchen Fällen einen Thread oder arbeitet mit einem SwingWorker: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/simple.html

Vielleicht kann das deine Frage beantworten oder bringt dich weiter.
 

Zurück
Oben