Swing Große Gui designen/gestalten

JohnnyCTW

Mitglied
Servus liebes Forum,

Ich möchte nun eine größere GUI erstellen, mit einem Haupmenü-Fenster und vielen weiteren kleinen. Nur wie geht man an so ein Unterfangen ran? Alles sollte im MVC Pattern geschrieben sein. Hab mich in die ganzen Streitfragen eingelesen bzgl GUI Klasse sollte/sollte nicht von JFrame erben, CardLayout statt mehreren JFrames... nun ja da bin ich ein bisschen überfordert.

Ich würde meine GUI Klasse von JFrame erben lassen, darauf ein CardLayout setzen und jetzt stellt sich die Frage ob ich die Panels in eigene Klassen setzen soll oder nicht. So dass jedes weitere Fenster das bei Knopfdruck geöffnet werden soll, eine eigene Klasse darstellt. Bei grob gesagt 20 Fenstern würde eine reine GUI Klasse doch explodieren oder nicht?

Ist meine Vorgehensweise richtig?
 

Harry Kane

Top Contributor
Ich möchte nun eine größere GUI erstellen, mit einem Haupmenü-Fenster und vielen weiteren kleinen.
Ich würde die Logik der ganzen "vielen weiteren kleinen Fenstern" in separate Klassen auslagern. Diese Klassen könnten z. B. von JPanel erben oder (was ich persönlich besser finde) eine Methode fillPanel(JPanel panel) anbieten, in der das übergebene JPanel mit den jeweils erforderlichen Komponenten gefüllt wird.
 

Saheeda

Top Contributor
JavaFX? Hab ich noch nie probiert. Bin es gewohnt die GUIs mit Swing zu erstellen. Inwiefern lohnt es sich nun auf FX umzusteigen?

In JavaFx kannst du die GUI mit so einer Art XML erstellen (nennt sich dort FXML), der Quellcode wird dadurch wesentlich sauberer und klarer strukturiert. Templating ist meiner Meinung nach damit auch schöner/lesbarer machbar. Und zumindest mir fällt es damit wesentlich leichter, strikt zwischen Views, Controllern und "allem anderen" zu trennen.
 

JohnnyCTW

Mitglied
Dann werde ich das Projekt hier noch mit Swing schreiben und dann zu JavaFX wechseln, danke für den Tipp!

Ich möchte ein altes Lager-Artikel Programm neu aufrollen, startet nun mit den Klassen ArticleModel, ArticleView und ArticleController, hab nun das Hauptmenü als Klasse ausgelagert und von JPanel erben lassen. So macht das für mich am meisten Sinn.

Wie strukturiere ich das dann am besten? Wenn ich später mehrere Views habe, soll dann jede View nur die JPanel-Klassen bekommen die zu der View passen? das MVC kommt mir oftmals in die Quere.
Die Views ansich erfüllen ja dann eigentlich keinen Zweck mehr oder nicht? Wenn alles ausgelagert wird...

Edit:

Schreibe nun die ersten kleineren Klassen und muss sagen, wow, alleine die Übersicht ist bereits jetzt einfach viel besser. Danke!
 
Zuletzt bearbeitet:

JohnnyCTW

Mitglied
Bin nun wiefolgt vorgegangen:

Panel Hauptmenü erstellt, Panel Hautpanel (CardLayout; welches für alle Panel zuständig ist) erstellt und das Hauptmenü im Hauptpanel hinzugefügt. Nun hab ich das Hauptpanel dem JFrame hinzugefügt.

Doch standardmäßig müsste nun ja das BorderLayout vom JFrame greifen oder?

Wenn ich nun im Hauptmenü Panel mein GridBagLayout erstelle, ist trotzdem alles zentriert und mir sind die Hände gebunden, was das Anordnen angeht.

Oder es liegt am Kaffee...

EDIT:://

Das Ding lässt mich net locker. Hab nun die Layouts geschachtelt, mein Hauptmenü besitzt nun das BorderLayout als Layout und in den jeweiligen Richtungen agieren nun weitere Panels. Somit kann ich das oben genannte vermeiden. Ich denke das sollte ein solides Konzept sein und wenn nicht, werd ichs morgen schon von euch erfahren. Danke jetzt schon!
 
Zuletzt bearbeitet:

JohnnyCTW

Mitglied
Stehe nun vor einem neuen Problem. Das oben geschrieben fließt nun perfekt ineinander ein.

