java – JOptionPane按钮和自定义面板之间的通信

我通过构建一个包含我想要的字段的JPanel并将其添加到JOption窗格来创建一个多输入对话框

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,我发现了这个:

options – an array of objects indicating the possible choices the user
can make; if the objects are components, they are rendered properly;
non-String objects are rendered using their toString methods; if this
parameter is null, the options are determined by the Look and Feel

那么,我不能将自定义按钮作为参数传递吗?

看起来我将不得不制作自己的JDialog?对于这种情况,我不知道如何让它像JOptionPane那样返回一个int,任何推荐的教程?

在示例中,选项是{“Aceptar”,“Cancelar”},它们是显示的按钮,

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

这是JOptionPane的截图:

解决方法:

我不认为您可以取消激活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,对话框的所有组件都由此保存.然后它会通过对话框保存的所有组件进行递归.如果组件是Container,则它会通过该容器进行递归.如果组件是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();
         }
      });
   }

}
上一篇:java – JDialog有问题


下一篇:java-将JDialog移近某个位置时,使其粘在另一个上