1

为什么代码在JSpinner的change事件中输入两次?

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

当您只单击一次时,上面的代码显示了两次消息。

4

2 回答 2

3

生成 2 个事件:一个用于取消选择的值,另一个用于在组件中选择的新值。正如@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();
    }
});

这不会阻止侦听器被调用两次,但防止不必要地调用任何昂贵的代码

于 2013-10-03T18:32:48.193 回答
0

刚刚遇到同样的问题并找到了不同的解决方法,因为https://stackoverflow.com/a/19166589/5326620中的那个导致它在第一次直接在文本字段上编辑日期时错过了事件。

在我的例子中,我为 Calendar.DAY_OF_MONTH 使用 SpinnerDateModel(与 Ca​​lendar.DATE 相同)。如果 SpinnerDateModel 恰好在午夜用一个值初始化,则该事件不再触发两次。

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 回答