How to check manual edits on a JSpinner field using DefaultEditor approach

后端 未结 4 2094
孤城傲影
孤城傲影 2021-01-24 06:07

I am adapting code from here:

Value Change Listener to JTextField

EDIT 2

The following code gives me an infinite loop of dialogs when I press the up spin

相关标签:
4条回答
  • 2021-01-24 06:22

    Custom DocumentListeners and formattedTextField don't play nicely with each other, better don't mix. Instead, use a PropertyChangeListener on the text field that listens for changes of its editValid property: whenever that changes to false, you could notify the users

    field.addPropertyChangeListener(new PropertyChangeListener() {
    
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            LOG.info("" + evt);
            if ("editValid".equals(evt.getPropertyName()) 
                &&  Boolean.FALSE.equals(evt.getNewValue())) {
              SpinnerNumberModel model = (SpinnerNumberModel) spin2.getModel();  
              JOptionPane.showMessageDialog(null,
              "Error: Number must be in range [" + model.getMinimum() + " ..." + model.getMaximum() + "]",
               "Error Massage",
              JOptionPane.ERROR_MESSAGE);
    
            }
    
        }
    });
    

    BTW, personally, I agree with Mad - such an intrusive notification tends to annoy me and maybe your users as well ..

    0 讨论(0)
  • 2021-01-24 06:25

    You have a few basic choices.

    1. You could trap the exception
    2. You could check for a "empty" String

    Personally, I'd like to do both...

    public void warn() {
        String text = ((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText();
        if (text != null && !text.trim().isEmpty()) {
            try {
                int stringValue = Integer.parseInt(text);
                JOptionPane.showMessageDialog(null,
                      "VALS: "+spin2.getValue(), "Error Massage",
                      JOptionPane.ERROR_MESSAGE);
                if (stringValue<10 || stringValue >100){
                JOptionPane.showMessageDialog(null,
                  "Error: Please enter number bigger than 0", "Error Massage",
                  JOptionPane.ERROR_MESSAGE);
                }
            } catch (NumberFormatException exp) {
                exp.printStackTrace();
            }
        }
    }
    

    Now, as a user, this is likely just to annoy me. Highlight the field, beep, change the tooltip, sure, throw a dialog in my face...hmmm...

    You could take a look at Validating Input, which will allow you to validate the input when the field loses focus, which, personally, might be a better choice.

    If you don't particularly need to functionality of the JSpinner (running values up and down in a sequence), you could take a look at using a DocumentFilter (for examples), which will allow you to control what goes into the field. You should know that it's not possible (or close enough to it) to add a DocumentFilter to a JSpinner... :P

    0 讨论(0)
  • 2021-01-24 06:30

    This proved to be a huge pain the rear. I wanted to color my text field background immediately. Ended up making an editor that overrode the editor I wanted to use, then setting it as the spinners editor accordingly. Seems to be working for me so far.

    Add a java class with the following (remove the quotes around the code block, I'm having a hard time with stack overflow's editor):

    `public class CustomNumberEditor extends JSpinner.NumberEditor {
        public CustomNumberEditor( JSpinner spinner ) {
            super( spinner );
            ((DefaultFormatter ) ((JFormattedTextField) getComponent( 0 )).getFormatter()).setCommitsOnValidEdit( true );
        }
        @Override public void propertyChange(PropertyChangeEvent e) {
            super.propertyChange( e );
            if( e.getPropertyName().equals( "value" ) )
                doStuff( (int) e.getNewValue() );
        }
        private void doStuff( int value )
        {
            //do stuff
        }
    }`
    

    Then when adding your spinner, do this:

    _quantitySpinner.setEditor(new CustomNumberEditor(_quantitySpinner));
    
    0 讨论(0)
  • 2021-01-24 06:32

    The Exception says that the String you pass to Integer.parseInt(..) is an empty string. So make sure to check ((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText() for null and empty before passing it to Integer.parseInt(..)

    You may have a look at apache commons-io and the StringUtils class, they have quite a few good methods to ease the pain on checking for empty/blank strings

    0 讨论(0)
提交回复
热议问题