# klassenübergreifende JPanels auf ein JFrame



## chrisUBER (14. Mai 2011)

Guten Tag,

ich habe mich ein wenig in diesem Forum eingelesen und dabei gehofft, dass ich eine genauere Lösung für mein Problem finden werde. Leider bin ich nicht fündig geworden und wende mich jetzt direkt an euch.

Bis jetzt habe ich immer kleinere Java Anwendungen erstellt (mit dem Netbeans GUI Builder), welche alle über ein einziges JFrame laufen und die Elemente auf dem JFrame sich nicht ändern (andere Anordnung zum Beispiel).

Nun habe ich ein etwas größeres Projekt vor meiner Nase. Das Programm soll wie folgt aussehen:







Meine vorgehensweise war bis jetzt: Ich erstelle mit Netbeans Gui Builder ein JFrame und lasse dieses erstmal leer. Daraufhin erstelle ich zwei weitere Klassen mit extends JPanel (JPanel 1 wird mein menü, JPanel 2 mein panel mit dem inhalt) und baue dort meine Oberflächen zusammen. Am Ende gehe ich in das JFrame und erstelle 2 neue JPanel Objekte und füge sie dann mit .add(JPanel) zu dem JFrame hinzu.

Das Problem ist nun, ich bin mir recht unsicher ob dies überhaupt eine schlaue Vorgehensweise ist. Dies ist mein erstes Programm, welches eine "richtige" Menüführung bekommen soll. Außerdem möchte ich dieses Vorhaben recht einfach gestalten, damit ich bei der weiteren Programmierung nicht durcheinander komme.

Das erste JPanel kann ich problemlos zu dem JFrame hinzufügen, sobald ich das zweite per .add hinzufüge, wird das erste sofort überschrieben. 

Ich habe auch schon im Internet nach einigen Anleitungen gesucht, jedoch findet man über die GUI Programmierung fast nur Beispiele über Anwendungen ohne "wechselnden" Aufbau.

das JFrame in dem der Inhalt angezeigt werden soll, sozusagen das "Hauptfenster":

```
public class AppWnd  extends JFrame {

       public AppWnd() {

        JFrame frame = new JFrame("Programm");
       
        frame.setSize(790,560);
        frame.setResizable(false);
 
        JPanel pn = new Navigation();
        JPanel pn2 = new Inhalt();
        pn2.setBounds(150, 150, 150, 150);
        frame.add(pn);
        frame.add(pn2);
        
        frame.setVisible(true);

    }
```

Das JPanel mit der Navigation (in initComponents werden alle Elemente wie Buttons etc. hinzugefügt):

```
public class Navigation extends javax.swing.JPanel {

    /** Creates new form Navigation */
    public Navigation() {
        initComponents();
    }
```

Das gleiche für den Inhalt:

```
public class Inhalt extends javax.swing.JPanel {

    /** Creates new form Inhalt */
    public Inhalt() {
        initComponents();
    }
```


Der Text wird nun immer länger und ich bin dabei mich selbst zu verwirren  also nochmal eine kurze Zusammenfassung:

Habe 1 JFrame, möchte Jpanels (jeweils eigene Klassen) auf dem JFrame anzeigen und diese nachher per Knopfdruck ändern.

Wäre sehr dankbar über einen kleinen Denkanstoß. Ich möchte natürlich keinen komplett fertigen Code, denn der Lerneffekt bleibt dann auf der Strecke  Mich interessiert, wie so etwas "einfach" realisiert wird. Eventuell hat ja auch jemand eine gute Anleitung wo solch ein Projekt beschrieben wird.

Falls ich etwas wichtiges vergessen habe, bitte zögert nicht dies zu sagen  Bin auch recht neu in der GUI Programmierung, also seid bitte nicht so streng mit mir 

Vielen Dank schonmal für die Antworten

MfG Chris


----------



## Camino (14. Mai 2011)

Hallo, du könntest dir mal das CardLayout anschauen. Damit kannst du mehrere Panel übereinander anordnen und sagen, welches davon angezeigt werden soll.


----------



## Kilinat (14. Mai 2011)

Also mein Vorschlag: 

Du machst eine Klasse "DeinFrame extends JFrame" ... 
Eine weitere Klasse: "DeinPanel extends JPanel". 

In deine Panel Klasse erzeugst du nun 2 neue Panels und fügst in eines dein Panel1 mit 3 Buttons ein und ins andere dein Panel2. Dann einfach mit this.add(panel1) und this.add(panel2) deinem "DeinPanel" hinzufügen. ( Musst natürlich den richtigen LayoutManager verwenden, dass das so aussieht, wie du willst. ) 

So nun holst du dir in deiner "DeinFrame" Klasse die ContentPane...

```
Container cp = getContentPane();
```

... und addest dein Panel Objekt...

```
cp.add(InstanzVonDeinPanel);
```

Hoffe ich hab dir damit geholfen.. 
MfG


----------



## chrisUBER (14. Mai 2011)

Vielen Dank schonmal, sobald ich zuhause bin werde ich es sofort versuchen.

Wie ist das mit dem CardLayout? habe bis jetzt nur mit absolute und free Layout was gemacht. Wie gesagt, kriege die Oberflächen nur durch zusammenklicken hin  Ist sowas nur mit CardLayout möglich? Würde gerne bei dem jetzigen Layout bleiben, da man dort die Elemento pixel genau versetzen kann, sehr angenehm zu erstellen.

Mein Fehler war/ist, dass ich viele Teile des Programmes schon fertig habe, jedoch für jedes aufgerufene Menü habe ich ein seperates JFrame. Nun möchte ich alles in einem Frame haben und ich bin total verwirrt und kriege so etwas scheinbar einfaches nicht zum laufen. Bei Button 1 soll als Inhalt ein Kalender angezeigt werden, bei Button 2 eine Übersicht meiner Termine und der dritte Button ist ein kleines Notizbuch. Diese Funktionen laufen befriedigend gut (werden noch optimiert), jedoch alle nicht in einem einizgen Fenster. Das kann doch nicht so schwierig sein  oder... anscheinend doch 

Sobald ich es ausprobiert habe, melde ich mich 

Gruß Chris


----------



## chrisUBER (14. Mai 2011)

Ok habe es mal so aufgebaut wie du es sagtest, das Frame öffnet sich, jedoch bleibt es leer. Liegt das evtl. am Layout ? oder habe ich irgendwo einen Fehler eingebaut

DeinFrame:

```
public class DeinFrame extends javax.swing.JFrame {

    /** Creates new form DeinFrame */
    public DeinFrame() {
        
       initComponents();
       Container cp = getContentPane();
       JPanel pn = new DeinPanel();

       cp.add(pn);
       cp.setVisible(true); //nur zum testen hinzugefügt, keine ahnung ob notwendig

 

    }

    @SuppressWarnings("unchecked")  // der von Netbeans generierte GUI Code
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DeinFrame().setVisible(true);
            }
        });
    }
```

DeinPanel:

```
public class DeinPanel extends javax.swing.JPanel {

    /** Creates new form DeinPanel */
    public DeinPanel() {

        
        initComponents();
        this.add(jPanel1);
        this.add(jPanel2);

        setVisible(true); //auch keine Ahnung ob notwendig oder nicht
    }

    @SuppressWarnings("unchecked") //Auch hier wieder der von Netbeans GUI generierte Code
    
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jButton1.setText("jButton1");

        jButton2.setText("jButton2");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addContainerGap(27, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton2)
                .addContainerGap(48, Short.MAX_VALUE))
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jLabel1.setText("jLabel1");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addContainerGap(56, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addContainerGap(75, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(50, 50, 50)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(132, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(42, 42, 42)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(154, Short.MAX_VALUE))
        );
    }
```


Habe ich irgendwas falsch umgesetzt, nach deiner Anleitung? Übersehe ich irgendetwas? Habe erstmal nur dein einfaches Beispiel nachgebaut um das Prinzip zu verstehen.


----------



## Camino (14. Mai 2011)

Du solltest dir mal im Internet Infos zu LayoutManagern suchen. Damit kannst du dir deine Komponenten besser anordnen. Du kannst auch mehrere LayoutManager ineinander schachteln, damit du ein Ergebnis so erhalten kannst, wie du möchtest.

Beim CardLayout erstellst du mehrere Panels und fügst sie dem CardLayout hinzu. Kannst du dir so in etwa wie einen Kartenstapel vorstellen. Dann kannst du festlegen, welches der Panel ganz oben liegt, also sichtbar ist. So kannst du bequem zwischen den Panels wechseln.


----------



## Spin (14. Mai 2011)

Ich habe mir dein Screen Shot angeschaut und finde das du mit verschiedene Layout Manager arbeiten solltest.

Bitte lasse die Finger vom GUI Bilder. Dieser macht viel zu viel Code, den keiner versteht.

Dein Frame bekommt : Null Layout ( hoffe dein Frame hat eine feste Größe)
Ausrichten durch setBounds();

Dein Panel mit den Buttons bekommt Box Layout - schönes vertikales arbeiten 
Dein anderes Panel bekommt CardLayout, welches andere Panels beinhaltet , see Camino.

mit cardlayout#show kannst du per Event immer alles auswechsln. Genau so wie du dir das vorstellst, grüße Spin

Poste hier deine Versuche mit den Layouts und wir helfen gerne  grüße

Baue aber alles selbst. Fragen sind gerne erwünscht


----------



## chrisUBER (14. Mai 2011)

Ok, das hört sich bei euch alles so einfach an  jetzt hat mich auch der Ehrgeiz gepackt und ich will es komplett alleine machen. Das schöne an dem Gui Builder ist halt, dass ich direkt eine Vorschau in Netbeans sehe und die Buttons mit der Maus so verrücken kann, wie ich möchte  Hatte da immer so meine Schwierigkeiten, wenn ich das nur über den Code versucht habe.

