java - 使用子类 SpinnerListModel 在 JSpinner 中键入数字

标签 java swing jspinner

我想要一个 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 可以。

最佳答案

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

This generates the model just fine and I can move through the values using the buttons on the JSpinner. However, typing a value in doesn't work. For instance, if the spinner is set to 3 and I type in 7, it remains at 3 (presumably because it doesn't think that 7 is a valid value). This works with the SpinnerNumberModel, so I'm not sure what's going on.

这里的问题是,使用 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());
        }
    }
}

关于java - 使用子类 SpinnerListModel 在 JSpinner 中键入数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15377180/

相关文章:

java - 如何使用 Spring Boot 从文件中获取数据列表?

java - 如何使垂直滚动条不可见?

java - JSpinner 不允许用户输入内容

Java JSpinner 用向下箭头增加值

java - 自定义 JSpinner 模型不起作用

java - 通过 JDBC 使用数据库时如何处理夏令时?

java - 如何更改 JTable 中按钮的字体

java - 如何从 SelectOneMenu 中的选定项目更新 JSF SelectManyListBox 项目?

激活 MouseListener 的 obj 的 Java getName

java - Java 中的 EDT,它是如何工作的,它的行为是否像普通线程(单线程或多线程)?