JFrame问题

问题描述:

我正在创建一个弹出式JFrame,它将显示一条消息和是/否按钮。我以两种方式使用这种方法。在1中,主程序调用此方法,另一方面,在先前的JFrame关闭后直接调用此方法。这种方法在从主程序调用时起作用,但当另一个JFrame调用它时,在此方法中创建的JFrame显示为完全空白,并且GUI冻结。我不能退出JFrame,但我可以移动它。冻结是Thread.yield的结果,因为响应始终为空,但在哪些情况下JFrame无法正确创建?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; 
    } 
+2

您不应该使用JFrame作为对话框。而是使用JDialog或JOptionPane。 – 2011-05-29 17:06:06

同样,您不应该使用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。根本不要这样做。

你不能做到这一点,简单明了。只有一个事件线程,当你坐在一个循环中等待某人点击你的JFrame时,你正在绑定该线程,以便不能处理任何事件。

不要尝试从JFrame中创建自己的对话框 - 使用JOptionPaneJDialog,这些对话框旨在为您在内部处理这种情况。

+0

那么在某些情况下它是如何工作的? – 2011-05-29 17:10:42

+0

@DazSlayer:看到我上面的答案。当您在Swing GUI中调用此调用时,您正在调用Swing事件调度线程上的线程冻结循环,并且这将冻结该相同的线程,从而有效地将您的GUI瘫痪。 +1给Friedman-Hill教授。 – 2011-05-29 17:16:46