3

私はスポーツ選手のグループを管理するプログラムを作ろうとしています。各プレーヤーには列挙型Sportがあり、SportManagerには便利なファクトリメソッドがあります。私がやろうとしているのは、名前のJTextFieldとスポーツを選択するためのコンボボックスがあるダイアログを開くことです。ただし、テキストフィールドが空白のときにユーザーがダイアログを閉じないようにしたいので、テキストフィールドが空白のときにユーザーに通知するためにビープ音が鳴るようにPropertyChangeListenerを作成しました。ただし、ビープ音を鳴らした後にユーザーがテキストに何かを入力した場合、リスナーはトリガーされず、値はすでにJOptionPane.OK_OPTIONであり、キャンセルが唯一の方法であるため、キャンセルを押さずにダイアログを閉じることはできません。 JOptionPane.VALUE_PROPERTYを変更します。だから私は追加しようとしました

message.setValue(JOptionPane.UNITIALIZED_VALUE);

リスナー内。ただし、これは、ユーザーにテキストフィールドに入力する機会を与えずに、ウィンドウをすぐに閉じるだけです。おそらく、登録したばかりのリスナーがトリガーされるためです。ビープ音が2回以上鳴り、ユーザーがフィールドに入力できるようにするにはどうすればよいですか?

参考までに、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

ただし、テキストフィールドが空白のときにユーザーがダイアログを閉じないようにしたい

私はあなたが行くところを理解しますが、JavaSwingはこれがあまり得意ではありません。リスナーが呼び出されないようにする方法はありません。解決策は呼び出しを無視することですが、これは実装が複雑です。

この問題を解決する方法は、ポップアップを非表示にし、戻り値を確認し、null /空の場合はビープ音を鳴らして、ユーザーが何かを入力するまで再度開くことです。

于 2011-08-10T23:03:42.033 に答える
1

JOptionPaneでそれを行うことはできないと思いますが、TaskDialogフレームワークと他のいくつかを使用して使用することはできます。

自分でダイアログを作成したり、フィールドに変更リスナーをアタッチしたり、フィールドの内容に基づいて[OK]ボタンを有効/無効にしたりすることもできます。このプロセスは通常、「フォーム検証」と呼ばれます

于 2011-08-11T00:42:50.230 に答える
1

JOptionPaneは、入力の検証を内部的にサポートしていません(バグリファレンス)。最善の策は、入力データが無効な場合に[OK]ボタンを無効にすることをサポートする独自のカスタムJDialogを作成することです。

他の人がバグレポートについて話し、回避策を提供しているので、バグレポートを読むことをお勧めします。

于 2011-08-11T00:43:36.703 に答える
1

ただし、テキストフィールドが空白のときにユーザーがダイアログを閉じないようにしたい

自動ダイアログクロージングの停止CustomDialogに関するSwingチュートリアルのセクションの例には、これを行う実際の例があります。

コードと実際の例をざっと見てみると、コードは次のようになっているはずです。

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 に答える
0

この問題を解決する1つの方法は、ダイアログCancelOkボタンを追加することです。次に、隅にあるを介してポップアップを閉じることを無効にし、ユーザーにいずれかXをクリックするか、ダイアログを終了/閉じるように強制します。ここで、テキストフィールドにリスナーを追加するだけで、テキストフィールドが空白の場合にボタン が無効になります。CancelOkOk

コードから判断すると、これらの手順を実装する方法を理解できると思いますが、問題が発生した場合はお知らせください。幸運を!

于 2011-08-11T00:00:35.097 に答える