简体   繁体   中英

Getting JPanel by clicking on JButton

public class OpenFrame extends JFrame implements ActionListener {

    private static final int WIDTH = 500;
    private static final int HEIGHT = 500;
    private BudgetPlanner budgetPlanner;
    private JLabel welcomeMessage;
    private JPanel openpanel = new JPanel();

    private JButton loadButton = new JButton();
    private JButton resetButton = new JButton();
    private JFrame openFrame;
    private JLabel getWelcomeMessage;

    public BudgetPlanner callBudgetPlanner() {
        try {
            budgetPlanner = new BudgetPlanner();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return budgetPlanner;
    }

    public OpenFrame() {
        openFrame = new JFrame();
        openFrame.setTitle("BudgetPlanner");
        openFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        openFrame.setResizable(false);
        openFrame.setLayout(null);
        openFrame.setLocationRelativeTo(null);
        openFrame.setSize(new Dimension(WIDTH, HEIGHT));
        openFrame.getContentPane().setBackground(Color.GRAY);
        openPanel();
        openFrame.setContentPane(openpanel);

        openFrame.setVisible(true);
    }

    public void openPanel() {
        openpanel.setLayout(null);

        welcomeMessage = new JLabel("Hello there! Welcome back. Choose an option below:");
        welcomeMessage.setVerticalTextPosition(TOP);
        welcomeMessage.setHorizontalTextPosition(SwingConstants.CENTER);
        welcomeMessage.setBounds(50, 20, 500, 200);
        welcomeMessage.setFont(new Font("Arial", Font.PLAIN, 17));

        openpanel.setBounds(0, 0, 500, 500);
        openpanel.add(welcomeMessage);

        loadButton.setBounds(200, 170, 100, 50);
        loadButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        loadButton.setText("Load Data");
        loadButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                LoadCompletePanel loadCompletePanel = new LoadCompletePanel();
                openpanel.add(loadCompletePanel);
            }
        });
        loadButton.setFocusable(false);

        resetButton.setBounds(200, 230, 100, 50);
        resetButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        resetButton.setText("Reset Data");
        resetButton.addActionListener(this);
        resetButton.setFocusable(false);

        openpanel.add(loadButton);
        openpanel.add(resetButton);
    }

Above is my code, and I have an issue. I would like to call a new panel (made in a separate class) by clicking on loadButton, but it doesn't seem to work - nothing happens even if I click on the button.

How should I fix this? By the way, below is the code for a new panel:

public class LoadCompletePanel extends JPanel implements ActionListener {

    private BudgetPlanner budgetPlanner;
    private JPanel loadCompletePanel;
    private JLabel loadCompleteMessage;
    private JButton addExpense;
    private JButton addIncome;
    private JButton viewMonthlyExpense;
    private JButton viewMonthlyIncome;

    public LoadCompletePanel() {
        loadCompletePanel = new JPanel();
        loadScreenPanel();
        loadCompletePanel.add(loadCompleteMessage);
        loadCompletePanel.setBounds(200, 170, 100, 50);
        setVisible(true);

    }

    private void loadScreenPanel() {
        loadCompletePanel.setLayout(null);
        loadCompleteMessage = new JLabel("Loading Complete.");
        loadCompleteMessage.setBounds(130, 50, 500, 200);

    }

Sorry if this is a very trivial & basic question. I'm still a beginner at Java. Any help would be appreciated.

I finally got your code to do what you expect it to do. I made a number of changes. I suggest you compare your code with the code below if you want to see what I changed. However, I recommend rewriting your application. I have done so and the code for the rewritten application appears after my modified version of your code.

Here is my modified version of the code in your question.
(Note that I couldn't find code for class BudgetPlanner in your question but since the code in your question never calls method callBudgetPlanner , I simply removed that method. I also removed unused imports and unused variables. More notes after the code.)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

public class OpenFrame extends JFrame implements ActionListener {
    private static final int WIDTH = 500;
    private static final int HEIGHT = 500;

    private JLabel welcomeMessage;
    private JPanel openpanel = new JPanel();

    private JButton loadButton = new JButton();
    private JButton resetButton = new JButton();
    private JFrame openFrame;

    public OpenFrame() {
        openFrame = new JFrame();
        openFrame.setTitle("BudgetPlanner");
        openFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        openFrame.setResizable(false);
        openFrame.setLayout(null);
        openFrame.setLocationRelativeTo(null);
        openFrame.setSize(new Dimension(WIDTH, HEIGHT));
        openFrame.getContentPane().setBackground(Color.GRAY);
        openPanel();
        openFrame.setContentPane(openpanel);

        openFrame.setVisible(true);
    }

    public void openPanel() {
        openpanel.setLayout(null);

        welcomeMessage = new JLabel("Hello there! Welcome back. Choose an option below:");
        welcomeMessage.setVerticalTextPosition(SwingConstants.TOP);
        welcomeMessage.setHorizontalTextPosition(SwingConstants.CENTER);
        welcomeMessage.setBounds(50, 20, 500, 200);
        welcomeMessage.setFont(new Font("Arial", Font.PLAIN, 17));

        openpanel.setBounds(0, 0, 500, 500);
        openpanel.add(welcomeMessage);

        loadButton.setBounds(200, 170, 100, 50);
        loadButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        loadButton.setText("Load Data");
        loadButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                LoadCompletePanel loadCompletePanel = new LoadCompletePanel();
                openpanel.removeAll();
                openpanel.add(loadCompletePanel);
                System.out.println("ADDED");
                openpanel.revalidate();
                openpanel.repaint();
            }
        });
        loadButton.setFocusable(false);

