我正在创建一个弹出式JFrame,它会有一条消息和是/否按钮。我以两种方式使用这种方法。在1中,主程序调用此方法,而在另一个中,此方法在前一个JFrame关闭后直接调用。此方法在从主程序调用时起作用,但当另一个JFrame调用它时,在此方法中创建的JFrame显示为完全空白并且GUI冻结。我不能退出JFrame,但我可以移动它。冻结是Thread.yield的结果,因为响应始终为null,但在什么情况下JFrame无法正确创建?
注意:响应是一个静态变量。此外,当此JFrame由另一个JFrame创建时,原始JFrame无法正确退出。该JFrame具有JComboBox,并且下拉列表中将冻结所选选项。当它不调用此方法时,它会正确关闭。
public static String confirmPropertyPurchase(String message)
{
response = null;
final JFrame confirmFrame = new JFrame("Confirm");
confirmFrame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent ev){
response = "No";
}
public void windowDeactivated(WindowEvent e) {
confirmFrame.requestFocus();
}
});
final JPanel confirmPanel = new JPanel();
final JButton yes = new JButton();
final JButton no = new JButton();
yes.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
response = "Yes";
confirmFrame.setVisible(false);
}
});
no.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
response = "No";
confirmFrame.setVisible(false);
}
});
final JLabel confirmLabel = new JLabel(" " + message);
yes.setText("Yes");
yes.setPreferredSize(new Dimension(100, 100));
no.setText("No");
no.setPreferredSize(new Dimension(100,100));
confirmFrame.add(confirmLabel, BorderLayout.CENTER);
confirmPanel.add(yes);
confirmPanel.add(no);
confirmFrame.add(confirmPanel, BorderLayout.AFTER_LAST_LINE);
confirmFrame.setPreferredSize(new Dimension(520, 175
));
confirmFrame.pack();
confirmFrame.setVisible(true);
while(response == null)
{
Thread.yield();
}
return response;
}
答案 0 :(得分:5)
同样,您不应该将JFrame用作对话框。实际上,您的整个代码可以用简单的JOptionPane替换。如,
Component parent = null; // non-null if being called by a GUI
queryString = "Do you want fries with that?";
int intResponse = JOptionPane.showConfirmDialog(parent, queryString,
"Confirm", JOptionPane.YES_NO_OPTION);
myResponse = (intResponse == JOptionPane.YES_OPTION) ? "Yes" : "No";
System.out.println(myResponse);
而且:
while(response == null)
{
Thread.yield();
}
永远不应该在主Swing线程,EDT或事件派发线程上调用。代码工作的原因是因为你在EDT之上调用了这一点,但是当你在EDT上调用它时它冻结了EDT,从而冻结了整个GUI。根本就不要这样做。
答案 1 :(得分:3)
你做不到这一点,简单明了。只有一个事件线程,当你坐在一个循环中等待有人点击你的JFrame
时,你就会绑定那个线程,以便不能处理任何事件。
请勿尝试使用JFrame
- 使用JOptionPane
或JDialog
创建自己的对话框,这些对话框旨在为您内部处理此情况。