簡體   English   中英

JSpinner stateChanged 是如何工作的?

[英]How does JSpinner stateChanged works?

為什么代碼在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");
        }
    });

當您只單擊一次時,上面的代碼會顯示兩次消息。

生成 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();
    }
});

這不會阻止偵聽器被調用兩次,但阻止不必要地調用任何昂貴的代碼

剛剛遇到同樣的問題並找到了不同的解決方法,因為https://stackoverflow.com/a/19166589/5326620 中的一個導致它在第一次直接在文本字段上編輯日期時錯過了事件。

就我而言,我將 SpinnerDateModel 用於 Calendar.DAY_OF_MONTH(與 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 相等是在毫秒上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM