通过构建包含我想要的字段的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 - 指示用户可能选择的对象数组 可以使;如果对象是组件,则它们被正确呈现; 非String对象使用其toString方法呈现;如果这 参数为null,选项由外观和感觉确定
那么,我不能将自定义按钮作为参数传递吗?
看起来我必须制作自己的JDialog?对于这种情况,我不知道如何让它返回int
就像JOptionPane那样,任何推荐的教程?
在示例中options
是{"Aceptar", "Cancelar"}
,它们是显示的按钮,
PS。我完全控制了我添加到JPanel的字段。
这是JOptionPane的截图:
答案 0 :(得分:2)
我建议您在JPanel扩展类中定义一些属性,并使用PropertyChangeListener监听发生的更改并启用/禁用相对按钮。
这是一个article。
另一个问题可能是在组件层次结构中找到ok / cancel按钮,因为JDialog是通过JOptionPane创建的,而你没有对按钮的引用。这是一个有用的thread。
您可以使用putClientProperty方法将属性添加到JComponent。 当给定属性发生更改时,将引发PropertyChanged事件。
因此,在您的示例中,您可以定义一个布尔属性,指示插入到JDialog中的必需项。然后添加一个PropertyChangeListener,通知何时启用/禁用ok按钮。
答案 1 :(得分: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,对话框的所有组件都由此保存。然后它会通过对话框保存的所有组件进行递归。如果组件是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();
}
});
}
}