Mein bisheriges "Werk": Habe ein JFrame gemacht mit fester Größe, Menüleiste und NullLayout. Eine weitere Klasse als JPanel mit BoxLayout und 3 Buttons. Bis hier hin erstmal und nicht weiter  Fehler im Code selber werden mir nicht markiert jedoch bekomme ich nun einen Pointer Error?


frame:

```
public class frame extends javax.swing.JFrame {

    /** Creates new form mainWindow */
    public frame() {
 
        //Elemente
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();
        jPanel1 = new javax.swing.JPanel();

        //Options
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setSize(790,560);
        setLayout(null);

        //Adds
        jMenu1.setText("Programm");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Hilfe");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);


        //Navigationspanel einfügen
        navi nav = new navi(); //FEHLER ???

        jPanel1.add(nav);
        
        
    }

    // Variables declaration - do not modify
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration

}
```

navi panel:

```
public class navi extends javax.swing.JPanel {

    /** Creates new form Navigation */
    public navi() {
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();

        setBorder(javax.swing.BorderFactory.createTitledBorder("Menü"));
        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));

        jButton1.setText("Übersicht");
        add(jButton1);

        jButton2.setText("Kalender");
        add(jButton2);

        jButton3.setText("Notizen");
        add(jButton3);
    }

    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;

}
```

und die kleine main:

```
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       new frame().setVisible(true);
    }

}
```

Sobald ich die mit dem Kommentar "Fehler" markierte Zeile entferne, öffnet sich das Frame. Jedoch sehe ich die Buttons nicht. Sobald ich die Zeile wieder einfüge, erhalte ich folgenden Fehler und es öffnet sich kein Frame:


```
Exception in thread "main" java.lang.NullPointerException
        at tgselbst.navi.<init>(navi.java:25)
        at tgselbst.frame.<init>(frame.java:41)
        at tgselbst.Main.main(Main.java:18)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)
```

Ist die Vorgehensweise, wie ich das Panel zum Frame hinzufügen will so überhaupt richtig? Synatx scheint in Ordnung zu sein, denke mal ich habe es einfach irgendwo verbockt 

Sobald diese 2 Dinge laufen, könnte ich dann ja die weiteren Panels erstellen mit dem CardLayout (bin schon ganz nervös ).

PS. Gibt es eigentlich keinen Edit Button? oder übersehe ich auch diesen? ???:L 

Gruß Chris

*Edit:*

Das mit dem Fehler hat sich erledigt, habe vergessen bei dem Panel oben Button 3 zu erzeugen ))
Jetzt öffnet sich das Fenster, jedoch wird mir das Panel nicht angezeigt, das Frame ist leer (bis auf die Menüleiste oben).

Irgendwas stimmt an meiner Denkweise nicht, sehe einfach die Logik dahinter nicht. Hilfeee


----------



## Camino (14. Mai 2011)

Bei dir fehlt beim Frame das 
	
	
	
	





```
setVisible(true);
```
Du solltest die Klassen-Namen mit einem Grossbuchstaben beginnen, also Frame anstatt frame.
Welchen Edit-Button meinst du?

Ich würde dir auch empfehlen, erstmal beim Frame anstatt dem Null-Layout das BorderLayout zu nehmen. Der JFrame hat standardmäßig das BorderLayout, brauchst du also nicht unbedingt zuweisen. Da ist das Fenster in 5 Bereiche aufgeteilt oben (=NORTH), unten (=SOUTH), links (=WEST), rechts (=EAST) und in der Mitte (=CENTER). In jeden dieser Bereiche kannst du eine Komponente legen, z.B. ein JPanel, welches dann auch wieder ein eigenes Layout haben kann (z.B. BoxLayout oder CardLayout).


----------



## chrisUBER (14. Mai 2011)

Ich meinte den Edit Button im Forum, der komischerweise auf einmal aufgetaucht ist 

Das Beste.... es funktioniert! Vielen herzlichen Dank. Es sieht zwar alles noch aus wie direkt vom Müll, aber ich glaube ich habe das System verstanden und werde nun mein schon angefangenes Projekt versuchen mit dieser Methode umzusetzen.

Wenn ich mir mein jetziges Programm mit all den JFrames anschaue und daran denke, dass alles umzubauen, wird mir schon wieder schwindelig 

Ich werde mich nun mit dem Layoutmanager beschäftigen, damit man sich das Programm nachher auch anschauen kann. Werde mich melden sobald ich einen kleinen Fortschritt habe 

Den Tipp mit den Klassennamen habe ich gerne angenommen und es sofort geändert


Gruß Chris


----------



## L-ectron-X (14. Mai 2011)

Der Edit-Button ist jetzt für dich da, weil ich deinen Account frei geschaltet habe.
Oder was denkst du, was du bei "Muss Aktivierungs-E-Mail noch bestätigen..." noch zu tun hast? 

Zum Thema:
Vielleicht helfen dir folgende Vorlagen:


```
import javax.swing.*;

public class Main {
  public Main(String title) {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    
    JFrame frame = new JFrame(title);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
  
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Main("DEMO");
      }
    });
  }
}
```


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MainPanel extends JPanel implements ActionListener {
  private JButton button1, button2, button3;
  private JPanel redPanel, greenPanel, bluePanel, cardPanel;

  public MainPanel() {
    super(new BorderLayout());
    
    add(createTitlePanel(), BorderLayout.NORTH);
    add(createButtonPanel(), BorderLayout.WEST);
    add(createCardPanel(), BorderLayout.CENTER);
  }
  
  //Erzeugt Überschrift
  private JPanel createTitlePanel() {
    JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    panel.setBorder(BorderFactory.createEtchedBorder());
    panel.setBackground(Color.WHITE);

    JLabel title = new JLabel("LayoutManager-Mix");
    title.setFont(title.getFont().deriveFont(16.0f));
    
    panel.add(title);
    return panel;
  }
  
  //Erzeugt Menü-Buttons (links)
  private JPanel createButtonPanel() {
    JPanel panel = new JPanel(new GridBagLayout());
    panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), BorderFactory.createTitledBorder("Auswahl")));
    GridBagConstraints gbc = new GridBagConstraints();
    
    button1 = new JButton("Rot färben");
    button1.addActionListener(this);
    
    button2 = new JButton("Grün färben");
    button2.addActionListener(this);
    
    button3 = new JButton("Blau färben");
    button3.addActionListener(this);
    
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1.0;
    gbc.insets = new Insets(5, 5, 0, 5);
    
    panel.add(button1, gbc);
    
    gbc.gridy = 1;
    gbc.insets = new Insets(5, 5, 0, 5);
    panel.add(button2, gbc);
    
    gbc.gridy = 2;
    gbc.insets = new Insets(5, 5, 5, 5);
    gbc.anchor = GridBagConstraints.NORTH;
    gbc.weighty = 1.0;
    panel.add(button3, gbc);
    
    return panel;
  }
  
  //Erzeugt die Panels mit variablem Inhalten
  private JPanel createCardPanel() {
    redPanel = new JPanel();
    redPanel.setBackground(Color.RED.darker());
    
    greenPanel = new JPanel();
    greenPanel.setBackground(Color.GREEN.darker());
    
    bluePanel = new JPanel();
    bluePanel.setBackground(Color.BLUE.darker());
    
    cardPanel = new JPanel(new CardLayout());
    cardPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 0, 10, 10), BorderFactory.createTitledBorder("Inhalte")));
    cardPanel.setPreferredSize(new Dimension(550, 500));
    
    cardPanel.add(redPanel, "RedPanel");
    cardPanel.add(greenPanel, "GreenPanel");
    cardPanel.add(bluePanel, "BluePanel");
    
    return cardPanel;
  }
  
  //Ereignisbehandlung für Menü-Buttons
  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    CardLayout cards = (CardLayout)cardPanel.getLayout();
    
    if(source == button1) {
      cards.show(cardPanel, "RedPanel");
    }
    else if(source == button2){
      cards.show(cardPanel, "GreenPanel");
    }
    else if(source == button3) {
      cards.show(cardPanel, "BluePanel");
    }
  }
}
```

Quellcode in der ausführbaren Jar-Datei


----------



## chrisUBER (14. Mai 2011)

Das Beispiel dort ist genau sowas, was ich gesucht habe 

Danke.

Ich habe nun mein Projekt so umgebaut, wie es von euch vorgeschlagen wurde.

Habe 1 JFrame, 2 Panel (eins mit BoxLayout fürs Menü und eins mit CardLayout für den Content). Jedoch habe ich nun ein weiteres Problem mit dem CardLayout.

Zum Testen und verstehen habe ich mir ein kleines Beispiel aus dem Forum kopiert:


```
public class Content  extends javax.swing.JPanel {

    public Content() {
        
         this.setBorder(javax.swing.BorderFactory.createTitledBorder("Inhalt"));

         try{
			 JPanel hpanel=new JPanel();
			 CardLayout card=new CardLayout();
                            JPanel panel1=new JPanel();
                            JPanel panel2=new JPanel();
                            JPanel panel3=new JPanel();
			 hpanel.setLayout(card);
                            panel1.add(new Calendar());         //funktioniert nicht
                            panel2.add(new JLabel("Panel2"));  // funktioniert
                            panel3.add(new JLabel("Panel3"));
                            hpanel.add(panel1,"1");
                            hpanel.add(panel2,"2");
                            hpanel.add(panel3,"3");
                         this.add(hpanel);
                            card.show(hpanel,"1"); //welches panel soll angezeigt werden
			 this.setSize(400,400);
			 this.setVisible(true);
			 } catch(Exception e){
				 System.out.println(e.toString());
			 }
			 }

    }
```

Wie gesagt, mache es nur so um das Prinzip zu verstehen und dieses Beispiel sieht recht einfach aus.
Wenn ich nun das Panel "1" anzeigen lassen will, öffnet sich das Frame aber das Panel mit CardLayout bleibt leer. Sobald ich das Panel "2" anzeigen lassen will, wird mir das jLabel mit "Panel2" angezeigt.

Was mache ich schon wieder falsch?  Das CardLayout ansich funktioniert. Aber anstatt ein jLabel aufzurufen, will ich ein weiteres Panel in das CardLayout Panel laden.

Der Code wird natürlich nachher angepasst und so umgeändert, dass ich die Auswahl des Panels mit Buttons durchführen kann. Scheitere aber mal wieder an der einfachen Version.

Gruß Chris


----------



## Camino (15. Mai 2011)

Ich hab's mal ein bisschen umgeändert. Evtl. müsste es so klappen:

```
public class Content  extends javax.swing.JPanel {
 
    public Content() {
        
         this.setBorder(javax.swing.BorderFactory.createTitledBorder("Inhalt"));

         this.setSize(400,400);

         CardLayout cardLayout = new CardLayout();
         this.setLayout(cardLayout);

         JPanel panel1=new JPanel();
         JPanel panel2=new JPanel();
         JPanel panel3=new JPanel();

         panel1.add(new Calendar());         //funktioniert nicht
         panel2.add(new JLabel("Panel2"));  // funktioniert
         panel3.add(new JLabel("Panel3"));

         this.add(panel1,"1");
         this.add(panel2,"2");
         this.add(panel3,"3");

         cardLayout.show(this,"1"); //welches panel soll angezeigt werden

         }
 
    }
```




chrisUBER hat gesagt.:


> Wenn ich nun das Panel "1" anzeigen lassen will, öffnet sich das Frame aber das Panel mit CardLayout bleibt leer. Sobald ich das Panel "2" anzeigen lassen will, wird mir das jLabel mit "Panel2" angezeigt.



Evtl. musst du auf dem 1. Panel das new Calendar() noch in ein JLabel reinsetzen, damit es auf dem Panel auch angezeigt wird.
Auf dem Panel2 hast du ein JLabel gesetzt, deshalb wird auch das Panel angezeigt, auf dem sich ein JLabel befindet.


----------



## chrisUBER (15. Mai 2011)

Es hat geklappt, lag aber mal wieder an den Layout, hatte meine anderen Panel noch im NullLayout, damit hat es leider nicht geklappt. Muss darauf in Zukunft nun mehr achten, kann ja nicht angehen 

Jetzt muss ich das cardLayout nur noch so umbauen, damit ich es mit den Buttons steuern kann.

Ich bedanke mich nochmal herzlich bei euch allen. Seid eine super Hilfe 

Gruß Chris


----------



## chrisUBER (15. Mai 2011)

Hi, ich bin es nochmal.

Muss den Thread noch einmal kurz missbrauchen, jedoch für ein neue Baustelle (Cardlayout bzw. Wechsel der "Karten").

Das Prinzip des CardLayouts ist es, dass ich im laufenden Betrieb des Programmes zwischen den einzelnen Cards wechseln kann, richtig?  Habe nun versucht das CardLayout in meinem Projekt umzusetzen. 

Natürlich habe ich auch da wieder ein Problem 


```
public class Content  extends javax.swing.JPanel {

    JPanel hpanel=new JPanel();
    CardLayout card=new CardLayout();
    JPanel panel1=new JPanel();
    JPanel panel2=new JPanel();
    
    public Content() {
        
         this.setBorder(javax.swing.BorderFactory.createTitledBorder("Inhalt"));

                            hpanel.setLayout(card);
                            panel1.add(new Overview());
                            panel2.add(new Events());
                            hpanel.add(panel1,"Overview");
                            hpanel.add(panel2,"Events");

                            this.add(hpanel);
                            
                            //card.show(hpanel,"Overview"); //funktioniert beim ausführen
                            //card.show(hpanel,"Events");    //funktioniert beim ausführen

                            this.setVisible(true);
			

    }

    public void showPanel(String panel) {

        card.show(hpanel,panel);  //funktioniert nicht
      
        System.out.println(panel); //Kontrollausgabe ob der Wert aus Klasse Navi übergeben wird, funktioniert Ausgaben sind "Overview" und "Events"

    }
```

Sobald ich einen Button in der Klasse Navi drücke, wird die Methode showPanels in der Klasse Content aufgerufen. Diese Methode wird mit der Variablen panel ausgeführt welche den Wert "Overview" oder "Events" hat. Nun wechselt das CardLayout im laufenden Betrieb aber nicht zwischen diesen beiden Panels. Ist meine Methode falsch oder dort einfach nicht richtig?

Wenn ich in der Methode Content() die Kommentare entferne und card.show(hpanel, "Overview") (oder "Events) eingebe, wird das gewünschte Panel beim Programmstart angezeigt.

Wo liegt (mal wieder ) mein Fehler?

Gruß Chris


----------



## Camino (15. Mai 2011)

Hmm, schwer zu sagen, ohne deine Klasse Navi zu kennen...

Um die Klasse Content mal ein klein bisschen zu vereinfachen: es würde evtl. auch ausreichen, wenn du der Klasse Content (welche ja von JPanel erbt) das CardLayout gibst. Dann brauchst du nicht noch extra ein weiteres JPanel (bei dir hpanel).


----------



## chrisUBER (15. Mai 2011)

Die Navi Klasse steht weiter oben schon, habe nicht viel dran geändert (außer den actionlistener)

Navi:

```
public class Navi extends javax.swing.JPanel {

