GUI-Controller Konzept

d3rbastl3r

Bekanntes Mitglied
Hallo,
ich habe für mich ein System erstellt wie ich die GUI-oberflächen ansteuere, bei welchem ich auf verbesserungsvorschläge hoffe 😀
In diesem Thread soll es nur darum gehen wie und wo man am besten den Thread der GUI starten soll um möglichst nicht fehleranfällig zu sein.

Nehmen wir an ich habe ein JFrame was von einem Controller gesteuert wird:
Das JFrame ist an der stelle nicht Runnable sondern der Controller der diesen implementiert
Java:
public class Controller implements Runnable{
    private MyJF myJF;

    public Controller(){
        try{
            EventQueue.invokeAndWait(this);
        }catch(InterruptedException e){
            //TODO Fehlerbehandlung
        }catch(InvocationTargetException e){
            //TODO Fehlerbehandlung
        }
    }

    private void init() {
        try {
            this.myJF = new MyJF();
            this.myJF.setVisible(false);
        } catch (Exception e) {
            //TODO Fehlerbehandlung
        }
    }

    public void setVisible(Boolean _visible){
        this.myJF.setVisible(_visible);
    }

    @Override
    public void run() {
        init();
    }
}

Fallen euch irgendwelche mängel auf, die beim späteren Programmablauf fehler, im bezug auf Threads(EventQueue.invokeAndWait), verursachen könnten??

Einen Lösungsansatz hätte ich, und zwar könnte man eine ImplementierungsKlasse schreiben die dann den Controller Implementiert und den Thread startet.
z.B.:
Java:
public class ImplProgram{
    public static Controller implController(){
        Controller controller = new Controller();

        // Dieser block würde dann natürlich in der ControllerClasse wegfallen
        try{
            EventQueue.invokeAndWait(controller);
        }catch(InterruptedException e){
            //TODO Fehlerbehandlung
        }catch(InvocationTargetException e){
            //TODO Fehlerbehandlung
        }
    
        return controller;
    }
}

Habt ihr da bessere lösungen im bezug auf GUI und Threads ??
 
Zuletzt bearbeitet:
ähm ... nur mal am rand : alles was mit GUI zu tun hat läuft automatisch im EventDispatchThread ...
wenn man nun an i-eine graphische component n listener dranhängt sollte man in dessen implementierung alles in einen Thread packen und diesen dann starten damit die GUI nicht freezed ... so einfach ... klappe zu thema closed
 
ähm ... nur mal am rand : alles was mit GUI zu tun hat läuft automatisch im EventDispatchThread ...
wenn man nun an i-eine graphische component n listener dranhängt sollte man in dessen implementierung alles in einen Thread packen und diesen dann starten damit die GUI nicht freezed ... so einfach ... klappe zu thema closed

Wenn eine GUI automatisch in einem Thread läuft, dann verstehe ich den erzeugten CodeAbschnitt von NetBeans bei einem JFrame nicht
Java:
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
 
ähm ... nur mal am rand : alles was mit GUI zu tun hat läuft automatisch im EventDispatchThread ...

Nein. Damit die GUI im EDT läuft ist
Java:
java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });

notwendig (anstatt der EventQueue kann man auch SwingUtilities nehmen). Wenn man Änderungen an der GUI vornimmt ist es nie verkehrt hierfür den SwingWorker zu verwenden.
 
Wenn man Änderungen an der GUI vornimmt ist es nie verkehrt hierfür den SwingWorker zu verwenden.

Also wenn ich das ganze richtig verstanden habe, kann eine Rechenoperation, die in dem Thread der GUI (z.B.: des einzelnes Frames), diese GUI / Frame / Thread blockieren. Damit dieser Fall nicht eintritt kann man diese Operation in einem SwingWorker ausführen was einen weiteren Thread generiert um diese rechenoperation durchzuführen.
Ist eine ganz interessante möglichkeit. 🙂

Ich versuche jedoch in meinen Programmen die GUI und die rechenoperationen unabhängig von einander laufen zu lassen.
Java:
public class Controller {
    public Controller(){
        java.awt.EventQueue.invokeLater(new Runnable(){
            public void run() {
                new MyJFrame().setVisible(true);
            }
        });
    }
}
Hier werden die Rechenoperationen (im Controller) außerhalb des JFrames-Threads durchgefürt.
Leider kann ich an dieser stelle auf die einzelnen Methoden des JFrames nciht mehr zugreifen (zumindest nicht direkt)

Wie könnte ich das Ganze so umbauen dass mein MyJFrame in einem Thread läuft und ich aus meinem Controller einen direkten zugriff auf die Public-Methoden meines JFrames habe ???

Gibt es eine Möglichkeit meinen JFrame aus dem EventDispatcher raus zu nehmen ?? Wenn ich z.B.: die Visibility der oberfläche auf false setze soll dieser keine Rechenleistung mehr beanspruchen.
 
du kannst den Frame außerhalb definieren. Es reicht, wenn du über invokeLater das setVisible aufrufst. Das ist das, was im EDT laufen soll. Deine Rechnoperationen hast du dann immernoch von dem GUI getrennt. Und ja: wenn beides in einem Thread läuft, wird eine Sache blockiert.
 
Habe nun etwas Recherche betrieben und etwas rum experementiert, mal sehen ob ich das ganze nun richtig verstanden habe xD

Die main-Methode wird in einem "main-Thread" gestartet.
EventQueue hat einen eigenen Thread (nur einen einzigen, egal vieviele aufgaben man hier reinschiebt). mit invokeLater() kann ich aufgaben in die Warteschlange des EventsQueue schieben.
Möchte man nun ein drittes, viertes, fünftes, ... Thread erstellen so erstellt man sich einfach eine Klasse die ein Thread erweitert ... so kann man diese in einem eigenem Thread laufen lassen.
Alternativ kann man mit dem SwingWorker ebenfalls aufgaben in weiteren Threads abarbeiten ohne dass man den MainThread oder den EventQueueThread blokiert.

Korrigiert mich falls ich da was falsch verstanden habe xD
 

Neue Themen


Zurück
Oben