Search code examples
javaswingcomparablejspinner

How to change max and min of a SpinnerNumberModel properly with the implemented Setters


I want to implement a JSpinner with a SpinnerNumberModel to a GUI. The values for value, min, max, step are read from a ini-file after the GUI gets built, therefore I need to change them with the Setters from the SpinnerNumberModel class. The values are read from the file as a String, then get parsed to double.

The JSpinner and SpinnerNumberModel are implemented in a class InputSpinner:

public class InputSpinner implements ChangeListener {

    JSpinner component;
    SpinnerNumberModel model;

    //empty constructor
    public InputSpinner() {
        model = new SpinnerNumberModel();   
        component = new JSpinner(model);

        JComponent field = ((JSpinner.DefaultEditor) component.getEditor());
        Dimension prefSize = field.getPreferredSize();
        prefSize = new Dimension(50, prefSize.height);
        field.setPreferredSize(prefSize);

        component.addChangeListener(this);
    }

    //constructor with name
    public InputSpinner(String name) {
        model = new SpinnerNumberModel();
        component = new JSpinner(model);
        component.setName(name);

        JComponent field = ((JSpinner.DefaultEditor) component.getEditor());
        Dimension prefSize = field.getPreferredSize();
        prefSize = new Dimension(50, prefSize.height);
        field.setPreferredSize(prefSize);
        component.addChangeListener(this);
    }

    //basic properties for all possible components
    public void setName(String componentName) {
        component.setName(componentName);
    }

    public void setToolTipText(String tooltip) {
        component.setToolTipText(tooltip);
    }

    public void setValue (Number value) {
        model.setValue(value);
    }

    public void setMaximum (Number max) {
        model.setMaximum((Comparable<Double>)max);
    }

    public void setMinimum (Number min) {
        model.setMinimum((Comparable<Double>)min);
    }

    public void setStepSize (Number step) {
        model.setStepSize(step);    
    }

    //getter for item
    public JComponent getComponent() {
        return this.component;
    }
}

As the Setters for StepSize and Value have Number as transfer parameters, I can set them after instancing both the SpinnerNumberModel and the JSpinner and it obviosly works that way.

The Setters for min and max otherwise demand the type Comparable. Simply parsing the double values to Comparable (raw type) or Comparable<Double> does not cause an exception, but also causes the JSpinner to not work properly anymore. (The initial value cannot be changed neither by editing nor by using the 2 Buttons that come with the editor).

When I add a JSpinner to my GUI and then change the values I do it like this:

public class main {

public static void main(String[] args) {

    JFrame frame = new JFrame("frame");
    InputSpinner spinner = new InputSpinner("spinner");

    frame.add(spinner.getComponent());

    spinner.setValue(some double value I got from ini-file);    //works properly
    spinner.setStepSize(some double value I got from ini-file); //works properly

    spinner.setMinimum(some double value I got from ini-file);  //causes problems
    spinner.setMaximum(some double value I got from ini-file);  //causes problems

    frame.pack();
    frame.setVisible(true);

    return;
}

}

How do I set the values properly, respectively how should I deal with the demand for Comparable ?


Solution

  • i don't know why exactly your set methods don't work with double, but i found a way to use double as current, min , max and stepsize.

    if you create you model, you pass the values in constructor like this:

    double current = 5.7;
    double min = (double) 5.5;
    double max = (double) 7.3;
    double step = 0.1;
    model = new SpinnerNumberModel(current, min, max, step);
    

    it doesn't matter which values you use, but they seem to be double if you want to use double further, because then this code works as well:

    JFrame frame = new JFrame("frame");
    InputSpinner spinner = new InputSpinner("spinner");
    
    frame.add(spinner.getComponent());
    
    spinner.setValue(5.1); 
    spinner.setMinimum(1.0); 
    spinner.setMaximum(25.3);  
    spinner.setStepSize(2.5);
    
    frame.pack();
    frame.setVisible(true);
    

    as i see it, you have to set step size as last value somewhy, but now its working just fine