Habe nun folgende Klassen

ArticleModel
ArticleController (implementiert den Listener und soll die Schaltflächen aller JPanels steuern)
GUI
HauptPanel
----> Hauptmenü (Panel1)
----> EditArticle (Panel2)

Das GUI erstellt nun das HauptPanel und fügt es hinzu. Das Hauptpanel besitzt alle anderen Panels und steuert diese durch eine Methode, die dann in der ArticleControll aufgerufen wird.

Java:
public class ArticleController {

    static GraphicalUserInterface gui;
    static ArticleModel model;
   
    public ArticleController(){
       
        gui = GraphicalUserInterface.getInstance();
        model = new ArticleModel();
        gui.createGUI();
        addListener();       
    }
   
    public void addListener(){
        gui.setActionListener(new GeneralActionHandler());
    }
   
   
    private class GeneralActionHandler implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent aE) {
            if (aE.getSource().equals(gui.hauptPanel.hauptmenu.jBnewArticle)){ //Unschön!
                gui.hauptPanel.setCards("edit");
            }
        }
    }
}


Die Zeile in der der JButton abgefragt wird ist aber ziemlich unsauber.
Hab deshalb eine Methode geschrieben, die das Hauptmenü zurückliefert, jedoch kann ich darüber nicht auf den jButton zugreifen??

Java:
public class GraphicalUserInterface extends JFrame {

    private static GraphicalUserInterface INSTANCE = new GraphicalUserInterface();
    JPanel mainPanel;
    CardLayout cardLayout;
    HauptPanel hauptPanel;
   
    public static GraphicalUserInterface getInstance(){return INSTANCE;}
    private GraphicalUserInterface(){};
   
    public void createGUI(){
       
        hauptPanel = new HauptPanel();
        setSize(800, 600);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
        add(hauptPanel);
    }

    public void setActionListener(ActionListener l){
        hauptPanel.hauptmenu.jBnewArticle.addActionListener(l);
    }

    //---> Hier die Methode
   
    public JPanel getHauptMenu(){
        return this.hauptPanel.hauptmenu;
    }

}
 

Harry Kane

Top Contributor
In bezug auf das "unschön" stimme ich dir vollkommen zu.
Ganz ehrlich: das sieht komplett chaotisch aus. Und dabei hast du noch nicht mal die Logik implementiert (also anlegen von Artikeln, Bestellungen, abbuchen von gelieferten Artikeln aus dem Bestand).
Kannst du mir erklären, warum GeneralActionHandler eine innere Klasse von ArticleController ist, wenn der Button, dem er zugeordnet ist, im hauptPanel liegt, und in der actionPerformed eine Methode aus dem hauptpanel aufgerufen werden soll?
Ohne das jetzt genau verstanden zu haben, was das ganze soll, würde ich eher dazu raten, den GeneralActionHandler in der HauptPanel-Klasse zu deklarieren. Dann hat er direkt Zugriff auf alles was er braucht. Und wenn der GeneralActionHandler wirklich nur mit einem Einzeiler eine Methode aus hauptPanel aufruft, braucht es gar keine separate GeneralActionHandler-Klasse, sondern dan tut es auch ein anonymer ActionListener.
Und was soll die getHauptMenu()-Methode in deiner GraphicalUserInterface-Klasse ? hauptPanel ist keine private Variable von GraphicalUserInterface, und hauptMenu ist offenbar auch keine private Variable von hauptPanel. Von daher kannst du auch direkt mit gui.hauptPanel.hauptmenu auf das Hauptmenu zugreifen, wie du es ja in dre ActionPerformed auch machst.
 

JohnnyCTW

Mitglied
Wenn ich dem HauptPanel den ActionListener verpassen, besitze ich doch keine Trennung mehr zwischen Daten und View oder nicht?

//Edit

Nun hat aber die Grafische Komponente den Listener implementiert. Sollte dies nicht immer der Controller tun um eine strikte Trennung zu ermöglichen?
 
Zuletzt bearbeitet:

Harry Kane

