2012-10-10 71 views
4

我下面就如何創建自定義對話框,在Oracle教程:http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html的ActionListener上的JOptionPane

我有兩個按鈕:保存對象和刪除點擊它應該執行一個特定的代碼時對象。不幸的是,我似乎無法將任何ActionListener添加到JOptionPane按鈕,因此當它們被點擊時,什麼都不會發生。

任何人都可以幫助告訴我如何去做這件事嗎?以下是目前爲止對話框中的課程:

class InputDialogBox extends JDialog implements ActionListener, PropertyChangeListener { 
    private String typedText = null; 
    private JTextField textField; 

    private JOptionPane optionPane; 

    private String btnString1 = "Save Object"; 
    private String btnString2 = "Delete Object"; 

    /** 
    * Returns null if the typed string was invalid; 
    * otherwise, returns the string as the user entered it. 
    */ 
    public String getValidatedText() { 
     return typedText; 
    } 

    /** Creates the reusable dialog. */ 
    public InputDialogBox(Frame aFrame, int x, int y) { 
     super(aFrame, true); 

     setTitle("New Object"); 

     textField = new JTextField(10); 

     //Create an array of the text and components to be displayed. 
     String msgString1 = "Object label:"; 

     Object[] array = {msgString1, textField}; 

     //Create an array specifying the number of dialog buttons 
     //and their text. 
     Object[] options = {btnString1, btnString2}; 

     //Create the JOptionPane. 
     optionPane = new JOptionPane(array, 
       JOptionPane.PLAIN_MESSAGE, 
       JOptionPane.YES_NO_OPTION, 
       null, 
       options, 
       options[0]); 


     setSize(new Dimension(300,250)); 
     setLocation(x, y); 

     //Make this dialog display it. 
     setContentPane(optionPane); 
     setVisible(true); 

     //Handle window closing correctly. 
     setDefaultCloseOperation(DISPOSE_ON_CLOSE); 

     addWindowListener(new WindowAdapter() { 
      public void windowClosing(WindowEvent we) { 
       /* 
       * Instead of directly closing the window, 
       * we're going to change the JOptionPane's 
       * value property. 
       */ 
       optionPane.setValue(new Integer(
         JOptionPane.CLOSED_OPTION)); 
      } 
     }); 

     //Ensure the text field always gets the first focus. 
     addComponentListener(new ComponentAdapter() { 
      public void componentShown(ComponentEvent ce) { 
       textField.requestFocusInWindow(); 
      } 
     }); 

     //Register an event handler that puts the text into the option pane. 
     textField.addActionListener(this); 

     //Register an event handler that reacts to option pane state changes. 
     optionPane.addPropertyChangeListener(this); 
    } 

    /** This method handles events for the text field. */ 
    public void actionPerformed(ActionEvent e) { 
     optionPane.setValue(btnString1); 
     System.out.println(e.getActionCommand()); 
    } 

    /** This method reacts to state changes in the option pane. */ 
    public void propertyChange(PropertyChangeEvent e) { 
     String prop = e.getPropertyName(); 

     if (isVisible() 
     && (e.getSource() == optionPane) 
     && (JOptionPane.VALUE_PROPERTY.equals(prop) || 
      JOptionPane.INPUT_VALUE_PROPERTY.equals(prop))) { 
      Object value = optionPane.getValue(); 

      if (value == JOptionPane.UNINITIALIZED_VALUE) { 
       //ignore reset 
       return; 
      } 

      //Reset the JOptionPane's value. 
      //If you don't do this, then if the user 
      //presses the same button next time, no 
      //property change event will be fired. 
      optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE); 
      if (btnString1.equals(value)) { 
        typedText = textField.getText(); 
       String ucText = typedText.toUpperCase(); 
       if (ucText != null) { 
        //we're done; clear and dismiss the dialog 
        clearAndHide(); 
       } else { 
        //text was invalid 
        textField.selectAll(); 
        JOptionPane.showMessageDialog(
           InputDialogBox.this, 
            "Please enter a label", 
            "Try again", 
            JOptionPane.ERROR_MESSAGE); 
        typedText = null; 
        textField.requestFocusInWindow(); 
       } 
      } else { //user closed dialog or clicked delete 
       // Delete the object ... 

       typedText = null; 
       clearAndHide(); 
      } 
     } 
    } 

    /** This method clears the dialog and hides it. */ 
    public void clearAndHide() { 
     textField.setText(null); 
     setVisible(false); 
    } 
+0

我想說,我認爲您可能錯誤地混合了本教程中的一些概念。將JOptionPane嵌入到自定義JDialog中的想法對我來說似乎很奇怪。這裏期望的結果是什麼?按下按鈕是否需要更改此組件或其他? –

回答

12

我想你錯過了JOptionPane這一點。它配備了展現它自己對話的能力...

public class TestOptionPane02 { 

    public static void main(String[] args) { 
     new TestOptionPane02(); 
    } 

    public TestOptionPane02() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       JTextField textField = new JTextField(10); 

       String btnString1 = "Save Object"; 
       String btnString2 = "Delete Object"; 

       //Create an array of the text and components to be displayed. 
       String msgString1 = "Object label:"; 
       Object[] array = {msgString1, textField}; 
       //Create an array specifying the number of dialog buttons 
       //and their text. 
       Object[] options = {btnString1, btnString2}; 

       int result = JOptionPane.showOptionDialog(null, array, "", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE, "New Object", options, options[0]); 
       switch (result) { 
        case 0: 
         System.out.println("Save me"); 
         break; 
        case 1: 
         System.out.println("Delete me"); 
         break; 
       } 
      } 
     }); 
    } 
} 

做手工,你將不得不做一些更多的工作。

首先,你將不得不聽面板的屬性更改事件,尋找更改JOptionPane.VALUE_PROPERTY和忽略的JOptionPane.UNINITIALIZED_VALUE任何價值...

一旦檢測到變化,則需要處理你的對話。

您需要提取通過JOptionPane#getValue方法選擇的值,該方法返回Object。你將不得不打斷的意思到自己的價值......

不用說,JOptionPane.showXxxDialog方法做這一切爲你...

現在,如果你擔心不必經過的所有設置對話,我會寫一個實用的方法,要麼做到了完全或採取了必要的參數...但是這只是我

修訂

不知道爲什麼我沒有想到它越快。 ..

而不是傳遞一個String作爲選項參數的數組,傳遞一個JButton的數組。這樣你可以附加你自己的聽衆。

options - 指示用戶可能做出的可能選擇的對象數組; 如果對象是組件,它們會被正確渲染; 非String對象使用其toString方法呈現;如果此參數爲空,則選項由外觀確定

+0

以下是手動方法的[示例](http://stackoverflow.com/a/12451673/230513)。 – trashgod

0

爲了提高靈活性,您應該讓您的類擴展JFrame而不是JDialog。然後聲明你的按鈕爲JButtons: JButton saveButton = new JButton(「Save」);並添加一個actionListnener到這個按鈕: saveButton.addActionListener(); 要麼你可以在saveButton的括號內放一個類名,或者你可以簡單地將關鍵字'this'傳遞給它,並聲明一個名爲actionPerformed的方法來封裝當按下按鈕時應該執行的代碼。 有關更多詳細信息,請參閱此鏈接獲得JButton教程: http://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

+1

'JFrame'不提供形式,無論如何,我們應該避免(如果可能)從頂級容器 – MadProgrammer