3

我想要一个 JSpinner 来显示一个非模式化的数字序列(比如,一个素数序列)。这种模式对于 SpinnerNumberModel 来说太复杂了,所以我决定继承 SpinnerListModel。构造函数看起来像这样:

public CustomSpinnerListModel() {
    Vector<Integer> values = new Vector<Integer>();
    values.add(1);
    values.add(3);
    values.add(5);
    values.add(7);

    this.setList(values);
}

这可以很好地生成模型,我可以使用 JSpinner 上的按钮来移动这些值。但是,输入值不起作用。例如,如果微调器设置为 3,而我输入 7,它仍为 3(可能是因为它认为 7 不是有效值)。这适用于 SpinnerNumberModel,所以我不确定发生了什么。

编辑:我发现如果我将数字保存为字符串值,输入就可以了。但是,SpinnerNumberModel 将所有内容保存为整数,这也有效。所以我不确定为什么我的整数不起作用,但 SpinnerNumberModel 可以。

4

2 回答 2

3

我认为以下解决方案比实施 Formatter 的建议更好,因为它不是格式问题,而是限制可能值的问题,这应该是模型的责任。我遇到了类似的问题,偶然发现了这个线程解决方案,导致实现非常丑陋。所以希望我想出的东西能让你远离麻烦。

这可以很好地生成模型,我可以使用 JSpinner 上的按钮来移动这些值。但是,输入值不起作用。例如,如果微调器设置为 3,而我输入 7,它仍为 3(可能是因为它认为 7 不是有效值)。这适用于 SpinnerNumberModel,所以我不确定发生了什么。

这里的问题是使用 setModel 设置新模型具有未记录的副作用,即根据模型的类型更改 JTextFieldEditor 属性:http: //fuseyism.com/classpath/doc/javax/swing/JSpinner-source.html

默认情况下,JSpinner 使用 SpinnerNumberModel 类的模型和 DefaultNumberEditor 类的编辑器。当您将模型设置为 SpinnerListModel 时,它将改为使用 ListEditor。在您的情况下,这是一个糟糕的选择,因为它要求您将每个素数输入到列表中,以将其提供给 SpinnerListModel 进行输入验证。否则,正如您所指出的,您的输入将被忽略。

所以这里的简单解决方案是继承 SpinnerNumberModel,它允许任何数字,而不是特定的值列表:

class PrimeNumberModel extends SpinnerNumberModel {
    Object currentValue;

    @Override
    public Object getNextValue() {
        return findNextPrimeFrom(currentValue);
    } 

    @Override
    public Object getPreviousValue() {
        return findPreviousPrimeFrom(currentValue);
    }

    @Override
    public void setValue(Object o) {
        throwOnNonePrime(o); //Verify Input
        super.setValue(o);
    }

    private void throwOnNonePrime(Object o) {
        try {
            int num = Integer.valueOf(o.toString());
            if(!isPrime(num))
                throw new IllegalArgumentException(o.toString());
        } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException(o.toString());
        }
    }
}
于 2014-08-02T10:24:57.493 回答
-1

我认为您可以使用字符串来完成,然后使用一种方法来获取数字。像这样:

Spinner1(){
          String[] values={"1","3","5","7"};
          SpinnerModel model=new SpinnerListModel(values);
          JSpinner spinner=new JSpinner(model);
}
int getValue(Object obj){
    int out=0;
    return out=Integer.parseInt((String)obj);
}
于 2013-04-04T19:59:08.893 回答