Top Contributor
Wenn ich dem HauptPanel den ActionListener verpassen, besitze ich doch keine Trennung mehr zwischen Daten und View oder nicht?
Den Satz habe ich 10x gelesen und immer noch nicht verstanden. Ich sehe nichts von "Daten".
Sollte dies nicht immer der Controller tun um eine strikte Trennung zu ermöglichen?
In deinem Beispiel sind ArticleController und das GraphicalUserInterface zwar in verschiedenen Klassen, aber durch diese ganzen Kreuz-und-Quer-Bezüge wie hauptPanel.hauptmenu.jBnewArticle.addActionListener(l) oder den Code in der actionPerformed des GeneralActionHandler doch wieder aufs innigste miteinander vermischt.
Über welche Funktionalität reden wir?
1. Es gibt einen JFrame mit einem HauptPanel drin. Der Layoutmanager des HauptPanel ist ein CardLayout.
2. Das HauptPanel hat offenbar ein hauptmenu. Ob hauptmenu ein JPanel ist oder eine JMenuBar oder eine JToolBar, ist unklar. Spielt aber auch für die Diskussion keine wirkliche Rolle.
3. Im hauptmenu gibt es einen Button, mit dem das aktive JPanel des HauptPanels gesetzt werden kann.
Dafür brauchts meiner Meinung nach keine eigene Klasse.
Wenn du unbedingt die Logik "setze im HauptPanel ein neues JPanel" in eine separate Klasse auslagern willst, würde ich das über einen simplen ActionListener machen:
Java:
public class ViewChanger implements ActionListener{
   private HauptPanel hp;
   private String cardName;
   public ViewChanger(HauptPanel hp, String cardName){
     this.hp = hp;
     this.cardName = cardName;
   }
   public void actionPerformed(ActionEvent ae){
     this.hp.setCard(cardName);
   }
}
Den ActionListener kannst du dann in der HauptPanel-Klasse instanziieren.
 

JohnnyCTW

Mitglied
Das ist eben das Problem
In deinem Beispiel sind ArticleController und das GraphicalUserInterface zwar in verschiedenen Klassen, aber durch diese ganzen Kreuz-und-Quer-Bezüge wie hauptPanel.hauptmenu.jBnewArticle.addActionListener(l) oder den Code in der actionPerformed des GeneralActionHandler doch wieder aufs innigste miteinander vermischt.

Korrigier mich bitte, wenn ich da etwas falsch verstanden habe:

Nach dem MVC-Prinzip sollte doch das Model von der View getrennt sein, sprich Berechnungen ins Model schicken, Ausgaben über die View realisieren. Wenn nun die Daten aber im Hauptmenü eingegeben werden, welches ja erst den Weg über das Hauptpanel und schließlich zum JFrame machen muss, dann muss ja trotzdem der Controller darauf zugreifen oder nicht?

Der Controller weißt doch jeder Komponente den ActionListener zu oder nicht? Bin gerade ein bisschen perplex..

Danke für deine Bemühungen


Das Model habe ich oben nicht angezeigt, da es derzeit ja noch keine Verwendung findet, solange nur der Button realisiert werden soll.
 

Harry Kane

Top Contributor
Nach dem MVC-Prinzip sollte doch das Model von der View getrennt sein, sprich Berechnungen ins Model schicken, Ausgaben über die View realisieren.
Soweit richtig. Nur hast du erstens in deinen geposteten Snippets keine Trennung zwischen wasauchimmer, und von einem Model sehe ich nach wie vor nichts.
Wenn nun die Daten aber im Hauptmenü eingegeben werden, welches ja erst den Weg über das Hauptpanel und schließlich zum JFrame machen muss, dann muss ja trotzdem der Controller darauf zugreifen oder nicht?
Sorry, den Satz habe ich nicht verstanden. Und vom "Model" ist jetzt auch keine Rede mehr.
Die Komponente, wie du sie auch immer nennen magst ("Hauptmenu" finde ich übrigens keine gute Bezeichnung für etwas, was der Dateneingabe dient), wo Daten eingegeben werden, braucht eine Referenz auf das Model, in dem die eingegebenen Daten hoffentlich landen sollen. Bei einer Änderung informiert das Model dann die Views, die sich daraufhin neu zeichnen.
 

Harry Kane

