JOptionPane按钮和自定义面板之间的通信 [英] Communication between JOptionPane buttons and a custom panel

查看:68
本文介绍了JOptionPane按钮和自定义面板之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过使用所需字段构建一个JPanel并将其添加到JOption窗格中,从而创建了一个多输入对话框

I have made a multiple input dialog by building a JPanel with the fields I want and adding it to a JOption pane

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");

但是我在按钮上遇到了麻烦,因为某些字段是必需的.在每个必填字段都显示完后,如何使确定"按钮启用,或者单击该按钮进行验证并且在填写完所有必填字段之前不关闭窗格?

However I'm having trouble with the buttons, because some of the fields are required. How can I make the "Ok" button to be enabled once every required field is up, or making the click on the button to make the validations and do not close the pane until every required field is filled?

从Java API中,我发现了这一点:

From the Java API, I found this:

options-一组对象,指示用户的可能选择 可以使;如果对象是组件,则正确渲染它们; 非字符串对象使用其toString方法呈现;如果这 参数为null,选项由外观决定

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

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

So, can't I pass custom buttons as parameter?

看起来我将必须制作自己的JDialog?在哪种情况下,我不知道如何使其像JOptionPane一样返回int,是否有任何推荐的教程?

Looks like I will have to make my own JDialog? for which case, I don't know how to make it return an int just like JOptionPane does, any recommended tutorial?

在示例中,options{"Aceptar", "Cancelar"},它们是显示的按钮,

In the example options is {"Aceptar", "Cancelar"} which are the displayed buttons,

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

PS. I have full controll over the fields I added to the JPanel.

这是JOptionPane的屏幕截图:

This is a screenshot of the JOptionPane:

推荐答案

我不认为您可以停用JOptionPane的选择按钮,但是仍然可以使用JOptionPane的一种方法是,如果尚未设置必填字段.您可以先显示一条错误消息JOptionPane来描述该错误,然后显示一个新的JOptionPane ,该JOptionPane 与其第二个参数具有相同的JPanel -这样就不会丢失已输入的数据.否则,您可能想创建自己的JDialog,这并不难做到.

I don't think that you can de-activate a JOptionPane's selections buttons, but one way to still use the JOptionPane is to simply re-display it if the required fields have not been set. You could display an error message JOptionPane first describing the error, and then display a new JOptionPane that holds the same JPanel as its second parameter -- so that the data already entered has not been lost. Otherwise, you may want to create your own JDialog which by the way isn't that hard to do.

修改
我错了.如果您使用一点递归,则可以启用和禁用对话框按钮.

Edit
I'm wrong. You can enable and disable the dialog buttons if you use a little recursion.

例如:

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或复选框),则它将启用或禁用-除了保存在豁免按钮集中的按钮之外.

This code uses listeners to check the state of a JCheckBox, but you can have listeners (DocumentListeners) listening to text field documents if you desire to know if they have data or not. The code then gets the JRootPane that holds the JCheckBox, then the root pane's contentPane, and all components of the dialog are held by this. It then recurses through all the components held by the dialog. If a component is a Container, it recurses through that container. If the component is an AbstractButton (such any JButton or checkbox), it enables or disables -- except for buttons held in the exempt buttons set.

文档监听器的更好示例

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();
         }
      });
   }

}

这篇关于JOptionPane按钮和自定义面板之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