2011-08-10 40 views
3

我想製作一個程序來管理一組運動員。每個玩家都有一個枚舉運動,而SportManager擁有便捷的工廠方法。我想要做的是打開一個對話框,其中包含名稱的JTextField和組合框以選擇一項運動。但是,我想停止用戶關閉對話框,而文本字段爲空,因此我編寫了一個PropertyChangeListener,以便當文本字段爲空時,它會發出蜂鳴聲以讓用戶知道。但是,如果用戶在發出嘟嘟聲之後在文本中放入了某些內容,它不會觸發監聽器,並且您不能在不按下取消的情況下關閉對話框,因爲該值已經是JOptionPane.OK_OPTION,並且取消是唯一方法改變JOptionPane.VALUE_PROPERTY。所以我試圖在偵聽器中添加如何在不觸發偵聽器的情況下從PropertyChangeListener更改JOptionPane的值?

message.setValue(JOptionPane.UNITIALIZED_VALUE); 

。然而,這只是立即關閉窗口而不給用戶一個機會來填寫文本字段,大概是因爲它觸發了我剛剛註冊的聽衆。我該如何做到這一點,以便它不止一次發出嗶嗶聲,並讓用戶有機會填寫該字段?

僅供參考newPlayer是我註冊動作的組件。

代碼:

newPlayer.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent e){ 
       Object[] msg = new Object [4]; 
       msg[0] = new JLabel("Name:"); 
       final JTextField nameField = new JTextField(); 
       msg[1]=nameField; 
       msg[2] = new JLabel("Sport: "); 
       JComboBox<Sport> major = new JComboBox<Sport>(SportManager.getAllSports()); 
       msg[3]=major; 
       final JOptionPane message = new JOptionPane(); 
       message.setMessage(msg); 
       message.setMessageType(JOptionPane.PLAIN_MESSAGE); 
       message.setOptionType(JOptionPane.OK_CANCEL_OPTION); 
       final JDialog query = new JDialog(gui,"Create a new player",true); 
       query.setContentPane(message); 
       query.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
       message.addPropertyChangeListener(
         new PropertyChangeListener() { 
          public void propertyChange(PropertyChangeEvent e) { 
           String prop = e.getPropertyName(); 


           if (query.isVisible()&& (e.getSource() == message)&& (prop.equals(JOptionPane.VALUE_PROPERTY))) { 
            if(nameField.getText().equals("")&&message.getValue().equals(JOptionPane.OK_OPTION)){ 
             Toolkit.getDefaultToolkit().beep(); 
             message.setValue(JOptionPane.UNINITIALIZED_VALUE); 
             return; 
            } 
            query.dispose(); 
           } 
          } 

         }); 
       query.pack(); 
       query.setVisible(true); 
       if(Integer.parseInt(message.getValue().toString())==JOptionPane.OK_OPTION){ 
        players.add(new Player(nameField.getText(),(Sport)major.getSelectedItem())); 
        edited=true; 
       } 
       gui.show(players); 
      } 
     }); 

回答

1

我不認爲你可以用JOptionPane的做,但你可以使用TaskDialog框架和其他一些使用。

您也可以自己創建對話框,將更改監聽器附加到您的字段並根據您的字段內容啓用/禁用「確定」按鈕。這個過程通常被稱爲「表單驗證」

+0

謝謝,會用NetBeans來試試這個 –

1

不過,我想從關閉對話框停止用戶而 文本字段爲空

我得到你要去哪裏,但的Java Swing這不是很好。您無法阻止偵聽器被調用。一個解決方案就是忽略這個調用,但這實施起來很複雜。

我解決這個問題的方法是讓彈出消失,檢查返回的值,如果它是空/空,嘟嘟聲並重新打開它,直到用戶填充某物。

0

解決此問題的一種方法是在對話框中添加一個CancelOk按鈕。然後,通過在角落裏的X禁用關閉彈出窗口,強制用戶單擊CancelOk完成/關閉對話框。現在,只需在文本字段中添加一個偵聽器,如果文本字段爲空,該偵聽器將禁用Ok按鈕。

從你的代碼判斷我假設你可以弄清楚如何實現這些步驟,但是如果你有麻煩告訴我們!祝你好運!

1

的JOptionPane內部不支持的輸入驗證(Bug Reference)。您最好的選擇是創建您自己的自定義JDialog,它支持在輸入數據無效時禁用「確定」按鈕。

因爲其他人談論它並給出解決方法,所以我建議您閱讀該錯誤報告。

1

不過,我想從關閉對話框阻止用戶在文本字段爲空

Stopping Automatic Dialog Closing在Swing教程中的部分中的CustomDialog例子有一個工作的例子,做到這一點。

採取快速瀏覽一下你的代碼和工作實例之後,我覺得你的代碼應該是這樣的:

if (query.isVisible() 
&& (e.getSource() == message) 
&& (prop.equals(JOptionPane.VALUE_PROPERTY))) 
{ 
    if (message.getValue() == JOptionPane.UNINITIALIZED_VALUE) 
     return; 

    if (nameField.getText().equals("") 
    && message.getValue().equals(JOptionPane.OK_OPTION)) 
    { 
     Toolkit.getDefaultToolkit().beep(); 
     message.setValue(JOptionPane.UNINITIALIZED_VALUE); 
    } 
    else 
     query.dispose(); 
} 

否則,我讓你與工作代碼比較你的代碼,看看有什麼區別在於。

相關問題