-3

I am trying allready to make custome model for JSpinner but it doesnt work. the code looks like:

public class ModelJSpinner implements SpinnerModel
 {
private long value;

private long min;

private long max;

private long increment;

private ChangeListener l;

private ArrayList<ChangeListener> listeners;

@Override
public Object getValue()
{

    return null;
}

public ModelJSpinner(long min, long max, long increment)
{
    super();
    this.min = min;
    this.max = max;
    this.increment = increment;
    setValue(min);
    listeners = new ArrayList<>();
}

@Override
public void setValue(Object value)
{
    if (value == null)
    {

    }else {
        this.value = (Long) value;    
    }


    //fireStateChanged();

}

private void fireStateChanged()
{
    if (listeners == null)
        return;
    for (int a = 0; a < listeners.size(); a++)
    {
        ChangeListener l = (ChangeListener) listeners.get(a);
        try
        {
            l.stateChanged(new ChangeEvent(this));
        }
        catch (RuntimeException e)
        {
            e.printStackTrace();
        }
    }

}

@Override
public Object getNextValue()
{
    Long nextValue = value + increment;
    if (nextValue > max)
    {

        return null;
    }
    else
    {

        return nextValue;
    }
}

@Override
public Object getPreviousValue()
{
    Long previousValue = value - increment;
    if (previousValue < min)
    {

        return null;
    }
    else
    {

        return previousValue;
    }
}

@Override
public void addChangeListener(javax.swing.event.ChangeListener l)
{
    this.l = l;
    listeners.add(l);

}

@Override
public void removeChangeListener(javax.swing.event.ChangeListener l)
{
    if (this.l == l)
    {
        l = null;
    }
    listeners.add(l);

}

}

However when i run the following code i get...nothing much except JSpinner that doesnt do much...

public class Test
{
public static void main(String[] args)
{
    ModelJSpinner model = new ModelJSpinner(10L, 20L, 5L);
    JSpinner spinner = new JSpinner(model);
    spinner.setModel(model);
    spinner.setValue(15L);
    JFrame frame = new JFrame("adasasd");
    frame.setSize(350, 150);
    frame.add(spinner);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setVisible(true);

}

 }

At the beginning, all i wanted was just to see that JSpinner can do something with above mentioned Model and later i wanted to implement Changelisteners.

As of now, i am not even able to have it drawn properly. Is there a chance that somebody could help me?

I need to use instance of Class implementing SpinnerModel as model for JSpinner and i just cannot make it work.

BR DK

DerKerl
  • 11
  • 4

1 Answers1

2

This is a guarantee to fail:

@Override
public Object getValue()
{
    return null;
}

since this is the method that the JSpinner uses to determine what value to display.

Instead have this return the value held by your value field. Also, don't return null for the getNextValue() if next value is above max. Instead return the max. Similarly for the getPreviousValue(), return the min value if the calculated previous value is less than min.

For example,

public class SpinnerModel3 implements SpinnerModel {
    private long value;
    private long min;
    private long max;
    private long increment;
    // using a set to avoid allowing addition of duplicate listeners
    private Set<ChangeListener> listenerSet = new HashSet<>();

    public SpinnerModel3(long value, long min, long max, long increment) {
        super();
        this.value = value;
        this.min = min;
        this.max = max;
        this.increment = increment;
    }

    @Override
    public void addChangeListener(ChangeListener l) {
        listenerSet.add(l);
    }

    @Override
    public Object getNextValue() {
        long nextValue = value + increment;
        nextValue = Math.min(nextValue, max);
        return nextValue;
    }

    @Override
    public Object getPreviousValue() {
        long prevValue = value - increment;
        prevValue = Math.max(prevValue, min);
        return prevValue;
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public void removeChangeListener(ChangeListener l) {
        listenerSet.remove(l);
    }

    @Override
    public void setValue(Object value) {
        this.value = (long) value;
        fireStateChanged();
    }   

    protected void fireStateChanged() {
        // create a ChangeEvent object
        ChangeEvent e = new ChangeEvent(this);
        for (ChangeListener l : listenerSet) {
            l.stateChanged(e);  // notify all listeners
        }
    }
}

Note that it is usually better to use the extend the abstract model class if one is available (or even better, the default model class, but none is available for spinner model). So better still:

@SuppressWarnings("serial")
public class SpinnerModel2 extends AbstractSpinnerModel {
    private long value;
    private long min;
    private long max;
    private long increment;

    public SpinnerModel2(long value, long min, long max, long increment) {
        super();
        this.value = value;
        this.min = min;
        this.max = max;
        this.increment = increment;
    }

    @Override
    public Object getNextValue() {
        long nextValue = value + increment;
        nextValue = Math.min(nextValue, max);
        return nextValue;
    }

    @Override
    public Object getPreviousValue() {
        long prevValue = value - increment;
        prevValue = Math.max(prevValue, min);
        return prevValue;
    }

    @Override
    public Object getValue() {
        return value;
    }

    @Override
    public void setValue(Object value) {
        this.value = (long) value;
        fireStateChanged();
    }

}