为什么以下代码不起作用?基本上,这是一个更难的程序的简化版本,在这个程序中,我试图创建一个可运行的初始屏幕,其中的选择将具有链接到不同runnables的按钮,但这不会像我预期的那样运行。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Runnables {
static Runnable runone;
static Runnable runtwo;
static JFrame frame = new JFrame();
static JButton button1 = new JButton("Initial screen");
static JButton button2 = new JButton("After button click screen");
public static void main(String[] args) {
runone = new Runnable() {
@Override
public void run() {
frame.removeAll();
frame.revalidate();
frame.repaint();
frame.add(button2);
}
};
runtwo = new Runnable() {
@Override
public void run() {
frame.setSize(800, 600);
frame.setVisible(true);
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
runone.run();
System.out
.println("This is performed, but the button doesnt change");
}
});
frame.add(button1);
}
};
runtwo.run();
}
}
答案 0 :(得分:4)
Runnable
没有任何特殊之处可以防止这种情况发生。您的代码示例代表如下:
public void actionPerformed(ActionEvent arg0) {
runone.run();
System.out.println("This is performed, but the button doesnt change");
}
和
public void actionPerformed(ActionEvent arg0) {
frame.removeAll();
frame.revalidate();
frame.repaint();
frame.add(button2);
System.out.println("This is performed, but the button doesnt change");
}
获取代码并在System.out.println
中添加runone.run
调试语句表明它实际上正在执行。
我认为您的代码示例是您问题的简化演示;您可能希望首先考虑将其作为“普通函数”进行操作(上面的第二个示例,将Runnables组合在一起),然后分离成不同的Runnables。
修改 - 要让您的示例正常工作,需要记住的是JFrame
使用contentPane来托管其子代 - frame.add
存在是为了方便要添加到contentPane (基于javadoc for JFrame),但removeAll
不会这样做(基于我刚刚使用它)。此外,在添加按钮后调用validate
将再次正确地重新布局子组件以显示第二个按钮。
将此runone
的定义替换为此定义,您的示例将起作用:
runone = new Runnable() {
@Override
public void run() {
frame.getContentPane().removeAll();
frame.add(button2);
frame.validate();
}
};
答案 1 :(得分:3)
<击>
您应该首先将Runnable
对象封装在Thread
对象中,然后通过调用start()
来启动您的线程。例如:
Runnable r = ...;
Thread thread = new Thread(r);
thread.start();
击> <击> 撞击>
修改强>
你应该确保从EDT调用你的Runnable。例如:
SwingUtilties.invokeLater(r);
或者您可以使用SwingWorker
来处理与swing代码有关的密集型操作。请参阅this answer以了解SwingWorker的工作原理。