我正在创建一个弹出式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;
}
Run Code Online (Sandbox Code Playgroud)
同样,您不应该将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);
Run Code Online (Sandbox Code Playgroud)
还有这个:
while(response == null)
{
Thread.yield();
}
Run Code Online (Sandbox Code Playgroud)
永远不应该在主Swing线程,EDT或事件派发线程上调用.代码工作的原因是因为你在EDT之上调用了这一点,但是当你在EDT上调用它时它冻结了EDT,从而冻结了整个GUI.根本就不要这样做.