简体   繁体   English

Java中奇怪的SpinnerNumberModel行为

[英]Odd SpinnerNumberModel behavior in Java

I'm trying to setup a JSpinner using a SpinnerNumberModel with value = 0.0005, min = 0.0, max = 1.0, and step size = 0.0005. 我正在尝试使用SpinnerNumberModel设置JSpinner,其值为0.0005,min = 0.0,max = 1.0,步长= 0.0005。 However, when I create a spinner with these parameters I observe very strange behavior. 但是,当我使用这些参数创建一个微调器时,我会发现非常奇怪的行为。 Rather than starting at 0.0005 and increasing by 0.0005 with each click of the up arrow, the value seems to stick at 0. 每次单击向上箭头,而不是从0.0005开始并增加0.0005,该值似乎保持为0。

To make sure this isn't just a formatting issue, I printed out the value of the spinner after each change event. 为了确保这不仅仅是格式化问题,我在每次更改事件后打印出微调器的值。 Surely enough, for each click of the up arrow, the console shows the value as 0 and then 0.0005, regardless how many times the spinner has been clicked. 当然,每次单击向上箭头,控制台都会将值显示为0,然后显示0.0005,无论旋转器被点击多少次。

Below is the code I've used to test this, including a spinner with slightly different values that works just fine for comparison purposes. 下面是我用来测试它的代码,包括一个值略有不同的微调器,它可以很好地用于比较目的。

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

public class Main {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setSize(200, 80);
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005));
        final JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0.05, 0.0, 1.0, 0.05));
        panel.add(spinner1, BorderLayout.NORTH);
        panel.add(spinner2, BorderLayout.SOUTH);
        frame.add(panel);
        spinner1.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                System.out.println("spinner1: " + ((Number) spinner1.getValue()).doubleValue());
            }
        });
        spinner2.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                System.out.println("spinner2: " + ((Number) spinner2.getValue()).doubleValue());
            }
        });
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

Can anyone explain to me why spinner2 works as intended, but spinner1 does not? 任何人都可以向我解释为什么spinner2按预期工作,但spinner1不?

Thanks. 谢谢。

Edit: Thanks to Peter for pointing out that the formatting of the spinner's text field actually has an effect on the stored value. 编辑:感谢Peter指出微调器文本字段的格式实际上对存储值有影响。 To get the first spinner to work as intended, I added the line: spinner1.setEditor(new JSpinner.NumberEditor(spinner1, "0.0000")); 为了让第一个微调器按预期工作,我添加了一行: spinner1.setEditor(new JSpinner.NumberEditor(spinner1, "0.0000")); .

the problem is this in the JFormattedTextField used by the spinner. 问题在于微调器使用的JFormattedTextField。 In that editor you can find: 在该编辑器中,您可以找到:

public void commitEdit() throws ParseException {
    AbstractFormatter format = getFormatter();

    if (format != null) {
        setValue(format.stringToValue(getText()), false, true);
    }
}

your spinner display 0.0005 as 0.0, if you increment it first put 0.0 in your model and then increments to 0.0005, you event actually captures it but your textfield only sees 0.0 你的微调器显示0.0005为0.0,如果你增加它首先在你的模型中加0.0然后增加到0.0005,你事件实际捕获它但你的文本域只看到0.0

so solution will be to change the formatting of the spinner textfield. 所以解决方案是更改微调器文本字段的格式。

you can overide the editor 你可以覆盖编辑器

final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005)) {
      @Override
      protected JComponent createEditor( SpinnerModel model )
      {
        return new NumberEditor(this, "0.0000");//needed decimal format
      }
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM