Modularer GUI Aufbau

DerEisige

Erfahrenes Mitglied
Hallo Leute,
ich habe mal wieder ein kleines Verständnis Problem.

Und zwar erstellen wir bei unseren schulprojekten für alle Aufgabe eine eigene GUI (z.B. Hauptfenster, Einstellungen, Artikelkarte), das heißt wenn ich die Einstellungen verändern möchte öffnet sich ein zweites Fenster in dem eigentlich fast alle Parameter gleich sind wie im Hauptfenster.

Das ist aber meiner Meinung nach keine Projektorientierte Programmierung.

Nun möchte ich die GUI über mehrere Classen zusammensetzen, also Modul für Modul.
Für ein besseres Verständnis habe ich mal ein kleines Bild gemalt.
2015-03-20_104514.jpg
Wie kann ich es nun umsetzen?
 
Zuletzt bearbeitet:
Hi

welche GUI-"Parameter"?
"Projektorientierte" Programmierung? Sicher?
Swing oder ...?

Das Einstellungsfenster (zB.) soll ja schon vom Sinn her kein alternatives Hauptfenster sein
=> es soll nicht davon erben
Und mehrere komplett verschiedene GUIs in eine Klasse stopfen geht nicht gut, bitte gleich vergessen

Es ist auf jeden Fall nicht nötig, einen größeren Codeteil mehrmals unverändert in verschiedenen Klassen zu haben.
Um da Alternativen vorzuschlagen müssten wir aber noch wissen, was bei dir eigentlich mehrfach ist...
Die Einstellungsgui wird ja wohl kaum eine 1:1-Kopie der Hauptgui enthalten?
(wenn doch, dann da umdenken, was man eigentlich drin haben will)

Zeig vllt. einmal zwei Klassen zur Gegenüberstellung
 
Zuletzt bearbeitet:
Danke erst mal aber ich habe mein Anliegen wohl nicht richtig beschrieben.
Also noch mal.
Wen ich eine GUI mit Swing programmiere geht man ja so vor.

1. Erstellen der Klasse
2. Frame Erstellen
Definiten der Standard werte:
Start Größe
Minimum Größe
DefaultClose
setLookAndFeel​
3. Erstellen von JMenuBar
4. Dan das Main Panel erstellen
4.1. Weitere Panel erstellen und mit Komponenten bestücken.

also ungefähr so:
Code:
package benutzeroberflaeche;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.UIManager;

import javax.swing.SpringLayout;
import java.awt.Dimension;

public class Hauptfenster {

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
     
        EventQueue.invokeLater(new Runnable() {
         
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception e) {
                    System.err.println("Setting Look and Feel Failed");
                }
                try {
                    Hauptfenster window = new Hauptfenster();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Hauptfenster() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setAutoRequestFocus(false);
        frame.setMinimumSize(new Dimension(600, 400));
        frame.setBounds(100, 100, 600, 410);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
     
        JMenu mnNewMenu = new JMenu("Datei");
        menuBar.add(mnNewMenu);
     
        JMenuItem mntmNeustart = new JMenuItem("Neustart");
        mnNewMenu.add(mntmNeustart);
     
        JMenuItem mntmBeenden = new JMenuItem("Beenden");
        mnNewMenu.add(mntmBeenden);
     
        JMenu mnEinstellungen = new JMenu("Einstellungen");
        menuBar.add(mnEinstellungen);
     
        JMenu mnHilfe = new JMenu("Hilfe");
        menuBar.add(mnHilfe);
     
        JMenuItem mntmHilfe = new JMenuItem("Hilfe");
        mnHilfe.add(mntmHilfe);
     
        JMenuItem mntmLogErstellen = new JMenuItem("Log erstellen");
        mnHilfe.add(mntmLogErstellen);
     
        JMenuItem mntmberPaket = new JMenuItem("\u00DCber Paket");
        mnHilfe.add(mntmberPaket);
     
        JMenuItem mntmSpeden = new JMenuItem("Speden");
        mnHilfe.add(mntmSpeden);
        SpringLayout springLayout = new SpringLayout();
        frame.getContentPane().setLayout(springLayout);
     
        JPanel jpFooterBar = new JPanel();
        springLayout.putConstraint(SpringLayout.WEST, jpFooterBar, 0, SpringLayout.WEST, frame.getContentPane());
        springLayout.putConstraint(SpringLayout.EAST, jpFooterBar, 0, SpringLayout.EAST, frame.getContentPane());
        springLayout.putConstraint(SpringLayout.NORTH, jpFooterBar, -20, SpringLayout.SOUTH, frame.getContentPane());
        springLayout.putConstraint(SpringLayout.SOUTH, jpFooterBar, 0, SpringLayout.SOUTH, frame.getContentPane());
        frame.getContentPane().add(jpFooterBar);
        jpFooterBar.setLayout(new SpringLayout());
     
        JPanel panel = new JPanel();
        springLayout.putConstraint(SpringLayout.NORTH, panel, 0, SpringLayout.NORTH, frame.getContentPane());
        springLayout.putConstraint(SpringLayout.WEST, panel, 0, SpringLayout.WEST, jpFooterBar);
        springLayout.putConstraint(SpringLayout.SOUTH, panel, -20, SpringLayout.SOUTH, frame.getContentPane());
        springLayout.putConstraint(SpringLayout.EAST, panel, 0, SpringLayout.EAST, frame.getContentPane());
        frame.getContentPane().add(panel);
    }
}
Nun sollen die schritte 1-3 immer gleich sein und jeweils nur das Main Panel ausgetauscht werden.
Daher dachte ich mir es wäre sinnvoll die schritte 1-3 in eine Superklasse zu packen und die einzelne Pales also schritt 4 in Subklassen.
 
Zuletzt bearbeitet:
Hi,

klar kannst du das so machen, hab ich selbst auch schon. Da es sonst zu viel Code in einer Klasse ist, teile ich meine Bereiche sowieso in mehrere Klassen auf (die alle von JPanel erben), wenn ich z.B. ein großes Fenster mit BorderLayout habe, wo jeder Bereich eine eigene individuelle Funktion bereitstellen soll.

Für dein Anliegen würde ich zuerst eine eigene Frame-Klasse zusammenbauen, die nur den Frame erzeugt, ohne Panels (also Schritt 1 bis 3), welches du dann für jedes deiner Fenster instanziieren kannst. Deine Hauptpanels für jeden deiner Frames werden dann eigene Klassen, die dann Schritt 4 bzw. 4.1 und evtl. weitere übernehmen. Dann "bestückst" du deine Frames nur mit dem jeweiligen Hauptpanel und fertig.

Gruß
Daniel
 
Improof genau so meinte ich das auch, mein Problem ist nur das ich gerade den Code Aufbau nicht hinbekomme oder auch nur vorstellen kann, wäre also nett wenn du ein kleines Code Beispiel machen könntest.
 
Hi,

ich hab gerade leider nicht so viel Zeit, aber morgen werde ich dir schnell was zusammenbasteln :)

Gruß
Daniel
 
So, dann mal ran an den Speck :D

Erstmal dein Frame (nenne ich DefaultFrame, da die einzelnen Frames deines Programms evtl. Sonderfunktionen benötigen. Dann kannst du davon erben. Natürlich könntest du auch eine abstrakte Vaterklasse machen, dann wäre die Benennung allerdings eher AbstractFrame).

Java:
public class DefaultFrame extends JFrame
{
    DefaultFrame(JPanel contentPane)
    {
        // Eigenschaften setzten (z.B. Größe, Position, DefaultClose, usw.)
       
        this.setContentPane(contentPane);
    }
}


Nun brauchst du deine Panels. Entweder baust du dir wieder eine Vaterklasse auf oder du lässt alle direkt von JPanel erben (kommt ganz darauf an, wie der konkrete Anwendungsfall ist).

Java:
public class TestPanel extends JPanel
{
    TestPanel()
    {
        // Set Layout usw.
       
        JButton testButton = new JButton("Click me!");
        testButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Hello World!");
            }
        });
       
        this.add(testButton);
    }
}

Und jetzt noch der Zusammenbau:

Java:
public static void main(String[] args)
{
    EventQueue.invokeAndWait(new Runnable() {
        @Override
        public void run() {
            TestPanel testPanel = new TestPanel();
            DefaultFrame testFrame = new DefaultFrame(testPanel);
            testFrame.setVisible(true);
        }
    });
}


Ich hab den Code jetzt nur schnell zusammen geschmissen und nicht explizit getestet, sollte aber funktionieren :)

Gruß
Daniel
 
Zurück