Java JFrame innerhalb des Hauptframes

PEASANT KING

Commander
Registriert
Okt. 2008
Beiträge
2.412
Hallo Leute,

ich bastel mal wieder an meiner Java Warenwirtschaft.
Da ich noch in den Anfängen stecke und gerade mal eine Datenbankklasse habe die auch funktioniert und ein AboutFrame erstellt habe ist meine Frage nun wie bekomme ich JFrames aus anderen Klassen in den Mainframe der Applikation ?

Zurzeit ist es so das alle Frames die durch Button sichtbar werden sich auch öffnen allerdings nicht innerhalb des Hauptframes meiner Applikation das soll sich ändern...
Jemand eine Idee wie ich das umsetzen kann ?
 
Naja ich versteh nur noch nicht ganz wie das funktionieren soll.
Mein Mainframe besteht aus einem JFrame -> JPanel ->Menüs bla bla.
Dann habe ich noch andere Klassen z.B. Kunde bestehend aus ->JFrame ->Panel und dann Content halt.
Aufrufen tue ich ViewKunde z.B. mit new ViewKunde().setVisible(true); was warscheinlich falsch ist es funktioniert und er ruft mir ViewKUnde auf allerdings soll das in meinem Mainframe geschehen zur Zeit wird der ausserhalb des Mainframes geladen, wie ich das umändern kann verstehe ich noch nicht ganz.
 
Ich würde ein CardLayout benutzen und einfach die cards (was JPanels sind wenn ich mich recht erinnere) durchschalten, z.B. mit einem drop down Menü. Geht aber natürlich auch mit Knöpfen.
Es sei denn du willst wirklich diesen Fenster in Fenster look erzielen, aber so klang das jetzt nicht unbedingt.
 
Fenster in Fenster Look geht mit JInternalFrame innerhalb eines JDesktopPane, CardLayout kann denke ich keine JFrames aufnehmen, das geht wohl kaum. Aber wenn man nur die Components innerhalb des JFrame braucht dann kann man mit CardLayout natürlich hin und her schalten.

edit: ich sehe gerade, du hast wohl ein ganz anderes Problem: hast du die GUI-Logik wirklich in deiner Kundenklasse drin? Deine Kundenobjekte sollten keine neuen Fenster erzeugen, sondern dein JFrame (und zwar ein und dasselbe) sollte verschiedene Kunden anzeigen können.
 
Zuletzt bearbeitet:
@carom das würde für mich jetzt bedeueten die Mainklasse bietet die GUI mit dem Frames und die anderen Klassen bilden nur den Inhalt und werden extended mit dem JFrame der Mainklasse richtig ?
 
Nein!

Du solltest es tunlichst vermeiden, für jeden möglichen Inhalt ein eigens Frame zu erzeugen (was du ja durch die Vererbung mittels 'extend' tun würdest).

Ich empfehle dir sehr dringend, dich mit dem MVC-Konzept (Model-View-Control) auseinanderzusetzen. Kurzer Einblick:
Dein Programm wird unterteilt in 3 große Blöcke. Das Model ist einzig und allein dafür verantwortlich, Informationen zu halten und in manchen Fällen zu verändern. Das View ist dafür zuständig, die im Model gespeicherten Informationen anzuzeigen. Jedes mal, wenn sich im Model etwas ändert, gibt das Model dem View bescheid, und das View kann sich dementsprechend updaten. Das Control (welches oft im View mit integriert ist), veranlasst das Model dazu, sich zu verändert. Dies geschieht in den allermeisten Fällen, wenn Benutzereingaben erfolgen.

Hier ein Beispiel:
Wir wollen simulieren, wie sich ein Bakterienstamm in einer Petrischale vermehrt (oder abstirbt).

Im Model würde man hierfür eine Datenstruktur aufbauen, die die Petrischale in eine beliebige Anzahl von Arealen unterteilt und für jedes dieser Areale speichert, ob sich ein Bakterium darin befindet oder nicht. Das Model sollte Methoden besitzen, um den Zustand eines Areals auszulesen oder es zu verändern. Außerdem ist eine Methode sinnvoll, die die aktuelle Bakteriengeneration in die nächste überführt, um Wachstum und Rückgang zu ermöglichen.

In der GUI (View+Control) wird einfach die Petrischale gezeichnet und mit unterschiedlichen Farben dargestellt, wo sich Bakterien befinden und wo nicht. Außerdem gibt es einen Knopf, mit dem die nächste Generation berechnet werden soll. Wenn man diese anklickt, wird im Model die Methode zur Berechnung der Generation ausgeführt. Sobald diese abgeschlossen ist merkt das Model, dass es sich verändert hat, und gibt dem GUI bescheid. Das GUI holt sich also den aktuellen Zustand des Model und zeichnet sich neu.
 
Ahh okay ich verstehe, ich habe schon in PHP Projekten mit dem MVC Modell gearbeitet, allerdings war die Java GUI Geschichte für mich wie eine andere Sprache von weit her.
Dann versuch ich das mal danke für die Tipps.
 
Gerne, wenn weitere Krücken benötigt werden, einfach schreien ;)
 
So ich hab mir das alles mal zu Gemüte gerführt allerdings stehe ich immernoch etwas aufm Schlauch.
Ich habe eine Klasse die den JFrame zur Verfügung stellt inklusive einer Menubar dann habe ich eine weitere Klasse die ein Panel darstellt.
Durch einen Klick auf einen Button soll dieses Panel aufgerufen werden.
Wie mache ich das ?
Ich habe es versucht indem ich beim ActionCode des Buttons eine Instanz auf die Klasse mit dem Panel erzeugt habe und dann mit add das Panel zum Frame hinzufüge allerdings bekomme ich das nicht hin :(
Ich bin irgendwie zu doof für Java...
 
Du bist nicht zu doof für Java, du weißt nur noch net, wie man ordentlich programmiert ;)
Ich sage es noch einmal: Du darfst nicht für jeden möglichen Inhalt ein eigenes Panel haben (außer natürlich, der strukturelle Aufbau) ist grundlegend verschieden.
Ansonsten, wenn du das wirklich tun willst, stimmt aber das, was du versucht hast. Das alte Panel entfernen, das neue hinzufügen.
 
Das Problem ist das das alte Panel sich nicht entfernt und das neue nicht angezeigt wird.
 
Hast du schon mal revalidate für den Haupt-Container aufgerufen, nachdem du dieses hinzufügen und entfernen durchgeführt hast?
 
Ich versteh das aber schon richtig das in meinem mainFrame alle Panels liegen müssen ?
Ich arbeite mit Netbeans und der interne GUI Builder erleichtert einiges, nur das mit add(); funktioniert nicht wenn ich ein Panel aus einer externen Klasse auf dem Frame abbilden möchte.

Edit:

Ich bekomm echt die Krise villt könnte mir Jemand mit einem kleinen Beispiel Code erklären wie ich es schaffe aus externen Klassen die Elemente im mainFrame aufzuzeigen bzw. aufzurufen.
 
Zuletzt bearbeitet:
Ich versuchs mal. Vielleicht geht das ja in die Richtung die du willst. Zumindest haben wir dann eine Grundlage auf der wir reden können :D:

Das Hauptfenster:
Code:
public class Sandbox extends JFrame
{
    private static final Dimension INITIAL_DIMENSION = new Dimension(800, 600);
    
    public static void main(String[] args)
    {
        Sandbox myTestFrame = new Sandbox();
        myTestFrame.setBounds(100, 100, INITIAL_DIMENSION.width, INITIAL_DIMENSION.height);
        myTestFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        myTestFrame.setVisible(true);
        
        SomeClass instance = new SomeClass(INITIAL_DIMENSION.width, INITIAL_DIMENSION.height);
        myTestFrame.add(instance.getPanel());
    }
}
Die "andere Klasse in der Inhalt erzeugt wird":
Code:
public class SomeClass
{
    private JPanel panel = null;
    
    public SomeClass(int width, int height)
    {
        panel = new JPanel(true);
        panel.setSize(width, height);
        panel.setBackground(Color.RED);
    }
    
    public JPanel getPanel()
    {
        return panel;
    }
}
 
Genau sowas meine ich danke, das blöde ist nur das ich die GUI mit dem Netbeans internen Builder erstellt habe, was zum einen einen sehr wüsten Code erzeugt und zum anderen findet man sich dort nicht wirklich zu recht.
 
Das kann ich absolut nachvollziehen, daher meide ich die Dinger auch soweit es geht. Dann steckt man hinterher auch mehr drin in der Materie. ;)
 
So ich habe jetzt mal angefangen alles manuell zu programmieren und es klappt auch ganz gut allerdings erzeuge ich ein JPanel in meiner Klasse mainView und adde es dem mainFrame.
Dieses Panel will sich aber auf Teufel komm raus nicht anzeigen lassen.

Hier mal der Code:
PHP:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mainApp;


//Java Klassenimporte//
import java.awt.Frame;
import javax.swing.*;
import java.awt.event.MouseEvent;

/**
 *
 * @author ******
 */
public class mainView extends JFrame {
    

    
    public mainView() {
        super();
        setTitle("SKS Business Warenwirtschaft");
        setIconImage(new ImageIcon(getClass().getResource("images/sks.png")).getImage());
        initComponents();
        setExtendedState(MAXIMIZED_BOTH);
        this.setVisible(true);          
    }
    
    private void initComponents(){
        
        mainFrame = new javax.swing.JFrame();
        mainMenu = new javax.swing.JMenuBar();
        mainPanel = new javax.swing.JPanel();
        
              
        //Dateimenu//
        JMenu_data = new javax.swing.JMenu("Datei");
        jMenuItem_exit = new javax.swing.JMenuItem("Beenden");
        jMenuItem_exit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem_exit.addMouseListener(new java.awt.event.MouseAdapter() {
        
            @Override
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jMenuItem_exitMousePressed(evt);
            }
            
            private void jMenuItem_exitMousePressed(java.awt.event.MouseEvent evt) {
                System.exit(0);
            }
        });
        
        mainMenu_edit = new javax.swing.JMenu("Bearbeiten");
        
        
        //Hilfemenu//
        JMenu_help = new javax.swing.JMenu("Hilfe");
        JMenuItem_about = new javax.swing.JMenuItem("Über...");
        JMenuItem_about.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        JMenuItem_about.addMouseListener(new java.awt.event.MouseAdapter() {
        
            @Override
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jMenuItem_aboutMousePressed(evt);
            }

            private void jMenuItem_aboutMousePressed(MouseEvent evt) {
              
            }
        });
        
        //Definition des Hauptfensters//
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.add(mainMenu);

        
        //Definition des Hauptmenus//
        mainMenu.add(JMenu_data);
        JMenu_data.add(jMenuItem_exit);
        mainMenu.add(mainMenu_edit);
        mainMenu.add(JMenu_help);
        JMenu_help.add(JMenuItem_about);
        setJMenuBar(mainMenu);
        
        //Definitionen des Hauptpanels//
        mainPanel.setSize(800,600);
        mainPanel.setBackground(Color.BLUE);


        mainFrame.add(mainPanel);      
    
    pack();
    }
    


    
    //Variablendeklaration//
    private JFrame mainFrame;
    private JPanel mainPanel;
    private JMenuBar mainMenu;
    private JMenu JMenu_data;
    private JMenu JMenu_help;
    private JMenuItem jMenuItem_exit;
    private JMenuItem JMenuItem_about;
    private JMenu mainMenu_edit;
    private Frame AboutBox;
}
 
Auch auf die Gefahr hin, dass wir immer noch aneinander vorbeireden:

Wozu erzeugst du einen weiteren JFrame, wenn deine Klasse doch schon JFrame extended? Was du machen willst (so wie ich das sehe) ist:
Code:
//mainFrame.add(mainPanel); // falsch
add(mainPanel); // richtig

//mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // falsch
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // richtig
Und noch eine Sache die mir aufgefallen ist - es gibt eine Methode namens setJMenuBar(). Verwende lieber direkt die, statt eines rohen adds zum Container. Ob es einen Unterschied macht, kann ich dir gar nicht mit Sicherheit sagen, aber da Swing ja intern recht komplex ist, würde ich nicht riskieren diese Methode zu ignorieren, auch wenn sie vielleicht nur aus convenience Gründen da ist. ;)
 
Du hast natürlich vollkommen Recht wenn ich mainView extenden lasse in JFrame ist es natürlich klar das ich keinen weitern Frame erzeugen muss.
Somit kann das Panel auch nicht dazu geaddet werden.
Jetzt funktioniert es so wie es sein soll, wunderbar danke.
 
Zurück
Oben