【发布时间】:2016-02-10 12:56:26
【问题描述】:
我对 AWT/Swing 编程很陌生,所以我看不到问题所在。 当事件被调用时,窗口甚至在移除组件之前就冻结了,我必须手动关闭它。
那么,这段代码有什么问题?
@Override
public void actionPerformed(ActionEvent event)
{
if(((JButton)event.getSource()).getName() == "start")
{
for(Component c : QuizShow.frame.getContentPane().getComponents())
{
if(c.getName() == "wrapper")
{
final JPanel wrapper = (JPanel) c;
SwingUtilities.invokeLater
(
new Runnable()
{
public void run() {
wrapper.removeAll();
QuizPanel qp = new MainQuizPanel();
qp.setup();
wrapper.add(qp);
}
}
);
break;
}
}
}
System.out.println(event.getSource());
}
编辑: 这是 qp.setup() 无效:
public void setup()
{
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 6; j++)
{
questions[i*6+j] = new JButton();
questions[i*6+j].setText(""+i*10);;
add(questions[i*6+j]);
}
}
}
这是 main(String[] args) 类:
SwingUtilities.invokeLater
(
new Runnable()
{
public void run() {
frame = new QuizShowFrame("Quiz Show");
frame.setSize(800, 600);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.setVisible(true);
}
}
);
还有 QuizShowFrame 类:
public class QuizShowFrame extends JFrame
{
private static final long serialVersionUID = 1L;
public QuizPanel introPanel = new Intro();
public JPanel p = new JPanel();
public QuizShowFrame(String name)
{
super(name);
this.setLayout(new BorderLayout());
Container c = this.getContentPane();
p.setBorder(new EmptyBorder(5,5,5,5));
p.setName("wrapper");
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
c.add(p);
p.add(introPanel);
try
{
introPanel.setup();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
最后是 Intro 类:
public void setup()
{
//...skipped JTextPanes...
JButton gameStart = new JButton("Start the quiz show");
gameStart.setName("start");
try {
gameStart.addActionListener(Listener.class.newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
add(gameStart);
}
【问题讨论】:
-
你这里有某种永无止境的递归吗?
-
你有没有通过单步执行代码进行调试?
-
附带问题,不要这样做:
if(c.getName() == "wrapper")。使用 equals 或 equalsIgnoreCase。至于您的主要问题,您正在某处踩踏 Swing 事件线程,根据发布的代码 sn-p 很难说。创建并发布您的minimal reproducible example。请注意,这不是完整的代码转储——请阅读链接。 -
在
actionPerformed()中,您已经在 EDT 上运行。在 EDT 上调用所有 Swing 事件。所以没有必要使用SwingUtilities.invokeLater()。只需在 EDT 上做所有这些事情。