Von Menü: Seite zu Seite springen (CardLayout)

internet

Top Contributor
Hallo,

ich versuche mich gerade mit Swing und habe ier auch den Windows Builder in Eclipse installiert.
Ich scheitere aber gerade bei einem "Seitenwechsel".

Also sowas möche ich machen:
- Je nachdem wo man draufklickt wird in dem "Contentbereich" Seite1 oder Seite2 angezeigt.
1656574877350.png

Aber das funktioniert nicht.

Java:
public class MainWindow {

    private JFrame frame;
    private JTextField textField;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainWindow window = new MainWindow();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

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

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
    
        frame = new JFrame("Test");
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        EventQueue.invokeLater(() -> frame.setVisible(true));
        
        
        JPanel cardLayout = new JPanel(new CardLayout());
        GridBagConstraints gbcCards = new GridBagConstraints();
        gbcCards.gridx = 0;
        gbcCards.gridy = 1;
        gbcCards.gridwidth = 2;
        gbcCards.fill = java.awt.GridBagConstraints.BOTH;
        gbcCards.weightx = 1.0;
        gbcCards.weighty = 1.0;
        frame.getContentPane().add(cardLayout);
        
        final JPanel panel = new JPanel(new FlowLayout());
        cardLayout.add(panel, "page1");
        
        textField = new JTextField();
        textField.setBounds(277, 5, 130, 26);
        panel.add(textField);
        textField.setColumns(10);

        
        final JPanel panel_1 = new JPanel(new FlowLayout());
        cardLayout.add(panel_1, "page2");
        
        JLabel lblNewLabel = new JLabel("New label");
        lblNewLabel.setBounds(311, 5, 61, 16);
        panel_1.add(lblNewLabel);
        
        ItemListener buttonSelectListener = (ItemEvent e) -> {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                showCard(((AbstractButton) e.getSource()).getActionCommand(), cardLayout);
            }
        };
        
        //////////
        // Menu
        //////////
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        
        JMenu mnNewMenu_2 = new JMenu("Allgemein");
        menuBar.add(mnNewMenu_2);
        
        JMenuItem mntmNewMenuItem = new JMenuItem("Dashboard");
        mntmNewMenuItem.setActionCommand("page1");
        mntmNewMenuItem.addItemListener(buttonSelectListener);
        mnNewMenu_2.add(mntmNewMenuItem);
        
        JMenuItem mntmNewMenuItem_2 = new JMenuItem("Einstellung");
        mntmNewMenuItem_2.setActionCommand("page2");
        mntmNewMenuItem_2.addItemListener(buttonSelectListener);
        mnNewMenu_2.add(mntmNewMenuItem_2);
    

    }


    /**
     * holder muss ein CardLayout haben
     *
     * @param key
     * @param holder
     */
    private void showCard(String key, JPanel holder) {
        ((CardLayout) holder.getLayout()).show(holder, key);
    }

Was mache ich falsch?
 
So weit ich das beurteilen kann, hast du das panel aber schon mal richtig initialisiert und befüllt. showCard schaut auch gut aus

Für normale MenüItems solltest du einen Actionlistener verwenden. ItemListener sind z.B. für Radiomenuitems gedacht.

Lass dir dort, wo showCard aufgerufen wird, mal was ausgeben, damit du siehst, ob der Punkt überhaupt erreicht wird.


edit: Post korrigiert, hatte was übersehen.
 
Java:
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


// BoxLayout (Außen) mit CardLayout (Innen):
public class BoxLayoutDemo extends JFrame
{   
    JPanel cardPanel = new JPanel(); 
    JPanel dokuPanel = new JPanel();
    JLabel dokuLabel = new JLabel("Das ist die Dokumentation über die Toyota-Serie...");
    
    ImageIcon pic1 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Corolla.png");   
    ImageIcon pic2 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Yaris_Cross.png");
    ImageIcon pic3 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Rav4.png");
    ImageIcon pic4 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Highlander.png");
    ImageIcon pic5 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Kleinbus.png");
    ImageIcon pic6 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Supra.png");
    Image picFuchs = Toolkit.getDefaultToolkit().getImage("E:/NetBeansProjects/BoxLayoutDemo/Silberfuchs-Wappen_java.png");
      
    public BoxLayoutDemo(String title)
    {       
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));       
        
        // 1. Horizontale Box (HEADERBOX) erzeugen:
        Box headerBox = Box.createHorizontalBox();
        headerBox.add(new JLabel("TOYOTA-SERIE"));
        this.add(headerBox);
        
        // 2. Horizontale Box (BUTTONBOX) erzeugen:
        Box buttonBox = Box.createHorizontalBox();
        buttonBox.add(Box.createRigidArea(new Dimension(10, 0)));
        JButton dokuButton = new JButton("DOKU");
        buttonBox.add(dokuButton);
        // alle Komponenten so weit wie möglich nach links oder rechts verschieben:
        buttonBox.add(Box.createHorizontalGlue());
        JButton weiterButton = new JButton("WEITER");
        buttonBox.add(weiterButton);
        buttonBox.add(Box.createRigidArea(new Dimension(10, 0)));
        this.add(buttonBox);         
        
        // 3. Horizontale Box (ICONBOX) erzeugen:
        Box iconBox = Box.createHorizontalBox();
        // alle Komponenten so weit wie möglich nach links oder rechts verschieben:
        iconBox.add(Box.createHorizontalGlue());
        CardLayout carLa = new CardLayout(100, 50);
        cardPanel.setLayout(carLa);
        cardPanel.setBackground(Color.BLACK);
        cardPanel.add(new JLabel(pic1));
        cardPanel.add(new JLabel(pic2));
        cardPanel.add(new JLabel(pic3));
        cardPanel.add(new JLabel(pic4));
        cardPanel.add(new JLabel(pic5));
        cardPanel.add(new JLabel(pic6));
        iconBox.add(cardPanel);
        this.add(iconBox);           
              
        // 4. Horizontale Box (EXITBOX) erzeugen:
        Box exitBox = Box.createHorizontalBox();
        // alle Komponenten so weit wie möglich nach links oder rechts verschieben:
        exitBox.add(Box.createHorizontalGlue());
        JButton exitButton = new JButton("EXIT");
        exitBox.add(exitButton);
        exitBox.add(Box.createHorizontalGlue());
        this.add(exitBox);
        // ExitButton:
        exitButton.addActionListener(AE ->
        { System.exit(0); });
        exitButton.addKeyListener(new KeyAdapter()
        {
            @Override
            public void keyPressed(KeyEvent e)
            {
                if (e.getKeyCode() == KeyEvent.VK_ENTER)
                { System.exit(0); }   
            }
        }); 
        
        // weiterButton -> addActionListener:
        weiterButton.addActionListener(AE ->
        {
            carLa.next(cardPanel);
            cardPanel.remove(dokuPanel);
        });         
        
        // weiterButton -> addKeyListener:
        weiterButton.addKeyListener(new KeyAdapter()
        {
            @Override
            public void keyPressed(KeyEvent e)
            {
                if (e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
                    carLa.next(cardPanel);
                    cardPanel.remove(dokuPanel);                   
                }   
            }
        });
        
        // dokuButton -> CardLayout show (carLa.show):
        dokuButton.addActionListener((ActionEvent AE) ->
        {
            dokuPanel.add(dokuLabel);       
            cardPanel.add(dokuPanel, "se_llama_DOKU");
            carLa.show(cardPanel, "se_llama_DOKU");       
        });
              
        // Finale:
        BoxLayoutDemo.setDefaultLookAndFeelDecorated(true);
        this.setIconImage(picFuchs);
        this.pack();
        this.setVisible(true);
    } 
    
        
    // Main:
    public static void main(String... args)
    {
        SwingUtilities.invokeLater(() ->
        { new BoxLayoutDemo("BoxLayout mit CardLayout"); });
    }
}
 
@volcanos Schau Dir einmal an, wie man mit Ressourcen in Java umgeht. Code wie:
Java:
    ImageIcon pic1 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Corolla.png");   
    ImageIcon pic2 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Yaris_Cross.png");
    ImageIcon pic3 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Rav4.png");
    ImageIcon pic4 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Highlander.png");
    ImageIcon pic5 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Kleinbus.png");
    ImageIcon pic6 = new ImageIcon("E:/NetBeansProjects/BoxLayoutDemo/Toyota_Supra.png");
    Image picFuchs = Toolkit.getDefaultToolkit().getImage("E:/NetBeansProjects/BoxLayoutDemo/Silberfuchs-Wappen_java.png");
ist mit das Schlechteste, das man machen kann. Je nach Projekt ist die Frage, wo die Ressourcen erwartet werden. Wenn NetBeans kein eigenes Verzeichnis hat, dann wäre das obere besser zu schreiben als:
Java:
    ImageIcon pic1 = new ImageIcon(getClass().getResource("/Toyota_Corolla.png"));   
    ImageIcon pic2 = new ImageIcon(getClass().getResource("/Toyota_Yaris_Cross.png"));
    ImageIcon pic3 = new ImageIcon(getClass().getResource("/Toyota_Rav4.png"));
    ImageIcon pic4 = new ImageIcon(getClass().getResource("/Toyota_Highlander.png"));
    ImageIcon pic5 = new ImageIcon(getClass().getResource("/Toyota_Kleinbus.png"));
    ImageIcon pic6 = new ImageIcon(getClass().getResource("/Toyota_Supra.png"));
    Image picFuchs = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/Silberfuchs-Wappen_java.png"));

Das funktioniert dann auch wenn die Ressourcen mit in der Jar Datei sind und so. Und vor allem hast Du keine fest codierten Pfade. Bei mir wird es so schnell kein e:\NetBeans\Projects geben und so Linux und Apple nicht massiv was verändern wird es auch Anderen ebenso gehen.
 
ist mit das Schlechteste, das man machen kann. Je nach Projekt ist die Frage, wo die Ressourcen erwartet werden. Wenn NetBeans kein eigenes Verzeichnis hat, dann wäre das obere besser zu schreiben als:
Nur als Info: In einem ANT Projekt wird in Netbeans ein src und ein resources Ordner angelegt (bei Maven musste ich das manuell machen), um beides voneinenader zu trennen, sie sind aber - den Zugriff auf Resourcen betreffend - gleichwertig. Im Build Script wird der Inhalt des Resources-Verzeichnis dann auf Wunsch mit in die JAR gepackt.
Der oben verwendete Pfad kommt nur zustande, wenn man das resources-Verzeichnis nicht nutzt.

Was ich am Standard nicht gut finde, ist, dass - sofern man nichts anderes angibt - das Projektverzeichnis als Ausführungsverzeichnis verwendet wird. Hier hab ich mir ein eigenes angelegt, damit das Projekt auf keinen Fall durch die Ausführung verändert wird.

@volcanos
Egal was man verwendet: Resourcen direkt im Projektverzeichnis sind ... suboptimal.
 
Zuletzt bearbeitet:

Zurück
Oben