2012-01-06 32 views
4

我已經通過構建一個JPanel,與我的欄目並將它添加到但是我有與按鈕麻煩JOption窗格JOptionPane的按鈕和一個自定義面板之間的通信

JMainPanel mainPanel = new JMainPanel(mensaje, parametros, mgr); 

int i = JOptionPane.showOptionDialog(null, mainPanel, "Sirena", 
     JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, 
     new String[] {"Aceptar", "Cancelar"}, "Aceptar"); 

做多輸入對話框,因爲有些字段是必需的。如何讓每個必填字段啓用後啓用「確定」按鈕,或者點擊按鈕進行驗證,並且在填充每個必填字段之前不要關閉窗格?

從Java API,我發現這一點:

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

所以,我不能將自定義按鈕作爲參數傳遞嗎?

看起來像我將不得不讓我自己的JDialog?對於這種情況,我不知道如何使它像JOptionPane一樣返回int,任何推薦的教程?

在該示例中是options{"Aceptar", "Cancelar"}其是顯示的按鈕,

PS。我完全控制了我添加到JPanel的字段。

這是JOptionPane的截圖:

enter image description here

回答

2

我不認爲你可以取消激活JOptionPane的選擇按鈕,但仍然使用JOptionPane的一種方法是,只需重新顯示它,如果沒有設置必需的字段。您可以先顯示錯誤消息JOptionPane首先描述錯誤,然後顯示一個新的JOptionPane ,它保存與第二個參數相同的JPanel - 以便已輸入的數據沒有丟失。否則,你可能想創建自己的JDialog,順便說一下,這並不難。

編輯
我錯了。如果使用少量遞歸,您可以啓用和禁用對話框按鈕。

例如:

import java.awt.Component; 
import java.awt.Container; 
import java.awt.event.*; 
import java.util.HashSet; 
import java.util.Set; 

import javax.swing.*; 

public class Foo extends JPanel { 
    private static final String[] DIALOG_BUTTON_TITLES = new String[] { "Aceptar", "Cancelar" }; 
    private JCheckBox checkBox = new JCheckBox("Buttons Enabled", true); 
    private Set<AbstractButton> exemptButtons = new HashSet<AbstractButton>(); 

