如何在 java 中更新监听按钮的组件

How to update components listening a button in java

很抱歉问这个问题,因为它似乎有点明显,但我无法单独找到我的解决方案。

我正在 Java 编写一个小应用程序,我遇到了一些问题 "redrawing" 我的 swing 组件。基本上,我希望我的 JFrame 在事件发生时更新。我设法在下面的代码中重现了这个问题。此代码应该显示两个按钮(它确实如此),并在您单击第一个按钮时将它们替换为第三个按钮(它没有)。

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

public class Example extends JFrame implements ActionListener {

    private JButton button = new JButton("Button 1");
    private JButton button2 = new JButton("Button 2");
    private JButton button3 = new JButton("Button 3");
    private JPanel buttons = new JPanel();

    public void init() {
        this.setVisible(true);
        this.setSize(500,500);
        buttons.add(button);
        buttons.add(button2);
        this.add(buttons);
        this.button.addActionListener(this);
    }

    public void update() {
        this.removeAll();
        buttons.add(button3);
        this.revalidate();
    }

    public static void main(String[] args) {
        Example ex = new Example();
        ex.init();
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == button) {
            update();
        }
    }
}

我很确定我在 update() 方法中做错了什么。我实际上很难理解 removeAll()revalidate()repaint() 等是如何工作的,我想这就是问题所在。我尝试在 buttons 面板上调用相同的方法,它几乎可以工作,但我仍然有一个图形错误,我想对所有容器都这样做。我也尝试在 this.getContentPane() 上调用这些方法,但它不起作用。

任何人都可以帮助我吗?

您要删除 this 中的所有组件(在本例中为 JFrame(因为您正在扩展它,不需要这样做,相反您应该创建一个实例从它而不是从它继承,因为你没有改变 JFrame 的行为所以最好只创建它的一个实例。参见:Extends JFrame vs. creating it inside the program

在这种情况下,您将以这种方式添加组件:

JFrame > buttons (JPanel) > JButtons

而您正在尝试删除

JFrame > everything

包括 contentPane,你应该调用。

buttons.removeAll()

update() 方法中。

并且还调用了 this.repaint() 所以你的 update() 方法应该变成:

public void update() {
    buttons.removeAll();
    buttons.add(button3);
    this.revalidate();
    this.repaint();
}

或者最好的方法是使用 CardLayout as recommended by @AndrewThompson in the comment below. This way you don't have to handle removing / repainting for each component, as CardLayout will do it for you. For example

这有效,

public void update() {
    buttons.remove(button);
    buttons.remove(button2);
    buttons.add(button3);
    this.revalidate();
    this.repaint();
}