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

次の解決策は、フォーマットの問題ではなく、モデルの責任である可能性のある値を制限する問題であるため、フォーマッターを実装するという提案よりも優れていると思います。私は同様の問題を抱えていて、このスレッドソリューションにつまずいたため、非常に醜い実装につながりました。うまくいけば、私が思いついたことがあなたをトラブルから遠ざけてくれることを願っています.

これで問題なくモデルが生成され、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());
        }
    }
}
于 2014-08-02T10:24:57.493 に答える