        resetButton.setBounds(200, 230, 100, 50);
        resetButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        resetButton.setText("Reset Data");
        resetButton.addActionListener(this);
        resetButton.setFocusable(false);

        openpanel.add(loadButton);
        openpanel.add(resetButton);
    }

    public void actionPerformed(ActionEvent event) {
        
    }

    public static void main(final String[] args) {
        EventQueue.invokeLater(() -> new OpenFrame());
    }
}

class LoadCompletePanel extends JPanel {
    private JPanel loadCompletePanel;
    private JLabel loadCompleteMessage;

    public LoadCompletePanel() {
        super(null);
        setBounds(0, 0, 300, 300);
        loadCompletePanel = new JPanel();
        loadScreenPanel();
        loadCompletePanel.add(loadCompleteMessage);
        loadCompletePanel.setBounds(200, 170, 100, 50);
        add(loadCompletePanel);
        setVisible(true);
    }

    private void loadScreenPanel() {
        loadCompletePanel.setLayout(null);
        loadCompleteMessage = new JLabel("Loading Complete.");
        loadCompleteMessage.setBounds(1, 1, 50, 20);
        loadCompletePanel.add(loadCompleteMessage);
    }
}

Initial Swing sample code (from the last century, circa 1998) always had the application class extend either JFrame or JPanel . This is not required.

It appears that you want to replace openpanel with loadCompletePanel after the user clicks on loadButton . Since you are using no layout manager , simply adding loadCompletePanel won't replace openpanel . That's why, in the above code, before adding loadCompletePanel , I remove openpanel . However that still doesn't fix the problem. The reason why nothing seems to happen after the user clicks on loadButton is because the values you use in the calls to method setBounds on the various components are wrong and so the components are being drawn at coordinates which are outside of their parent containers. That's why, in the above code, I changed all the arguments in the calls to setBounds .

Here is a screen capture of the app before clicking loadButton .

正在运行的应用程序的初始屏幕截图

Here is a screen capture of the app after clicking loadButton .

正在运行的应用程序的第二个屏幕截图

You are better off using appropriate layout managers . The below code uses BoxLayout and CardLayout although you can use other layout managers to achieve your desired result. I can only answer what you wrote in your question and therefore BoxLayout and CardLayout seemed appropriate.

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

public class OpenWndw implements Runnable {
    private static final String  LOAD_COMPLETE = "LOAD_COMPLETE";
    private static final String  OPEN = "OPEN";

    private JFrame  frame;
    private JPanel  mainPanel;

    @Override // java.lang.Runnable
    public void run() {
        buildAndDisplayGui();
    }

    private void buildAndDisplayGui() {
        frame = new JFrame("BudgetPlanner");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createMainPanel(), BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createMainPanel() {
        mainPanel = new JPanel(new CardLayout());
        mainPanel.add(createOpenPanel(), OPEN);
        mainPanel.add(createLoadCompletePanel(), LOAD_COMPLETE);
        return mainPanel;
    }

    private JPanel createOpenPanel() {
        JPanel openPanel = new JPanel();
        openPanel.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
        BoxLayout layout = new BoxLayout(openPanel, BoxLayout.PAGE_AXIS);
        openPanel.setLayout(layout);

        JLabel welcomeMessage = new JLabel("Hello there! Welcome back. Choose an option below:");
        welcomeMessage.setVerticalTextPosition(SwingConstants.TOP);
        welcomeMessage.setHorizontalTextPosition(SwingConstants.CENTER);
        welcomeMessage.setFont(new Font("Arial", Font.PLAIN, 17));
        welcomeMessage.setAlignmentX(Component.CENTER_ALIGNMENT);
        openPanel.add(welcomeMessage);

        openPanel.add(Box.createRigidArea(new Dimension(10, 30)));

        JButton loadButton = createButton("Load Data");
        loadButton.addActionListener(this::showLoadCompletePanel);
        openPanel.add(loadButton);

        openPanel.add(Box.createRigidArea(new Dimension(10, 10)));

        JButton resetButton = createButton("Reset Data");
        openPanel.add(resetButton);
        return openPanel;
    }

    private JButton createButton(String text) {
        JButton button = new JButton(text);
        button.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
        button.setAlignmentX(Component.CENTER_ALIGNMENT);
        Dimension dim = new Dimension(112, 50);
        button.setMaximumSize(dim);
        button.setMinimumSize(dim);
        button.setPreferredSize(dim);
        return button;
    }

    private JPanel createLoadCompletePanel() {
        JPanel loadCompletePanel = new JPanel(new BorderLayout());
        JLabel loadCompleteMessage = new JLabel("Loading Complete.", SwingConstants.CENTER);
        loadCompletePanel.add(loadCompleteMessage, BorderLayout.CENTER);
        return loadCompletePanel;
    }

    private void showLoadCompletePanel(ActionEvent event) {
        CardLayout layout = (CardLayout) mainPanel.getLayout();
        layout.show(mainPanel, LOAD_COMPLETE);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new OpenWndw());
    }
}

The ActionListener for loadButton , in the above code, uses method references .

Here is the initial app.

其他应用初始屏幕截图

And after clicking on loadButton

其他应用第二个屏幕截图

Note that I used code from the answer to the following SO question in order to display loadCompleteMessage in the center of its parent container.

Centering a JLabel on a JPanel

Do the following:

 public void actionPerformed(ActionEvent e) {
     LoadCompletePanel loadCompletePanel = new LoadCompletePanel();
     openpanel.add(loadCompletePanel);
     openPanel.repaint();
     openPanel.revalidate();
 }

This code will make sure that the panel paints the newly added components.

Since I'm not familiar with setLayout(null) associated with setBounds(...) and I haven't been doing Swing for a long time, I never managed to display the LoadCompletePanel instance even directly. Anyway as the problem is in the action listener I replaced the loadCompletePanel panel with the LoadindCompleteLabel label. For this label to appear in the action listener, you must invoke repaint() on the effected container.

    public void openPanel() {
    openpanel.setLayout(null);

    welcomeMessage = new JLabel("Hello there! Welcome back. Choose an option below:");
    welcomeMessage.setVerticalTextPosition(SwingConstants.TOP);
    welcomeMessage.setHorizontalTextPosition(SwingConstants.CENTER);
    welcomeMessage.setBounds(50, 20, 500, 200);
    welcomeMessage.setFont(new Font("Arial", Font.PLAIN, 17));

    openpanel.setBounds(0, 0, 500, 500);
    openpanel.add(welcomeMessage);
    openpanel.add(loadCompletePanel);
    
    
    JLabel LoadindCompleteLabel = new JLabel("Loading Complete.");
    LoadindCompleteLabel.setBounds(130, 50, 500, 200);

    
    loadButton.setBounds(200, 170, 100, 50);
    loadButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    loadButton.setText("Load Data");
    loadButton.addActionListener(new ActionListener() {
        
        public void actionPerformed(ActionEvent e) {
            openpanel.add(LoadindCompleteLabel);
            openpanel.repaint();
        }
        
    });
    
    loadButton.setFocusable(false);

    resetButton.setBounds(200, 230, 100, 50);
    resetButton.setFont(new Font("Arial", Font.CENTER_BASELINE, 15));
    resetButton.setText("Reset Data");
    resetButton.addActionListener(this);
    resetButton.setFocusable(false);

    openpanel.add(loadButton);
    openpanel.add(resetButton);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM