I don't think you can deactivate the JOptionPane selection buttons, but one way to use JOptionPane is to simply re-display it if the required fields have not been set. You can display a JOptionPane error message that first describes the error, and then display a new JOptionPane that contains the same JPanel as the second parameter, so that the data you have already entered has not been lost. Otherwise, you can create your own JDialog, which, incidentally, is not so difficult to do.
Edit
I'm wrong. You can enable and disable the dialog buttons if you use a small recursion.
For instance:
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(); } }); } }
This code uses listeners to check the status of the JCheckBox, but you can listen to (DocumentListeners) text field listeners if you want to know if they have data or not. Then the code gets a JRootPane that contains the JCheckBox, and then the contents area of โโthe root panel and all the dialogue components are held by that. Then it repeats through all the components held by the dialog. If the component is a container, it passes through that container. If the component is an AbstractButton (for example, any JButton or flag), it enables or disables - with the exception of buttons held in sets of released buttons.
Best example with document listeners
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); }