2011-05-29 73 views
2

我正在創建一個彈出式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

回答

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。根本不要這樣做。

3

你不能做到這一點,簡單明瞭。只有一個事件線程,當你坐在一個循環中等待某人點擊你的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