    public Foo() { 
     JButton exemptBtn = new JButton("Exempt Button"); 
     JButton nonExemptBtn = new JButton("Non-Exempt Button"); 

     add(checkBox); 
     add(exemptBtn); 
     add(nonExemptBtn); 
     exemptButtons.add(checkBox); 
     exemptButtons.add(exemptBtn); 

     checkBox.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent evt) { 
      allBtnsSetEnabled(checkBox.isSelected()); 
     } 
     }); 

    } 

    private void allBtnsSetEnabled(boolean enabled) { 
     JRootPane rootPane = SwingUtilities.getRootPane(checkBox); 
     if (rootPane != null) { 
     Container container = rootPane.getContentPane(); 
     recursiveBtnEnable(enabled, container); 
     } 
    } 

    private void recursiveBtnEnable(boolean enabled, Container container) { 
     Component[] components = container.getComponents(); 
     for (Component component : components) { 
     if (component instanceof AbstractButton && !exemptButtons.contains(component)) { 
      ((AbstractButton) component).setEnabled(enabled); 
     } else if (component instanceof Container) { 
      recursiveBtnEnable(enabled, (Container) component); 
     } 
     } 
    } 

    public int showDialog() { 
     return JOptionPane.showOptionDialog(null, this, "Sirena", 
      JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, 
      DIALOG_BUTTON_TITLES, "Aceptar"); 
    } 


    private static void createAndShowGui() { 
     Foo foo = new Foo(); 
     int result = foo.showDialog(); 
     System.out.println(DIALOG_BUTTON_TITLES[result]); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

該代碼使用監聽器來檢查JCheckBox的狀態,但你可以有聽衆(DocumentListeners)聽文本字段的文檔,如果你希望知道他們是否有數據或不。然後代碼獲取包含JCheckBox的JRootPane,然後是根窗格的contentPane,並且此對話框的所有組件都由此保存。然後它通過對話框中的所有組件遞歸。如果一個組件是一個容器,它通過該容器遞歸。如果組件是一個AbstractButton(如任何JButton或複選框),它將啓用或禁用 - 除了按鈕設置在豁免按鈕中。

更好的與文件的聽衆例如

import java.awt.*; 
import java.awt.event.*; 
import java.util.HashSet; 
import java.util.Set; 
import javax.swing.*; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

public class Foo2 extends JPanel { 
    private static final String[] DIALOG_BUTTON_TITLES = new String[] { 
     "Aceptar", "Cancelar" }; 
    private static final int FIELD_COUNT = 10; 
    private Set<AbstractButton> exemptButtons = new HashSet<AbstractButton>(); 
    private JTextField[] fields = new JTextField[FIELD_COUNT]; 

    public Foo2() { 
     setLayout(new GridLayout(0, 5, 5, 5)); 
     DocumentListener myDocListener = new MyDocumentListener(); 
     for (int i = 0; i < fields.length; i++) { 
     fields[i] = new JTextField(10); 
     add(fields[i]); 
     fields[i].getDocument().addDocumentListener(myDocListener); 
     } 

     // cheating here 

     int timerDelay = 200; 
     Timer timer = new Timer(timerDelay , new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      checkDocsForText();    
     } 
     }); 
     timer.setRepeats(false); 
     timer.setInitialDelay(timerDelay); 
     timer.start(); 

    } 

    private void checkDocsForText() { 
     for (JTextField field : fields) { 
     if (field.getText().trim().isEmpty()) { 
      allBtnsSetEnabled(false); 
      return; 
     } 
     } 
     allBtnsSetEnabled(true); 
    } 

    private void allBtnsSetEnabled(boolean enabled) { 
     JRootPane rootPane = SwingUtilities.getRootPane(this); 
     if (rootPane != null) { 
     Container container = rootPane.getContentPane(); 
     recursiveBtnEnable(enabled, container); 
     } 
    } 

    private void recursiveBtnEnable(boolean enabled, Container container) { 
     Component[] components = container.getComponents(); 
     for (Component component : components) { 
     if (component instanceof AbstractButton && !exemptButtons.contains(component)) { 
      ((AbstractButton) component).setEnabled(enabled); 
     } else if (component instanceof Container) { 
      recursiveBtnEnable(enabled, (Container) component); 
     } 
     } 
    } 

    public int showDialog() { 
     return JOptionPane.showOptionDialog(null, this, "Sirena", 
      JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, 
      DIALOG_BUTTON_TITLES, "Aceptar"); 
    } 

    private class MyDocumentListener implements DocumentListener { 

     public void removeUpdate(DocumentEvent arg0) { 
     checkDocsForText(); 
     } 

     public void insertUpdate(DocumentEvent arg0) { 
     checkDocsForText(); 
     } 

     public void changedUpdate(DocumentEvent arg0) { 
     checkDocsForText(); 
     } 
    } 


    private static void createAndShowGui() { 
     Foo2 foo = new Foo2(); 
     int result = foo.showDialog(); 
     if (result >= 0) { 
     System.out.println(DIALOG_BUTTON_TITLES[result]); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 

} 
2

我建議你來定義一些屬性到您的JPanel擴展分類,並使用PropertyChangeListener聽的發生變化,並啓用/禁用相對按鈕。

這是article

另一個問題可能是在組件層次結構中找到ok/cancel按鈕,因爲JDialog是通過JOptionPane創建的,並且沒有對按鈕的引用。這是一個有用的thread

您可以使用putClientProperty方法將屬性添加到JComponent。 當給定屬性發生更改時,會引發PropertyChanged事件。

因此,在您的示例中,您可以定義一個布爾屬性,指示需要插入到JDialog中的布爾屬性。然後添加一個PropertyChangeListener,通知何時啓用/禁用ok按鈕。

相關問題