简体   繁体   English

通过点击 JButton 获取 JPanel

[英]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.我想通过单击 loadButton 调用一个新面板(在单独的类中制作),但它似乎不起作用 - 即使我单击按钮也没有任何反应。

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.我仍然是 Java 的初学者。任何帮助将不胜感激。

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.) (请注意,我在您的问题中找不到 class BudgetPlanner的代码,但由于您问题中的代码从不调用方法callBudgetPlanner ,我只是删除了该方法。我还删除了未使用的导入和未使用的变量。代码后有更多注释。)

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 .初始Swing示例代码(从上个世纪开始,大约 1998 年)总是让应用程序 class 扩展JFrameJPanel This is not required.这不是必需的。

It appears that you want to replace openpanel with loadCompletePanel after the user clicks on loadButton .您似乎希望在用户单击loadButton openpanel替换为loadCompletePanel Since you are using no layout manager , simply adding loadCompletePanel won't replace openpanel .由于您没有使用布局管理器,因此简单地添加loadCompletePanel不会替换openpanel That's why, in the above code, before adding loadCompletePanel , I remove openpanel .这就是为什么在上面的代码中,在添加loadCompletePanel之前,我删除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.用户单击loadButton后似乎没有任何反应的原因是,您在调用各种组件的方法setBounds时使用的值是错误的,因此组件是在其父容器之外的坐标处绘制的。 That's why, in the above code, I changed all the arguments in the calls to setBounds .这就是为什么在上面的代码中,我在对setBounds的调用中更改了所有 arguments 。

Here is a screen capture of the app before clicking loadButton .这是单击loadButton之前应用程序的屏幕截图。

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

Here is a screen capture of the app after clicking loadButton .这是单击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.下面的代码使用了BoxLayoutCardLayout ,尽管您可以使用其他布局管理器来实现您想要的结果。 I can only answer what you wrote in your question and therefore BoxLayout and CardLayout seemed appropriate.我只能回答你在问题中写的内容,因此BoxLayoutCardLayout似乎是合适的。

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 .上面代码中loadButtonActionListener使用方法引用

Here is the initial app.这是初始应用程序。

其他应用初始屏幕截图

And after clicking on loadButton在点击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.请注意,我使用了以下 SO 问题的答案中的代码,以便在其父容器的中心显示loadCompleteMessage

Centering a JLabel on a JPanel 使 JLabel 在 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.由于我不熟悉与 setBounds(...) 关联的 setLayout(null) 并且我已经很长时间没有做 Swing 了,所以我从来没有设法直接显示 LoadCompletePanel 实例。 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.无论如何,由于问题出在动作侦听器中,我用 LoadindCompleteLabel label 替换了 loadCompletePanel 面板。要使此 label 出现在动作侦听器中,您必须在受影响的容器上调用 repaint()。

    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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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