0

I'm trying to make a basic Swing project and trying to figure out the best way to change Cards from within the panels when using Card Layout.

The only way I've managed to get it working is by parsing the Main Window into each Panel on it. Is this considered a proper way to do it? Or is there a better way?

Here's an example of what I mean:

Main Window Class:

import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.CardLayout;
import javax.swing.JPanel;
import java.awt.Color;

public class Window {

    private JFrame frame;
    private CardLayout cardLayout;

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

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

            }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new CardLayout());

        Orange orange = new Orange(this);
        orange.setBackground(Color.ORANGE);
        frame.getContentPane().add(orange, "orange");

        Green green = new Green(this);
        green.setBackground(Color.GREEN);
        frame.getContentPane().add(green, "green");

        //Shows orange by default
        cardLayout = (CardLayout) frame.getContentPane().getLayout();
        cardLayout.show(frame.getContentPane(), "orange");


    }

    //Changes the currently shown card to the "Green" Panel
    public void goGreen() {
        cardLayout.show(frame.getContentPane(), "green");
    }

    //Changes the currently shown card to the "Orange" Panel
    public void goOrange() {
        cardLayout.show(frame.getContentPane(), "orange");
    }   


}

Orange Panel:

import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;

public class Orange extends JPanel {

    private Window parent;

    public Orange(Window parent) {
        this.parent = parent;
        setBackground(Color.ORANGE);        

        //Adds a button to change to the "Orange" Panel
        JButton btnGoGreen = new JButton("Go Green Panel");
        btnGoGreen.setBounds(188, 132, 89, 23);
        btnGoGreen.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //Function of the parent Window.class to change to the Orange Panel
                parent.goGreen();
            }
        });
        add(btnGoGreen);

    }

}

Green Panel:

import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;

public class Green extends JPanel {

    private Window parent;

    public Green(Window parent) {
        this.parent = parent;
        setBackground(Color.GREEN);     

        //Adds a button to change to the "Green" Panel
        JButton btnGoOrange = new JButton("Go Orange Panel");
        btnGoOrange.setBounds(188, 132, 89, 23);
        btnGoOrange.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //Function of the parent Window.class to change to the Orange Panel
                parent.goOrange();
            }
        });
        add(btnGoOrange);

    }

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
A Conway
  • 3
  • 4
  • 1
    If this were my project, I'd M-V-C it. – Hovercraft Full Of Eels May 16 '18 at 03:39
  • 2
    Start by reading the Swing tutorial on [How to Use CardLayout](https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) for a working example. Basically you should NOT extend JFrame. You create a class that contains the card layout panel and the child panels of the card layout. Also don't use a null layout on the child panels. The CardLayout will use the preferred size of the child panels to determine the size of the card layout panel. If you don't use layout managers then the child panels won't have a preferred size. – camickr May 16 '18 at 03:41
  • 1
    You're kind of on the right path, but instead of passing your "main" class to all the other panels, you should be passing a "navigation controller", this reduces the coupling and risk of exposing your "main" class to mistreatment. Something like [this for example](https://stackoverflow.com/questions/24296505/how-to-effectively-use-cardlayout-in-java-in-order-to-switch-from-panel-using-bu/24296872#24296872) or [this for example](https://stackoverflow.com/questions/30925564/why-is-my-jlabel-not-showing-up/30926625#30926625) – MadProgrammer May 16 '18 at 03:55
  • I somewhat understand the examples you've linked above. I might of misunderstood, but is it not good practice to let the child panel of a main panel be able to control which 'card' the main panel is showing? - through a button which is on the child panel – A Conway May 16 '18 at 04:31
  • 1
    It's better for each of your panels to have a `addActionListener(ActionListener listener)` method in which they are adding `listener` argument to a `Set actListeners` field of your panel class. Then every time an action occurred on the button the only thing you need to do is to call the `actionPerformed` method of all the `actListeners`. On the other side, your parent panel instead of passing itself to each panel, should add itself to each child panel as actionListener of their button's events. This way parent can be informed of which button clicked and call the proper method. – STaefi May 16 '18 at 05:15
  • Do you have any examples, or some examples I can look, based on anything like that? I've looked around but I'm struggling to find anything on the proper way to give the child Panel's access to the parents method when the child panels are separate classes – A Conway May 16 '18 at 08:37

0 Answers0