1

を更新するコードが少しありますJSlider。別の時点で、JSliderの最大値を更新する必要があります。setMaximum()問題は、スライダーを呼び出すと、 ChangeEvent. それを避けるために、私はこれをやっています:

slider.removeChangeListener(this);
slider.setMaximum(newMax);
slider.addChangeListener(this);

これを行うためのよりクリーンでエレガントな方法はありますか?

4

4 に答える 4

3

きれいな方法は、実際に変更されたプロパティを運ぶことができるカスタム ChangeEvent を起動するカスタム BoundedRangeModel を実装することです (実際に必要なものに少し依存します)。

/**
 * Extended model that passes the list of actually changed properties
 * in an extended changeEvent.
 */
public static class MyBoundedRangeModel extends DefaultBoundedRangeModel {

    public MyBoundedRangeModel() {
    }

    public MyBoundedRangeModel(int value, int extent, int min, int max) {
        super(value, extent, min, max);
    }

    @Override
    public void setRangeProperties(int newValue, int newExtent, int newMin,
            int newMax, boolean adjusting) {
        int oldMax = getMaximum();
        int oldMin = getMinimum();
        int oldValue = getValue();
        int oldExtent = getExtent();
        boolean oldAdjusting = getValueIsAdjusting();
        // todo: enforce constraints of new values for all
        List<String> changedProperties = new ArrayList<>();
        if (oldMax != newMax) {
           changedProperties.add("maximum"); 
        }
        if (oldValue != newValue) {
            changedProperties.add("value");
        }
        // todo: check and add other properties 
        changeEvent = changedProperties.size() > 0 ? 
                new MyChangeEvent(this, changedProperties) : null;
        super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
    }


}

/**
 * Extended ChangeEvent that provides a list of actually 
 * changed properties. 
 */
public static class MyChangeEvent extends ChangeEvent {

    private List<String> changedProperties;

    /**
     * @param source
     */
    public MyChangeEvent(Object source, List<String> changedProperties) {
        super(source);
        this.changedProperties = changedProperties;
    }

    public List<String> getChangedProperties() {
        return changedProperties;
    }

}

その使用法は次のようになります。

final JSlider slider = new JSlider();
slider.setModel(new MyBoundedRangeModel(0, 0, -100, 100));
ChangeListener l = new ChangeListener() {

    @Override
    public void stateChanged(ChangeEvent e) {
        if (e instanceof MyChangeEvent) {
            MyChangeEvent me = (MyChangeEvent) e;
            if (me.getChangedProperties().contains("value")) {
               System.out.println("new value: " + 
                    ((BoundedRangeModel) e.getSource()).getValue()); 
            }
            if (me.getChangedProperties().contains("maximum")) {
                System.out.println("new max: " + 
                    ((BoundedRangeModel) e.getSource()).getMaximum()); 
            }
        } else {
            // do something else or nothing
        }
    }
};
slider.getModel().addChangeListener(l);

スライダーではなくモデルにリスナーを登録する必要があることに注意してください(スライダーがプレーンタイプの新しいchangeEventを作成するためです)

于 2013-04-24T15:23:56.333 に答える
0

本質的に、この質問と同じ問題のように見えます。 その場合、答えは「いいえ」です。

于 2013-04-24T14:07:16.683 に答える
0

誰がリスナーの変更をトリガーしたかを確認できます。まだかなり汚れていますが、変更リスナーを削除する必要はありません。

于 2013-04-24T14:06:32.213 に答える