views:

37

answers:

2

Hi, have tried a few different approaches to this but with no success so far. Just wondered if I'm missing anything. I have a JSpinner which is a component of a DateSelector widget alongside a Calendar. I am trying to fire a validation method if the user changes any text in the JSpinner instead of using the Calendar control or the JSpinner up and down arrows.

Here are the different approaches I have tried:

jSpinner1.addKeyListener(kl);

jSpinner1.getEditor().addKeyListener(kl);

((JSpinner.DefaultEditor) jSpinner1.getEditor().getTextField().addKeyListener(kl);

Anyone out there got any ideas as to what I'm doing wrong? Thanks

UPDATE Apologies, I should have said that I have already added a ChangeListener to the JSpinnerDateModel which is attached to the JSpinner. Like so:

ChangeListener changeListener = new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            dateChanged();
        }
    };

    jSpinnerDateModel.addChangeListener(changeListener);

    KeyListener keyListener = new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println(e.getKeyChar());
            dateChanged();
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

    };
    ((JSpinner.DefaultEditor) jSpinner1.getEditor()).getTextField().addKeyListener(
            keyListener);

Thanks

Frank

+1  A: 

If you want to disable keyboard editing do this:

JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
tf.setEditable(false);

To listen for key events you need to add a listener to the text field. This works for me:

((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyListener(){

            @Override
            public void keyPressed(KeyEvent e) {                    
            }

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("PRESSED!");                    
            }

            @Override
            public void keyTyped(KeyEvent e) {                    
            }

        });
dogbane
Yeah thanks for this. I have this as a last option if I have to but I would rather the user had full access to edit the date using the controls or manually via the keyboard.
Frank
Thanks but I already had this code in place - I have updated the question to show all the code in use. Sorry about that.
Frank
Your code works for me. When I type some text, it prints out the characters.
dogbane
+1  A: 

JSpinners handle KeyEvents themselves, but they fire ChangeEvents to the outside world. Adding a ChangeListener should allow you to perform the validation you wish.

See also: Detecting Spinner Value Changes (Java Tutorials)

Michael Myers
Apologies for not including this info in the original question (I have update it now) but I already have a ChangeListener attached to the Model of the JSpinner. This catches any changes made to the value in the JSpinner but only if the user uses the JSpinner controls. I am trying to fire the key pressed event of a KeyListener for when the user manually edits the value of the JSpinner via the keyboard. Thanks
Frank
@Frank: A ChangeListener should fire whenever the user changes the value *and focuses away* (or presses Enter). You're right that it won't fire while the user is typing, though.
Michael Myers
Yeah that's the issue I'm having. This is part of a wizard panel and if the user simply selects a date and clicks next then the focus is not lost and the validation method fires too late. Thanks for your input anyway. Seems to be trickier than first thought.
Frank
@Frank: I just tried the KeyListener code you posted and I saw events printed out every time I changed the text of my spinner. Do you just get nothing?
Michael Myers
Really? My ChangeListener is firing fine but if I focus on the Textfield of the JSpinner and edit the value by hand I get nothing. I have breakpointed all key events and it triggers none of them. No output. How can you be successful with the same code? It must be something else... Only way it can make sense if yours works. Thanks I'll keep trying different things.
Frank