3

我正在尝试制作一个程序来管理一组体育运动员。每个玩家都有一个枚举 Sport,SportManager 有方便的工厂方法。我想要做的是打开一个对话框,其中有一个 JTextField 作为名称和一个组合框来选择一项运动。但是,我想阻止用户在文本字段为空白时关闭对话框,所以我编写了一个 PropertyChangeListener 以便当文本字段为空白时,它会发出哔哔声让用户知道。但是,如果用户在关闭哔声后在文本中输入内容,它不会触发侦听器,并且您无法在不按取消的情况下关闭对话框,因为该值已经是 JOptionPane.OK_OPTION,并且取消是唯一的方法更改 JOptionPane.VALUE_PROPERTY。所以我尝试添加

message.setValue(JOptionPane.UNITIALIZED_VALUE);

听者内。然而,这只是立即关闭窗口而没有让用户有机会填写文本字段,大概是因为它触发了我刚刚注册的侦听器。我如何让它发出不止一次的哔哔声并让用户有机会填写该字段?

仅供参考 newPlayer 是我正在向其注册操作的组件。

代码:

    newPlayer.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                Object[] msg = new Object [4];
                msg[0]  = new JLabel("Name:");
                final JTextField nameField = new JTextField();
                msg[1]=nameField;
                msg[2] = new JLabel("Sport: ");
                JComboBox<Sport> major = new JComboBox<Sport>(SportManager.getAllSports());
                msg[3]=major;
                final JOptionPane message = new JOptionPane();
                message.setMessage(msg);
                message.setMessageType(JOptionPane.PLAIN_MESSAGE);
                message.setOptionType(JOptionPane.OK_CANCEL_OPTION);
                final JDialog query = new JDialog(gui,"Create a new player",true);
                query.setContentPane(message);
                query.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
                message.addPropertyChangeListener(
                        new PropertyChangeListener() {
                            public void propertyChange(PropertyChangeEvent e) {
                                String prop = e.getPropertyName();


                                if (query.isVisible()&& (e.getSource() == message)&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {
                                    if(nameField.getText().equals("")&&message.getValue().equals(JOptionPane.OK_OPTION)){
                                        Toolkit.getDefaultToolkit().beep();
                                        message.setValue(JOptionPane.UNINITIALIZED_VALUE);
                                        return;
                                    }
                                    query.dispose();
                                }
                            }

                        });
                query.pack();
                query.setVisible(true);
                if(Integer.parseInt(message.getValue().toString())==JOptionPane.OK_OPTION){
                    players.add(new Player(nameField.getText(),(Sport)major.getSelectedItem()));
                    edited=true;
                }
                gui.show(players);
            }
        });
4

5 回答 5

1

我不认为你可以使用 JOptionPane 来做到这一点,但你可以使用TaskDialog框架和其他一些框架。

您还可以自己创建一个对话框,将更改侦听器附加到您的字段,并根据您的字段内容启用/禁用 OK 按钮。这个过程通常称为“表单验证”

于 2011-08-11T00:42:50.230 回答
1

JOptionPane 内部不支持输入验证(错误参考)。最好的办法是创建自己的自定义 JDialog,它支持在输入数据无效时禁用 OK 按钮。

我建议阅读错误报告,因为其他人谈论它并提供解决方法。

于 2011-08-11T00:43:36.703 回答
1

但是,我想阻止用户在文本字段为空白时关闭对话框

CustomDialogSwing 教程中关于停止自动对话框关闭部分的示例有一个可以执行此操作的示例。

在快速查看您的代码和工作示例后,我认为您的代码应该类似于:

if (query.isVisible()
&& (e.getSource() == message)
&& (prop.equals(JOptionPane.VALUE_PROPERTY)))
{
    if (message.getValue() == JOptionPane.UNINITIALIZED_VALUE)
        return;

    if (nameField.getText().equals("")
    && message.getValue().equals(JOptionPane.OK_OPTION))
    {
        Toolkit.getDefaultToolkit().beep();
        message.setValue(JOptionPane.UNINITIALIZED_VALUE);
    }
    else
        query.dispose();
}

否则,我会让您将您的代码与工作代码进行比较,看看有什么区别。

于 2011-08-11T00:57:55.273 回答
1

但是,我想阻止用户在文本字段为空白时关闭对话框

我知道你要去哪里,但是 Java Swing 不是很擅长这个。您无法阻止侦听器被调用。一个解决方案是忽略该调用,但这实现起来很复杂。

我解决这个问题的方法是让弹出窗口消失,检查返回的值,如果它是空/空,哔哔声并重新打开它,直到用户填写一些东西。

于 2011-08-10T23:03:42.033 回答
0

解决此问题的一种方法是在对话框中添加一个Cancel和按钮。Ok然后,禁用通过X角落中的关闭弹出窗口,强制用户单击CancelOk完成/关闭对话框。Ok现在,只需向文本字段添加一个侦听器,如果文本字段为空 ,它将禁用按钮。

从您的代码来看,我假设您可以弄清楚如何实现这些步骤,但如果您遇到问题,请告诉我们!祝你好运!

于 2011-08-11T00:00:35.097 回答