如何在 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();
}
很抱歉问这个问题,因为它似乎有点明显,但我无法单独找到我的解决方案。
我正在 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();
}