    /** Creates new form Navigation */
    public Navi() {
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        
        this.setBorder(javax.swing.BorderFactory.createTitledBorder("Menü"));
        this.setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));


        //Button 1 (Kalender)
        jButton1.setText("Kalender");
        jButton1.setAlignmentX(CENTER_ALIGNMENT);
        jButton1.setMaximumSize(new java.awt.Dimension(150, jButton1.getMaximumSize().height));
        this.add(jButton1);

        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                String panel = "Overview";
                Content buttonPushed = new Content();
                buttonPushed.showPanel(panel);
            }
        });


        //Button 2 (Events)
        jButton2.setText("Events");
        jButton2.setAlignmentX(CENTER_ALIGNMENT);
        jButton2.setMaximumSize(new java.awt.Dimension(150, jButton2.getMaximumSize().height));
        this.add(jButton2);

        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                String panel = "Events";
                Content buttonPushed = new Content();
                buttonPushed.showPanel(panel);

            }
        });

        //Button 3 (Notizen)
        jButton3.setText("Notizen");
        jButton3.setAlignmentX(CENTER_ALIGNMENT);
        jButton3.setMaximumSize(new java.awt.Dimension(150, jButton2.getMaximumSize().height));
        this.add(jButton3);

        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                String panel = "Notizen";
                Content buttonPushed = new Content();
                buttonPushed.showPanel(panel);
            }
        });

    }

    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
   
}
```

In der Klasse Content wird die Variable panel korrekt übergeben (als Bestätigung erhalte ich als system.out den inhalt der Variablen, "Overview" oder "Events"). Also müsste die Übergabe ja problemlos klappen oder nicht? Dann müsste der Fehler ja in der Klasse Content stecken.

Ich drücke auf den Button Events -> ruft die Methode showPanel in der Klasse Content auf und übergibt die Variable panel = "Events" an die Methode -> die Methode soll show.cards ausführen mit dem Wert der Variable Panel (in diesem Fall "Events) -> es soll auf das korrekte Panel gewechselt werden. Klingt für mich logisch, für meinen Compiler nicht  Vielleicht kommt einer auf die Lösung ohne viel an dem Programmaufbau zu ändern 

Der Content Klasse das Cardlayout zu geben ist eine gute Idee, garnicht dran gedacht.

*Edit 

Habe einige system.out.println eingefügt um zu sehen ob die Variablen richtig übergeben werden. Durch den Button1 wird die Methode in der Klasse Content (showPanels) aufgerufen und mir wird der Wert der Variablen panel richtig angezeigt. Dort sehe ich also kein Problem.

In der Methode showPanel kommt der Wert "Events" oder "Overview" richtig an, also sollte der Befehl card.show(hpanel, panel); auch einen der beiden Werte erhalten. Normalerweise sollte dann doch auf das richtige Panel gewechselt werden, quasi on the fly bei Knopfdruck. Klappt jedoch nicht, es wird nur das Panel angezeigt, welches ich bei Programmstart definiert habe. Danach ändert sich nichts mehr 

Gruß Chris


----------



## Camino (15. Mai 2011)

Oh weja, so wie es aussieht, hast du grundlegende Fehler bezüglich deinem Java-Code in deiner Navi-Klasse. Du erzeugst immer wieder neue Content-Objekte (mit new Conent). Du solltest aber von der Conent-Klasse einmal ein Objekt erzeugen, dies dann der Navi-Klasse übergeben, dann hast du auch in der Navi-Klasse Zugriff auf den Content. Es gab weiter oben schon mal ein Beispiel (von L-ectron-X), wie das Zusammenspiel mit den Komponenten (Buttons, ActionListener, Panels) funktioniert. Dies kannst du einfach erweitern und ausbauen...
Ich versuch gleich mal, deine Navi-Klasse umzuschreiben...


----------



## Camino (16. Mai 2011)

Also, hier nochmal die 3 Klassen: Test (startklasse main und JFrame), Navi (JPanel mit den Buttons) und MainPanel (JPanel mit den Content-Panels)

```
import java.awt.BorderLayout;

import javax.swing.JFrame;

public class Test
extends JFrame {

	
	public Test() {
		
		// Titel des Frame
		setTitle("Test");
		
		// Grösse des Frame setzen
		setSize(400, 400);
		
		// Framegrösse nicht veränderbar
		setResizable(false);
		
		// Frame zentriert auf dem Bildschirm anzeigen
		setLocationRelativeTo(null);
		
		// Frame terminiert auch die Anwendung.
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// Objekt von MainPanel erzeugen
		MainPanel mainPanel = new MainPanel();
		
		// Objekt von Navi erzeugen --> Objekt mainPanel übergeben, damit Navi Zugriff darauf hat
		Navi naviPanel = new Navi(mainPanel);
		
		// Navi in den linken Bereich (=WEST) des BorderLayouts hinzufügen
		add(naviPanel, BorderLayout.WEST);
		
		// MainPanel in den zentralen Bereich (=CENTER) des BorderLayouts hinzufügen
		add(mainPanel, BorderLayout.CENTER);
		
		setVisible(true);
		
	}


	// mit der main-Methode startet das Programm
	public static void main(String[] args) {
		new Test();
	}

}
```


```
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JPanel;


public class Navi
extends JPanel
implements ActionListener {
	
	private MainPanel mainPanel;
	
	private JButton jButton1, jButton2, jButton3;
	
	// Konstruktor
	public Navi(MainPanel mainPanel) {
		
		// Hiermit bekommst du Zugriff auf das übergebene Objekt mainPanel
		this.mainPanel = mainPanel;
		
		setBorder(javax.swing.BorderFactory.createTitledBorder("Menü"));
		
		// Button-Objekte erstellen
		jButton1 = new JButton("Kalender");
        jButton2 = new JButton("Events");
        jButton3 = new JButton("Notizen");
        
        // ActtionListener den Buttons hinzufügen
        jButton1.addActionListener(this);
        jButton2.addActionListener(this);
        jButton3.addActionListener(this);
        
        // Grösse der Buttons festlegen
        jButton1.setMaximumSize(new Dimension(100, 24));
        jButton2.setMaximumSize(new Dimension(100, 24));
        jButton3.setMaximumSize(new Dimension(100, 24));
        
        Box box = Box.createVerticalBox();
        
        box.add(jButton1);
        box.add(jButton2);
        box.add(jButton3);
        
        this.add(box);
		
	}

	// In dieser Methode änderst du das anzuzeigende Panel
	// über die showPanel-Methode in mainPanel
	public void actionPerformed(ActionEvent e) {

		if(e.getActionCommand().equals("Kalender"))
			mainPanel.showPanel("Kalender");
		
		if(e.getActionCommand().equals("Events"))
			mainPanel.showPanel("Events");
		
		if(e.getActionCommand().equals("Notizen"))
			mainPanel.showPanel("Notizen");
		
	}

}
```


```
import java.awt.CardLayout;
import java.awt.Color;

import javax.swing.JLabel;
import javax.swing.JPanel;