Top Contributor
Hier mal ein Beispiel, wie man die Funktionalität "Umschalten der views in einem CardLayout" umsetzen kann. Ist nur mitm texteditor geschrieben und kann deshalb massive Syntaxfehler enthalten:
Java:
public class Lagerverwaltung{
   public Lagerverwaltung(){
     JFrame f = new JFrame("Lagerverwaltung");
     Cardlayout cl = new CardLayout();
     JPanel mainView = new JPanel(cl);
     mainView.add(new JPanel(), "show");
     mainView.add(new JPanel(), "edit");
     Action showAction = new ViewChanger(cl, mainView, "show");
     Action editAction = new ViewChanger(cl, mainView, "edit");
     //Aus den Actions je nach Wunsch JButtons oder JMenuItems erzeugen
   }
}
public class ViewChanger extends AbstractAction{
  private CardLayout cl;
  private String cardName;
  private JPanel view;
  public ViewChanger(CardLayout cl, JPanel view, String cardName){
    this.cl = cl;
    this.view = view;
    this.cardName = cardName;
  }
  public void actionPerformed(ActionEvent ae){
    this.cl.show(view, cardName);
  }
}
Die ViewChanger-Klasse braucht keinen Zugriff auf die JFrame-Klasse mehr. Sie hat nur Referenzen auf die Objekte, die sie zur Erledigung ihre Aufgaben braucht.
Was mir zu deiner setActionListener(ActionListener l)-Methode noch einfällt: wenn du später nicht mehr nur den Button jBnewArticle hast, sondern noch weitere, bräuchtest du dafür weitere Methoden in der GraphicalUserInterface-Klasse. Und diese neuen Methoden sollten dann nur von neuen Controller-Klassen mit speziellen ActionListenern aufgerufen werden. Aktuell macht der Aufruf der setActionListener-Methode nur aus der ArticleController-Klasse Sinn, und dabei muss eine Instanz von GeneralActionHandler übergeben werden. Prinzipiell kann aber die setActionListener-Methode von jedem beliebigen Objekt mit jedem beliebigen ActionListener aufgerufen werden. Mir wäre das viel zu fehleranfällig.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P TreeView automatisch an große von Inhalt anpassen AWT, Swing, JavaFX & SWT 3
H zwei gleich große Panels getrennt durch ein weiteres Panel AWT, Swing, JavaFX & SWT 10
E 2D-Grafik Speicherprobleme große Tiff-Dateien AWT, Swing, JavaFX & SWT 50
J Welche(n) LayoutManager für große Gui? AWT, Swing, JavaFX & SWT 6
M Swing Große GUI - Konzept, Ideen, Vorschläge AWT, Swing, JavaFX & SWT 20
G Große dynamische ContextMenus erzeugen (Eclipse RCP) AWT, Swing, JavaFX & SWT 4
R JPanel sehr große JPanel hinzufügen AWT, Swing, JavaFX & SWT 5
T JTable / RowSorter macht große Probleme AWT, Swing, JavaFX & SWT 2
P SWT Button --> große Probleme!! AWT, Swing, JavaFX & SWT 7
D verschieden große Componenten in einem JPanel? AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
C JTree bereitet große Probleme, kann uns bitte jemand helfen! AWT, Swing, JavaFX & SWT 6
J Große Anzahl von Comboboxen in Tabelle darstellen AWT, Swing, JavaFX & SWT 2
H große mengen an jbuttons dynamisch erzeugen? AWT, Swing, JavaFX & SWT 15
Thallius JDatePicker anders designen AWT, Swing, JavaFX & SWT 1
P JScrollBar designen oder unsichtbar machen AWT, Swing, JavaFX & SWT 10
E Swing JButton neu designen AWT, Swing, JavaFX & SWT 9
B Schachfeld designen AWT, Swing, JavaFX & SWT 6
A Java Programm gestalten AWT, Swing, JavaFX & SWT 4
A Scrollbar gestalten AWT, Swing, JavaFX & SWT 2
B Link eines Icons dynamisch gestalten AWT, Swing, JavaFX & SWT 2
S JTextField "resizable" gestalten - wie? AWT, Swing, JavaFX & SWT 3
P [JTree] Markierhilfe der Drop-Location selber gestalten. AWT, Swing, JavaFX & SWT 4
C Swing GridLayout: Kann man die Spaltenbreiten variabel gestalten? AWT, Swing, JavaFX & SWT 4
Y Außergewöhnliches Fenster gestalten AWT, Swing, JavaFX & SWT 4
L Mein Kopf dreht sich... Brauche Hilfe beim GUI gestalten AWT, Swing, JavaFX & SWT 10
D Vorabberatung :) Briefe gestalten und drucken (als PDF) AWT, Swing, JavaFX & SWT 3
D Swing Button selbst gestalten AWT, Swing, JavaFX & SWT 4
B ToolTip verändern / selbst gestalten AWT, Swing, JavaFX & SWT 3
C Text in TextArea gestalten AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben