我希望有一个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会这样做。
答案 0 :(得分:2)
我认为以下解决方案优于实现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());
}
}
}
答案 1 :(得分:-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);
}