1

JSpinner の change イベントでコードが 2 回入るのはなぜですか?

private javax.swing.JSpinner spinner = new javax.swing.JSpinner()
spinner.setModel(new javax.swing.SpinnerDateModel());
    spinner.addChangeListener(new javax.swing.event.ChangeListener() {
        @Override
        public void stateChanged(javax.swing.event.ChangeEvent evt) {
            System.out.println("Just a test");
        }
    });

上記のコードは、一度だけクリックするとメッセージを 2 回表示します。

4

2 に答える 2

3

2 つのイベントが生成されます。1 つは選択解除された値用で、もう 1 つはコンポーネントで選択された新しい値用です。@camickr がコメントで指摘しているように、この動作はデフォルトでは発生しSpinnerDateModelますが、デフォルトでは発生しませんSpinnerNumberModel

あなたが使用できる回避策として

spinner.addChangeListener(new ChangeListener() {

    Object lastValue;

    @Override
    public void stateChanged(ChangeEvent evt) {

        if (lastValue != null && !spinner.getValue().equals(lastValue)) {
           // expensive code calls here!
        }
        lastValue = spinner.getValue();
    }
});

これにより、リスナーが 2 回呼び出されるの防ぐことはできませんが、高価なコードが不必要に呼び出されるのを防ぐことができます。

于 2013-10-03T18:32:48.193 に答える
0

https://stackoverflow.com/a/19166589/5326620にあるものは、テキストフィールドで日付を最初に直接編集するときにイベントを見逃すため、同じ問題にぶつかり、別の回避策を見つけました。

私の場合、Calendar.DAY_OF_MONTH (Calendar.DATE と同じ) に SpinnerDateModel を使用しています。SpinnerDateModel が真夜中に正確に値で初期化された場合、イベントが 2 回発生することはなくなりました。

Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR_OF_DAY, 0);
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
Date value = now.getTime();
JSpinner dateSpn = new JSpinner(new SpinnerDateModel(value, null, null, Calendar.DAY_OF_MONTH));

これはおそらく、JFormattedTextField の commitEdit が古い値と新しい値を等しいかどうかでテストし、Date の等しいかどうかがミリ秒単位であるためです。

于 2019-06-07T14:09:10.797 に答える