Bug in JSpinner / SpinnerNumberModel

if use following constructor and pass BigDecimal instances for the four arguements then it accepts but on increasing value it throws ClassCastExecpetion.
public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize)I tried to look the reason of bug and probably found. Following method is invoked when spinner value is incremented
by mouse click. In this code there is no provision for BigDecimal class.
private Number incrValue(int dir)
     Number newValue;
     if ((value instanceof Float) || (value instanceof Double)) {
         double v = value.doubleValue() + (stepSize.doubleValue() * (double)dir);
         if (value instanceof Double) {
          newValue = new Double(v);
         else {
          newValue = new Float(v);
     else {
         long v = value.longValue() + (stepSize.longValue() * (long)dir);
         if (value instanceof Long) {
          newValue = new Long(v);
         else if (value instanceof Integer) {
          newValue = new Integer((int)v);
         else if (value instanceof Short) {
          newValue = new Short((short)v);
         else {
          newValue = new Byte((byte)v);
     if ((maximum != null) && (maximum.compareTo(newValue) < 0)) {
         return null;
     if ((minimum != null) && (minimum.compareTo(newValue) > 0)) {
         return null;
     else {
         return newValue;
    }regards,

The documentation says:
Internally, there's only support for values whose type is one of the primitive Number types: Double, Float, Long, Integer, Short, or Byte. So I guess you could file a request for enhancement.

Similar Messages

  • Using text in JSpinner SpinnerNumberModel.

    I was wondering if there is a way that I can use text in JSpinner SpinnerNumberModel.
    I have created a spinner as following:
    JSpinner spinner = new JSpinner(new SpinnerNumberModel(0,0,127,1));
    What I would like to do is put Text within the NumberModel so that when the spinner hits 127, it will display text such as "OFF"
    Is there a way I can implement this with a Spinner?
    Any help would be appreciated.
    Thanks.

    or you can paint a string, like this
    public void paint(Graphics g) {
         super.paint(g);
         g.drawString("Hello World!", x,y);  // replace x, y with your own coordinates
    }hope that helps

  • JSpinner/SpinnerNumberModel out of range verification & custom action

    I'm having a problem figuring out how the spinner's minimum & maximum values are checked against a user edit (by typing or arrow buttons). I need to have my spinners turn color when the user enters a value that is out of the spinner model's set range. I'm created custom editors, models, & added listeners onto the formatted textfield and none of these are called when the user enters a value out of range (they are called when the user enters a valid value).
    Does anyone have experience with this issue? Thanks.

    Posted my solution here:
    [http://forums.sun.com/thread.jspa?threadID=5432312|http://forums.sun.com/thread.jspa?threadID=5432312]

  • JSPinner and floating point quirk

    Please test these spinners only with their down arrow buttons to reach minimum value of each. When the number of fraction columns are 5,10 and 12, spinner stops at one step before the real minimum. They don't go to the real minimum. Why could this happen?
    import javax.swing.*;
    import java.text.*;
    public class SpinnerQuirk{
      public static void main(String[] args){
        Box panel = new Box(BoxLayout.X_AXIS);
        double fraction = 0.01;
        double base = 1.0;
        String fmt = "#0.00";
        for (int i = 2; i < 14; ++i){
          DecimalFormat df = new DecimalFormat(fmt);
          Box box = new Box(BoxLayout.Y_AXIS);
          JSpinner spinner = new JSpinner();
          SpinnerNumberModel spinnerModel
            = new SpinnerNumberModel(base + fraction,
                                     base + fraction - fraction * 101,
                                     base + fraction + fraction * 99,
                                     fraction);
          spinner.setModel(spinnerModel);
          spinner.setEditor(new JSpinner.NumberEditor(spinner, fmt));
          JLabel label = new JLabel("min = "
              + df.format((base + fraction - fraction * 101)));
          box.add(spinner);
          box.add(label);
          panel.add(box);
          fraction = fraction / 10.0;
          fmt += "0";
        JOptionPane.showMessageDialog(null, panel);
        System.exit(0);
    }

    Thanks. I think I have found the root cause of the problem. That is, there's no effective communications between java.text formatting and javax.swing.text one(*). A bad example of a bureaucratic sectionalism at Sun?
    (*: Because DecimalFormat does the right job given the same format string and same value.)
    Japanese: tate wari
    Englisn: divided vertically
    Edited by: hiwa on Oct 5, 2007 11:18 AM

  • JSpinner and BigDecimal , what am i doing wrong?

    hi,
    i'm trying to use a JSpinner to let the user input currencies.
    all my currencies are represented by BigDecimals.
    SpinnerNumberModel provides the following methodn which let's me think i can use BigDecimals in the spinner component:
    setStepSize(Number stepSize)
    The following code fails though :
    JSpinner spinner = new JSpinner();
    SpinnerNumberModel model = new SpinnerNumberModel();
    model.setStepSize(new BigDecimal("0.01");
    model.setValue(new BigDecimal("0.00");
    spinner.setModel(model);the spinner arrows don't work , and any value i enter is rejected
    what could be the problem ?

    From the SpinnerNumberModel API documentation:
    Internally, there's only support for values whose type is one of the primitive Number types: Double, Float, Long, Integer, Short, or Byte.

  • Help needed for jspinner

    Its the third time i am posting the same qusetion with out any sucess. Some one may knew the answer . Please help me
    I got a jspinner , a text box and a button in my frame. i valdiate the values entered in the text field and if an invalid value is entered an error dialog is show . Now if I enter an invalid value in the text field and click the buttons along with the jspinner, the error dialog is displayed and focus is returned back to the textbox,but the problem is that the spinner button remains in a pressed condition as a result the number keeps of increasing / decreasing in jspinner (if you click both the buttons , it will increase and decrease at the same time). I am including the code also.
    I have searched through the forums and couldnt find a solution. Is it a problem with jspinner or my code?
    thanks in advance
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class focus extends JFrame implements FocusListener {
    JPanel pan1=new JPanel();
    JButton btn1=new JButton("OK");
    JButton btn2=new JButton("Cancel");
    JTextField txt1=new JTextField(10);
    SpinnerCircularNumberModel model=new SpinnerCircularNumberModel(50);
    JSpinner spin=new JSpinner(model);
    focus() {
    getContentPane().setLayout(new FlowLayout());
    getContentPane().add(txt1);
    getContentPane().add(btn1);
    getContentPane().add(btn2);
    getContentPane().add(spin);
    txt1.addFocusListener(this);
    setSize(200,200);
    setVisible(true);
    pack();
    public void focusGained(FocusEvent fe) {
    public void focusLost(FocusEvent fe) {
    try {
    Integer.parseInt(txt1.getText());
    } catch ( NumberFormatException nfe) {
    JOptionPane.showMessageDialog(this, "Invalid value","ERROR", JOptionPane.ERROR_MESSAGE);
    txt1.requestFocus();
    public static void main(String arg[]) {
    focus f=new focus();
    class SpinnerCircularNumberModel extends SpinnerNumberModel {
    public SpinnerCircularNumberModel(int init) {
    super(init,0,99,1);
    public Object getNextValue() {
    int val = Integer.parseInt(getValue().toString());
    if(val==99)
    return (new Integer(0));
    else
    return (new Integer(++val));
    public Object getPreviousValue() {
    int val = Integer.parseInt(getValue().toString());
    if(val==0)
    return (new Integer(99));
    else
    return (new Integer(--val));

    i found out the answer . It was a bug with the jspinner.
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4840869

  • SetEnabled to false for a JSpinner

    hi all,
    I've got a little problem that I hope someone can solve for me.
    I'm trying to setEnabled() to false for my JSpinners, at run time, even though it is set to false, the JSpinner is still enabled and allows editing.
    Is this because JSpinners doesn't allow it to be disabled, or I have done something fatally wrong?
    Here is a snipet of my code.
    SpinnerNumberModel spinDays = new SpinnerNumberModel(days,0,30,1);
    spinnerDays = new JSpinner(spinDays);
    spinnerDays.addChangeListener(new ChangeListener(){
         public void stateChanged(ChangeEvent e){
         setSpinnerDays();     
    spinnerDays.setEnabled(false);
    Gabriel.

    This bug has been fixed in JDK1.4 beta 2. Download the latest version.
    Cheers,
    Joris
    http://www.esus.com

  • JSpinner generates multiple change events

    Having problem with JSpinner generating two change events when using double values in the model. It looks like the number editor formatter is causing an event to be generated before it rounds and after it rounds.
              final JSpinner s = new JSpinner(
                   new SpinnerNumberModel(20.0, 0.0, 100.0, 0.0025));
              s.setEditor(new JSpinner.NumberEditor(s, "###0.000"));
              // When value is changed, need to process certain events.
              s.addChangeListener(new ChangeListener() {
                   public void stateChanged(ChangeEvent event) {
                        System.out.println("New Value:" + s.getValue());
              JFrame f = new JFrame("Test Spinner");
              f.getContentPane().setLayout(new java.awt.BorderLayout());
              f.getContentPane().add(s, java.awt.BorderLayout.CENTER);
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              f.setSize(331, 254);
              f.setVisible(true);If you modify the editor to use the following format, you can see that the two events are not generated because the formatter does not need to round:
    "###0.000##############"I have to actually modify the model to round the incremented or decremented value to a precision where the formatter will not round the value, which is a pretty messy solution.
    Are there any other workarounds (or solutions) that are a little more elegant?
    Thanks.

    Thanks for the reply.
    This workaround reduces the amount of duplicate events, but I still see double change events that make it through the filter.
    You have to filter events to get the relevant one.
    See :
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=476
    5246
    import java.awt.*;
    import java.text.*;
    import javax.swing.*;
    import javax.swing.event.*;
    public class SpinnerEvents{
    JSpinner s;
    JSpinner.NumberEditor jne;
    DecimalFormat dfmt;
    public SpinnerEvents() {
    s = new JSpinner(new SpinnerNumberModel(20.0,
    0.0, 0.0, 100.0, 0.0025));
    jne = new JSpinner.NumberEditor(s, "###0.000");
    dfmt = jne.getFormat();
    s.setEditor(jne);
    // When value is changed, need to process only
    only *relevant event*.
    s.addChangeListener(new ChangeListener() {
    public void stateChanged(ChangeEvent event) {
    double val =
    le val = ((Double)s.getValue()).doubleValue();
    // ignore format event
    if
    if
    if
    if
    (!(String.valueOf(val).equals(dfmt.format(val)))){
    myImportantTask();
    JFrame f = new JFrame("Test Spinner");
    f.getContentPane().setLayout(new
    (new java.awt.BorderLayout());
    f.getContentPane().add(s,
    d(s, java.awt.BorderLayout.NORTH);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(300, 300);
    f.setVisible(true);
    void myImportantTask(){
    System.out.println("New Value:" +
    :" + dfmt.format(s.getValue()));
    public static void main(String[] args){
    new SpinnerEvents();

  • JSpinner would not spin after step size change

    Hi,
    I am trying to figure out why my spinner does not work after I change the spinner properties.
    The first spinner works fine, but the second spinner will not spin. I think it has to do with the step size, 0.1.
    Does anyone know how to remedy this problem?
    I have attached a part of my code. This code is later added to a BorderLayout South.
    Thanks.
    static Component createNorth() {       
              JPanel N = new JPanel(new GridLayout(0,2,30,20));
              N.setBorder(BorderFactory.createTitledBorder("Foward Level"));
              final JSpinner FwdLevelSpin = new JSpinner(new SpinnerNumberModel(127,0,127,1));
              final JSpinner FwdTrimSpin = new JSpinner(new SpinnerNumberModel(0,-0.9,0.9,0.1));
    ChangeListener l = new ChangeListener(){           
              public void stateChanged(ChangeEvent evt) {
    JSpinner newspin = (JSpinner)evt.getSource();
    Object value = newspin.getValue();
    String newValue = value.toString();
    int IntValue = Integer.parseInt(newValue);
    String Hex = Integer.toHexString(IntValue);
    Hex = Hex.toUpperCase();
    String Checksum ="00";
              if (evt.getSource()==FwdLevelSpin){                   
              System.out.println("FwdLevelSpin"+" "+ Hex);
    SerialWrite Serial = new SerialWrite();
    Serial.WriteToSerial("[024100" + Hex + Checksum + "]");
              else if(evt.getSource()==FwdTrimSpin){                  
              System.out.println("FwdTrimSpin"+" "+Hex);
    SerialWrite Serial = new SerialWrite();
    Serial.WriteToSerial("[022301" + Hex + Checksum + "]");
    FwdLevelSpin.addChangeListener(l);
              FwdTrimSpin.addChangeListener(l);
    JLabel FwdLevelLabel = new JLabel(" Foward Level ");
    JLabel FwdTrimLabel = new JLabel(" Trim(Unfinished) ");
    N.add(FwdLevelLabel);
              N.add(FwdLevelSpin);
    N.add(FwdTrimLabel);
    N.add(FwdTrimSpin);
    return N; }

    Hi there
    I'm not 100% sure on my understanding of this with Captivate 5. I know the developers rebuilt it from the ground up with shiny new code, and I'm also aware that the text in the captions is rendered in a different way. But what I'm unsure of, is whether the Captions are still cached in the project.
    Assuming Captivate 5 continues with the way the older versions worked, once a Caption was actually used in a project, all five types were cached in the .CP file. This means if you have a caption set named BlueBanner that has a bright blue banner at the top and you have used any of the different types or styles of that caption, that you cannot swap out the images so that perhaps you now see a bright red banner at the top. I mean sure, you can swap the images out all day long. But until you create a new project and use the caption for the first time in a new project, the captions are stuck at blue.
    From what you have described, Captivate 5 seems to be continuing this behavior. Assuming it is, I would urge you to file a Bug Report to make the dev team aware that a change may be needed to the way these work. (link for that is in my sig)
    Cheers... Rick
    Helpful and Handy Links
    Begin learning Captivate 5 moments from now! $29.95
    Captivate Wish Form/Bug Reporting Form
    Adobe Certified Captivate Training
    SorcererStone Blog
    Captivate eBooks

  • JSpinner - preventing edition

    I need to disable a JSpinner's editor without disabling the JSpinner entirely, forcing the user to use the arrows exclusively to change it's value.
    a sample of my code:
    SpinnerNumberModel spmdl = new SpinnerNumberModel(10, 5, 35, 1);
    myspin = new JSpinner(spmdl);
    myspin.getEditor().setEnabled(false); /* <--- this line does nothing! */
    I am aware of the fact that disabling a JSpinner was impossible in versions of the JDK prior to 1.4 beta 2. (my version is j2sdk1.4.1_01).
    Are there remnants of this bug in recent versions?
    Am I doing something completely wrong?
    Will I be forced to use a focus listener to prevent the user to edit the JSpinner's editor?
    thanks in advance,
    Louis

    oh! I guess I read the doc too fast... it works perfectly.
    thank you very much!
    Louis
    Not too sure what you really wanted to do, but every
    spinner has an associated editor which in turn has an
    associated textfield. You can try to disable the
    textfield... for example:
    JSpinner.DefaultEditor
    editor=(JSpinner.DefaultEditor)myspin.getEditor();
    JFormattedTextField
    TF=(JFormattedTextField)editor.getTextField();Having obtained the TF, you can do what you want with
    it!
    ;o)
    V.V.

  • JSpinner - customising colour or font of Editor

    Hi,
    I am using a JSpinner (JDK1.4beta3) and I want to change the colours and/or font
    used in the editor part of it.
    However it didn't work.
    The JSpinner is part of a JPanel
      Color foregroundColour;
      Font graphFont;
      SpinnerModel sm = new SpinnerNumberModel();
      JSpinner js = new JSpinner(sm);That's what I tried so far:
        js.getEditor().setForeground(foregroundColour);
        js.setForeground(foregroundColour);
        setForeground(foregroundColour);and for the font problem:
        js.setFont(getThis().graphFont);
        js.getEditor().setFont(getThis().graphFont);
        js.getEditor().invalidate();
        js.validate();I also checked, that the changes were applied, but font and colour did not change.
        System.out.println("EditorModel: "+js.getModel().toString());
        System.out.println("Editor:      "+js.getEditor().toString());
        System.out.println("Editor Font: "+js.getEditor().getFont().toString());
        System.out.println("Editor Fore: "+js.getEditor().getForeground().toString());
        System.out.println("Editor Back: "+js.getEditor().getBackground().toString());I fear I'm either missing something obvious, or I've stumbled into a bug.
    Thanks for your help

    editor.getTextField().setBackground(Color.blue);
    editor.getTextField().setFont(font);
    editor.getTextField().setHorizontalAlignment(JTextField.CENTER);

  • Jspinner keeps counting

    I am having a problem with Jspinner. I have implemented a circular spinner SpinnerCircularNumberModel by extending SpinnerNumberModel . I also have 2 text boxes . i have to validate these textboxes .I put the validation codes in the focus lost event of these text boxes .If an invalid value is entered, then an error message is displayed and focus is returned to that textbox..Its working fine but the problem occurs when after entering an invalid value and changing the focus to the spinner (click the spinner buttons) ,error message is displayed and control returns back to the textbox but the spinner button remains in the pressed state as a result the number keeps on auto incrementing .
    how can i solve this problem .please help me.

    I have encountered the same problem. Did you solve it meanwhile?
    Here is a little program that shows the behaviour.
    Perhaps it is a bug? Did anyone submit it as a bug in the
    BugParade?
    --------------- Code ---------------------------------------------
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    public class SpinnerFrame extends JFrame implements ChangeListener {
    private JSpinner spinner;
    private boolean changing;
    private SpinnerFrame() {
    super();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    getContentPane().add(getSpinner());
    setSize(80,60);
    setLocation(200, 300);
    setVisible(true);
    changing = false;
    private JSpinner getSpinner() {
    if (spinner == null) {
    spinner = new JSpinner();
    spinner.setModel(new SpinnerNumberModel(10, 1, 50, 1));
    spinner.addChangeListener(this);
    return spinner;
    public void stateChanged(ChangeEvent e) {
    JSpinner spinner = (JSpinner) e.getSource();
    int value = ((Integer) spinner.getValue()).intValue();
    System.out.println("Changed to " + value);
    if (changing) {
    return;
    changing = true;
    if (value > 20) {
    JOptionPane.showMessageDialog(this, "20 exceeded");
    changing = false;
    public static void main(String[] args) {
    new SpinnerFrame();

  • JSpinner and FocusListener

    The method addFocusListener of JSpinner doesn't work. Is it a bug?

    No it's not a bug. You might need to try harder to extract from the spinner something that can accept focus:
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.JTextField;
    import javax.swing.SpinnerNumberModel;
    public class JSpinFocusListener
      private JPanel mainPanel = new JPanel();
      private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, -10, 10, 1));
      private JTextField textField = new JTextField(10);
      public JSpinFocusListener()
        mainPanel.add(spinner);
        mainPanel.add(textField);
        // this doesn't work
        spinner.addFocusListener(new MyFocusListener("spinner"));
        // and this doesn't work
        spinner.getEditor().addFocusListener(new MyFocusListener("spinner's editor"));
        // but this one, works
        ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField()
            .addFocusListener(new MyFocusListener("spinner's editor's textfield"));
      public JPanel getMainPanel()
        return mainPanel;
      private class MyFocusListener implements FocusListener
        private String name;
        public MyFocusListener(String name)
          this.name = name;
        public void focusGained(FocusEvent e)
          System.out.println("Focus gained on " + name);
        public void focusLost(FocusEvent e)
          System.out.println("Focus lost from " + name);
      private static void createAndShowUI()
        JFrame frame = new JFrame("JSpinFocusListener");
        frame.getContentPane().add(new JSpinFocusListener().getMainPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      public static void main(String[] args)
        java.awt.EventQueue.invokeLater(new Runnable()
          public void run()
            createAndShowUI();
    }

  • Memory leak in JSpinner implementation (maybe others?)

    Hi,
    I am developing an application using Java and Swing, and have run into some problems with memory leaks. After examining the source code and making an example program (provided below), I can only come to the conclusion that there is a bug in the implementation of JSpinner in Sun Java 1.6.0_03.
    If one uses a custom model with the JSpinner, it attaches itself as a listener to the model. However, it never removes the listening connection, even if the model is changed. This causes the JSpinner to be kept in memory as long as the model exists, even if all other references to the component have been removed.
    An example program is available at http://eddie.dy.fi/~sampo/ModelTest.java . It is a simple swing program that has the JSpinner and two buttons, the first of which writes to stdout the listeners of the original model and the second changes the spinner model to a newly-created model. A sample output is below:
    Running on 1.6.0_03 from Sun Microsystems Inc.
    Listeners before connecting to JSpinner:
      Model value is 0, 0 listeners connected:
    Listeners after connecting to JSpinner:
      Model value is 0, 2 listeners connected:
      1: interface javax.swing.event.ChangeListener
      2: javax.swing.JSpinner$ModelListener@9971ad
    Listeners now:
      Model value is 8, 2 listeners connected:
      1: interface javax.swing.event.ChangeListener
      2: javax.swing.JSpinner$ModelListener@9971ad
    Changing spinner model.
    Listeners now:
      Model value is 8, 2 listeners connected:
      1: interface javax.swing.event.ChangeListener
      2: javax.swing.JSpinner$ModelListener@9971adThis shows that even though the model of the JSpinner has been changed, it still listens to the original model. I haven't looked at other components whether they retain connections to the old models as well.
    In my case, I have an adaptor-model which provides a SpinnerModel interface to the actual data. The adaptor is implemented so that it listens to the underlying model only when it itself is being listened to. If the JComponents using the model were to remove the listening connections, it, too, would be automatically garbage-collected. However, since JSpinner does not remove the connections, the adaptor also continues to listen to the underlying model, and neither can be garbage-collected.
    All in all, the listener-connections seem to be a very easy place to make memory leaks in Java and especially in Swing. However, as I see it, it would be a simple matter to make everything work automatically with one simple rule: Listen to the models only when necessary.
    If a component is hidden (or alternatively has no contact to a parent JFrame or equivalent), it does not need to listen to the model and should remove the connections. When the component is again set visible (or connected to a frame) it can re-add the connections and re-read the current model values just as it does when initializing the component. Similarly, any adaptor-models should listen to the underlying model only when it itself is being listened to.
    If the components were implemented in this way, one could simply remove a component from the frame and throw it away, and automatically any listener-connections will be removed and it can be garbage-collected. Similarly any adaptor-models are collected when they are no longer in use.
    Changing the API implementation in this way would not require any changes to applications, as the only thing that changes are the listener-connections. Currently used separate connection-removing methods should still work, though they would be unnecessary any more. The API would look exactly the same from the view of an application programmer, only that she would not need to care about remnant listening connections. (As far as I can tell, the current API specification would allow the API to be implemented as described above, but it should of course require it to be implemented in such a way.)
    Am I missing something, or is there some valid reason why the API is not implemented like this?
    PS. I'm new to these forums, so if there is a better place to post these reports, please tell me. Thanks.

    Another cognition: It's the following code, that causes the memory to be accumulated:
    obj = m_orb.resolve_initial_references("NameService");
    ctx = NamingContextExtHelper.narrow(obj);For the first 4 calls to this code the memory usage of the nameservice is unchanged. From the 5th to the 8th call, it's increased by approx. 10KB per call. And thenceforward (beginning with the 9th call) it's increasing by approx. 10MB.
    What's going wrong here?

  • How to set numeric filter for JSpinner?

    Hi there,
    I searched the forum but can't find a solution...I'm kind of getting mad!
    Problem is: I have a JSpinner, I must prevent the user to insert any non-numeric value. the accepted input should be in the form <n>.<m>
    where n could be any integer number, m is OPTIONAL and could be a single digit number. Example: 150.2 or 41 or 7.1 etc.
    I set a DocumentFilter on the editor of JSpinner, overriding replace method. Problem is replace method is never called so my filter is not applied and the user is allowed to insert whatever he wants, characters included.
    Here's my code (sorry for the horrible gui, but it's just for some testing.):
    import java.awt.Dimension;
    import java.util.regex.Pattern;
    import javax.swing.JFrame;
    import javax.swing.JSpinner;
    import javax.swing.JTextField;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.JSpinner.NumberEditor;
    import javax.swing.text.AbstractDocument;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DocumentFilter;
    public class SpinnerTry {
         public final static String REGEX_DOUBLE_NUMBER = "^([0-9]+)(\\.(\\d{1})?)?$";
         private static final Double MIN_PW = 12.0;
         private static final Double MAX_PW = 19.0;
         private static final Double DEFAULT = 15.0;
         private static final Double STEP = 1.00;
         private static final SpinnerNumberModel model = new SpinnerNumberModel(
                   DEFAULT, // initial value
                   MIN_PW, // min
                   MAX_PW, // max
                   STEP);
         public static void main(String[] args) {
              JFrame frame = new JFrame();
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              JSpinner spinner = new JSpinner(model);
              spinner.setPreferredSize(new Dimension(50, 15));
              NumberEditor edit = new NumberEditor(spinner, "#######.#");
              spinner.setEditor(edit);
              JTextField textField = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
              ((AbstractDocument) textField.getDocument()).setDocumentFilter(new MyDocumentFilter());
              frame.getContentPane().add(spinner);
              frame.setSize(new Dimension(200, 200));
              frame.setVisible(true);
         static class MyDocumentFilter extends DocumentFilter {
              public void replace(FilterBypass fb, int offset, int length, String text,
                        AttributeSet attrs) throws BadLocationException {
                   System.out.println("Called replace");
                   String mytext = fb.getDocument().getText(0, offset);
                   mytext += text;
                   if (fb.getDocument().getLength() - 1 > offset) {
                        mytext += fb.getDocument().getText(offset + 1,
                                  fb.getDocument().getLength() - offset);
                   boolean ok = true;
                   ok = Pattern.matches(REGEX_DOUBLE_NUMBER, mytext);
                   if (ok)
                        super.replace(fb, offset, length, text, attrs);
              public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
                        throws BadLocationException {
                   if (Pattern.matches(REGEX_DOUBLE_NUMBER, string)) {
                        super.insertString(fb, offset, string, attr);
    }Why replace method is not called when inserting somethig into the spinner text field?
    Thanks a lot in advance.
    Paul
    Edited by: the.paul on Jul 27, 2010 1:11 AM

    I found a solution, got inspiration from [http://forums.sun.com/thread.jspa?forumID=57&threadID=5424330] .
    Code:
    import java.awt.Dimension;
    import java.text.DecimalFormat;
    import java.text.NumberFormat;
    import java.util.regex.Pattern;
    import javax.swing.JFrame;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.JSpinner.NumberEditor;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DefaultFormatterFactory;
    import javax.swing.text.DocumentFilter;
    import javax.swing.text.NumberFormatter;
    public class SpinnerTry {
         public final static String REGEX_DOUBLE_NUMBER = "^([0-9]+)(\\.(\\d{1})?)?$";
         private static final Double MIN_PW = 12.0;
         private static final Double MAX_PW = 19.0;
         private static final Double DEFAULT = 15.0;
         private static final Double STEP = 1.00;
         private static final SpinnerNumberModel model = new SpinnerNumberModel(
                   DEFAULT, // initial value
                   MIN_PW, // min
                   MAX_PW, // max
                   STEP);
         public static void main(String[] args) {
              JFrame frame = new JFrame();
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              JSpinner spinner = new JSpinner(model);
              spinner.setPreferredSize(new Dimension(50, 15));
              String decimalFormatPattern = "#######.#";
              NumberEditor edit = new NumberEditor(spinner);
              spinner.setEditor(edit);
              ((NumberEditor) spinner.getEditor()).getTextField().setFormatterFactory(
                    new DefaultFormatterFactory(new MyListFormatter(model, new DecimalFormat(decimalFormatPattern))));
              frame.getContentPane().add(spinner);
              frame.setSize(new Dimension(200, 200));
              frame.setVisible(true);
         static class MyListFormatter extends NumberFormatter {
              private static final long serialVersionUID = -790552903800038787L;
              private final SpinnerNumberModel model;
              private DocumentFilter filter;
              MyListFormatter(SpinnerNumberModel model, NumberFormat format) {
                   super(format);
                   this.model = model;
                   setValueClass(model.getValue().getClass());
              public void setMinimum(Comparable min) {
                   model.setMinimum(min);
              public Comparable getMinimum() {
                   return model.getMinimum();
              public void setMaximum(Comparable max) {
                   model.setMaximum(max);
              public Comparable getMaximum() {
                   return model.getMaximum();
              protected DocumentFilter getDocumentFilter() {
                   if (filter == null) {
                        filter = new MyDocumentFilter();
                   return filter;
         static class MyDocumentFilter extends DocumentFilter {
              public void replace(FilterBypass fb, int offset, int length, String text,
                        AttributeSet attrs) throws BadLocationException {
                   System.out.println("Called replace");
                   String mytext = fb.getDocument().getText(0, offset);
                   mytext += text;
                   if (fb.getDocument().getLength() - 1 > offset) {
                        mytext += fb.getDocument().getText(offset + 1,
                                  fb.getDocument().getLength() - offset);
                   boolean ok = true;
                   ok = Pattern.matches(REGEX_DOUBLE_NUMBER, mytext);
                   if (ok)
                        super.replace(fb, offset, length, text, attrs);
              public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
                        throws BadLocationException {
                   if (Pattern.matches(REGEX_DOUBLE_NUMBER, string)) {
                        super.insertString(fb, offset, string, attr);
    }That is: define a custom formatter ; the formatter uses the custom DocumentFilter.
    Hope it is useful for some people out there.
    Regards

Maybe you are looking for