次の解決策は、フォーマットの問題ではなく、モデルの責任である可能性のある値を制限する問題であるため、フォーマッターを実装するという提案よりも優れていると思います。私は同様の問題を抱えていて、このスレッドソリューションにつまずいたため、非常に醜い実装につながりました。うまくいけば、私が思いついたことがあなたをトラブルから遠ざけてくれることを願っています.
これで問題なくモデルが生成され、JSpinner のボタンを使用して値を移動できます。ただし、値を入力しても機能しません。たとえば、スピナーが 3 に設定されていて、7 を入力すると、3 のままになります (おそらく、7 が有効な値であるとは考えられないためです)。これは SpinnerNumberModel で動作するため、何が起こっているのかわかりません。
ここでの問題は、 setModelを使用して新しいモデルを設定すると、モデルのタイプに応じて JTextFieldEditor 属性が変更されるという文書化されていない副作用があることです。
デフォルトでは、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());
}
}
}