public class MainPanel
extends JPanel {
	
	private CardLayout cardLayout;
	
	private JPanel panel1, panel2, panel3;
	
	
	// Konstruktor
	public MainPanel() {
		
		setBorder(javax.swing.BorderFactory.createTitledBorder("Content"));
		
		cardLayout = new CardLayout();

		this.setLayout(cardLayout);
		
		// Objekte der Panel erzeugen, die angezeigt werden sollen
		panel1 = new JPanel();
		panel2 = new JPanel();
		panel3 = new JPanel();
		
		panel1.setBackground(Color.YELLOW);
		panel2.setBackground(Color.RED);
		panel3.setBackground(Color.GREEN);
		
		JLabel label1 = new JLabel("Panel 1: Kalender");
		JLabel label2 = new JLabel("Panel 2: Events");
		JLabel label3 = new JLabel("Panel 3: Notizen");
		
		panel1.add(label1);
		panel2.add(label2);
		panel3.add(label3);
		
		this.add(panel1, "Kalender");
		this.add(panel2, "Events");
		this.add(panel3, "Notizen");
	
	}
	
	
	public void showPanel(String panel) {
		 
		cardLayout.show(this, panel);
 
    }

}
```
Ist zwar so einigermassen ähnlich dem vorher schon geposteten Beispiel von L-ectron-X, aber vielleicht wird es ja nun klarer...


----------



## chrisUBER (16. Mai 2011)

Oh oh, hab es wohl verbockt 

Habe mir das Beispiel angeschaut und eigentlich ist es ja genau das, was ich bei meinem Programm machen will. Leider ist mein Programmaufbau ein wenig anders, wie z. B. das die Buttons für die Navigation in einer komplett anderen Klasse sind wie das Panel mit dem Inhalt. Weiss nicht wie ich dieses Beispiel nun auf meinem Projekt anwenden soll 

Das mit dem "new Content()" habe ich in einigen Tutorials gelesen, mir wurde gesagt, dass man so Variabeln klassenübergreifend übergibt. Daher dachte ich mir, dass ich so die Variable von den Buttons an die Klasse mit den CardLayout Panels übergeben kann. Scheint ja ein absolutes no-go zu sein  Muss noch viel lernen wie es aussieht, leider kommt jetzt alles auf einmal und ich muss mir das alles in kürzester Zeit aneignen. Nicht ganz meine Stärke 

Wäre dir sehr dankbar, wenn du mir bei der Korrektur der Navi Klasse helfen könntest. Vielleicht verstehe ich das ganze Prinzip auch besser, wenn es an meinem Programm angewendet wird.

*Edit
Ok, werde mir das Beispiel von dir nun gründlichst anschauen und auf einen Geistesblitz hoffen  Danke

Gruß Chris


----------



## Spin (16. Mai 2011)

Hallo 

Ich habe mir mal 15 minuten Zeit genommen und deine Idee umgesetzt 

Sie ist Dirty aber macht das was du möchtest.


```
package javaforumhelp;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainFrame extends JFrame implements ActionListener{

	private JPanel navi = null;
	
	private JPanel cardPanel = null;
	private JPanel helloPanel = null;
	private JPanel huhuPanel = null;
	private JPanel xxPanel = null;
	
	private JButton buttonHello = null;
	private JButton buttonHuhu = null;
	private JButton buttonXX 	= null;
	
	public MainFrame() {
		super("Java Forum Help");
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		this.setMinimumSize(new Dimension(700,700));
		
		this.setLocationRelativeTo(null);
		
		this.initComponents();
		
		this.setVisible(true);
	}
	
	public void initComponents(){
		
		Container contentPane = this.getContentPane();
		contentPane.setLayout(null);
		
		this.navi = new JPanel();
		this.navi.setBounds(10,50,150,200);
		this.navi.setLayout(new BoxLayout(this.navi,BoxLayout.Y_AXIS));
		this.navi.setBorder(BorderFactory.createEtchedBorder());
		
		this.cardPanel = new JPanel();
		this.cardPanel.setBounds(200,50,400,400);
		this.cardPanel.setBorder(BorderFactory.createEtchedBorder());
		
		this.helloPanel = new JPanel();
		this.helloPanel.setBackground(Color.GREEN);
		
		helloPanel.setSize(200,200);
		helloPanel.setBorder(BorderFactory.createEtchedBorder());
		
		
		this.huhuPanel = new JPanel();
		this.huhuPanel.setBackground(Color.RED);
		
		this.xxPanel = new JPanel();
		this.xxPanel.setBackground(Color.BLACK);
		
		this.buttonHello = new JButton("Hello");
		this.buttonHello.addActionListener(this);
		this.buttonHuhu = new JButton("Huhu");
		this.buttonHuhu.addActionListener(this);
		this.buttonXX = new JButton("XX");
		this.buttonXX.addActionListener(this);
		
		Box vgap = Box.createVerticalBox();
		vgap.add(Box.createRigidArea(new Dimension(5,20)));
		vgap.add(buttonHello);
		vgap.add(Box.createRigidArea(new Dimension(5,5)));
		vgap.add(buttonHuhu);
		vgap.add(Box.createRigidArea(new Dimension(5,5)));
		vgap.add(buttonXX);
		
		
		this.cardPanel.setLayout(new CardLayout());
		this.cardPanel.add(helloPanel,"helloPanel");
		this.cardPanel.add(huhuPanel,"huhuPanel");
		this.cardPanel.add(xxPanel,"xxPanel");
		
		this.navi.add(vgap);
		
		contentPane.add(navi);
		contentPane.add(this.cardPanel);
		
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		Object source = arg0.getSource();
		
		CardLayout cl = (CardLayout)this.cardPanel.getLayout();
		
		
		if(source == this.buttonHello){
			cl.show(this.cardPanel, "helloPanel");
			
		}
		
		if(source == this.buttonHuhu){
			cl.show(this.cardPanel, "huhuPanel");
		}
		
		if(source == this.buttonXX){
			cl.show(this.cardPanel, "xxPanel");
		}
		
	}
	
	public static void main(String[] args){
		new MainFrame();
	}
}
```



grüße Spin


----------



## Camino (16. Mai 2011)

Sorry, hab ne Weile gebraucht, um das alles zusammenzuschreiben. Aber ich hoffe, der Zusammenhang ist nun einigermassen klar. Du erzeugst halt nur einmal ein Objekt der Klasse MainPanel (bei dir Content) und übergibst das dem NaviPanel. Dann hast du im Navi-Panel Zugriff auf die Methode showPanel über die actionPerformed-Methode des ActionListeners, bei dem die Buttons sich angemeldet haben.


----------



## chrisUBER (16. Mai 2011)

*trommelwirbel*

Es klappt !  yuppi, es läuft jetzt genauso, wie es von Anfang an geplant war 

Vielen vielen herzlichen Dank ! 

Euer Programmaufbau ist auch um einiges klarer als meiner, alles viel übersichtlicher und klar zu verstehen. Habe vorher alles mit dem GUI Builder gemacht und mir den gleichen unübersichtlichen Schreibstil angeeignet. Werde mir noch weitere Sachen bei euch abschauen, tolles Forum 

Habe jetzt den Sinn mit der Übergabe des Objektes verstanden und fasse mir doch selbst an den Kopf, wenn ich bedenke was für Fehler ich bei dem Rest meines Programmes eingebaut habe. Werde diese in den nächsten Tagen ausbessern.

Wenn das Projekt komplett fertig ist, würde ich mir gerne ein Feedback von euch holen. Mal sehen ob ich das soeben gelernte weiterhin gut umsetzen kann 

Danke nochmal  

Gute Nacht und lieben Gruß

Chris


----------

