0
votes

So I'm new to programming and I've been making a program that uses multiple JPanels on a JFrame and other JPanels. I'm using CardLayout to go between different JPanels and I have it working on two different JButtons, but I can't get the last one to return to the main screen.

I've looked for answers, but it seems like most people just forget to use an ActionListener, something that I know I've done. Here's some of the involved classes in my code (There are a lot so I won't include them all, but I can provide any others that are needed).

Here's the JFrame class:

import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.*;

public class ElephantCare extends JFrame {
private static final long serialVersionUID = 1L;

private final String MAIN_STRING = "Main";
public JPanel container, main;
private Staff1Panel staff1 = new Staff1Panel();
private Staff2Panel staff2 = new Staff2Panel();
private StaffConfirmPanel staffConfirm = new StaffConfirmPanel();
private WelcomePanel welcome = new WelcomePanel();
private StaffPanel staff = new StaffPanel();
private GallonsPanel gallons = new GallonsPanel();
private ToysPanel toys= new ToysPanel();
private ActionPanel action = new ActionPanel();
public CardLayout card = new CardLayout();

public ElephantCare() {
    setSize(400,300);
    setTitle("Elephant Care");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    buildPanel();
    add(container);
    setVisible(true);
}

private void buildPanel() {
    main = new JPanel();;
    container = new JPanel(card);
    container.add(main, MAIN_STRING);
    container.add(staff1, "Staff 1");
    container.add(staff2, "Staff 2");

    main.setLayout(new BorderLayout());

    main.add(welcome, BorderLayout.NORTH);
    main.add(staff, BorderLayout.WEST);
    main.add(gallons, BorderLayout.CENTER);
    main.add(toys, BorderLayout.EAST);
    main.add(action, BorderLayout.SOUTH);

    staff.getStaff1Button().addActionListener(new Staff1Listener());
    staff.getStaff2Button().addActionListener(new Staff2Listener());
    staffConfirm.getConfirmButton().addActionListener(new ConfirmButtonListener());
}

private class Staff1Listener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        card.show(container, "Staff 1");
    }
}

private class Staff2Listener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        card.show(container, "Staff 2");
    }
}
private class ConfirmButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        card.show(container, MAIN_STRING);
    }
}

}

Here's the JPanel with the Button:

import javax.swing.*;

public class StaffConfirmPanel extends JPanel{
    private static final long serialVersionUID = 1L;
    public JButton confirm;

    public StaffConfirmPanel() {

        confirm = new JButton("OK");

        add(confirm);
    }

    public JButton getConfirmButton() {
        return confirm;
    }
}

And here's the JPanels where the button is used:

 import java.awt.BorderLayout;

import javax.swing.*;

public class Staff1Panel extends JPanel{
    private static final long serialVersionUID = 1L;
    private Staff1NamePanel name = new Staff1NamePanel();
    private Staff1JobPanel job = new Staff1JobPanel();
    private StaffConfirmPanel confirm = new StaffConfirmPanel();

    public Staff1Panel() {
        setLayout(new BorderLayout());

        add(name, BorderLayout.WEST);
        add(job, BorderLayout.EAST);
        add(confirm, BorderLayout.SOUTH);
    }
}

And:

import java.awt.BorderLayout;

import javax.swing.*;

public class Staff2Panel extends JPanel{
    private static final long serialVersionUID = 1L;
    private Staff2NamePanel name = new Staff2NamePanel();
    private Staff2JobPanel job = new Staff2JobPanel();
    private StaffConfirmPanel confirm = new StaffConfirmPanel();

    public Staff2Panel() {
        setLayout(new BorderLayout());

        add(name, BorderLayout.WEST);
        add(job, BorderLayout.EAST);
        add(confirm, BorderLayout.SOUTH);
    }
}

Thanks for any help!

1

1 Answers

2
votes

There are a lot of things happening in this code that are not quite right, and they contribute to your issue. So lets address the biggest issue and then you will need to do the rest yourself.

First edit this code to have some debug text:

private class ConfirmButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        //NEW LINE OF CODE
        System.out.println("ConfirmButtonListener was triggered");
        card.show(container, MAIN_STRING);
    }
}

Now when you run your code you will notice that the message "ConfirmButtonListener was triggered" will never be printed to the console, meaning that the code never runs, so you can never return to the main screen.

This happens because you create a StaffConfirmPanel named staffConfirm in your ElephantCare class. Then you add an action listener to staffConfirm. The problem is that you never use that staffconfirm panel anywhere because you create a new StaffConfirmPanel inside Staff1Panel and Staff2Panel so the action listener you have made will do nothing.

So the solution is to move the whole ConfirmButtonListener method and the staffConfirm.getConfirmButton().addActionListener line into the StaffConfirmPanel class like so:

import javax.swing.*;

public class StaffConfirmPanel extends JPanel{
    private static final long serialVersionUID = 1L;
    public JButton confirm;

    public StaffConfirmPanel() {

        confirm = new JButton("OK");

        add(confirm);

        //NEW LINE: SET THE ACTION LISTENER
        confirm.addActionListener(new ConfirmButtonListener());
    }

    public JButton getConfirmButton() {
        return confirm;
    }

    //NEW CODE, MOVE THE ACTION LISTENER METHOD HERE
    //ACTION LISTENER MOVED HERE
    private class ConfirmButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            //NEW LINE OF CODE
            System.out.println("ConfirmButtonListener was triggered");
            card.show(ElephantCare.container, ElephantCare.MAIN_STRING);
        }
    }
}

Now it should work correctly and return to the main screen.

EDIT: you will need to make MAIN_STRING a public variable in the ElephantCare class.