添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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

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) {                    
                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
                Oct 6, 2010 at 15:07
                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
                Oct 6, 2010 at 15:22

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)

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 Oct 6, 2010 at 15:19 @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 Oct 6, 2010 at 15:36 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 Oct 6, 2010 at 15:50 @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 Oct 6, 2010 at 16:00 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 Oct 6, 2010 at 16:07

This is a shortfall of swing, and in my opinion JSpinner should follow JComboBox in supplying the following access to the underlying text field:

JComboBox.getEditor().getEditorComponent()

From going through the source of J1.7 I found you can acheive pretty much the same thing with

JSpinner.getEditor().getComponent(0)

Therefore you can "hack" the listener in the following way:

JSpinner.getEditor().getComponent(0).addKeyListener(...)

Obviously this depends on the 'under the covers' implementation of swing and works as at J1.7 but there is no guarantee this works for other versions future or past.

Enjoy.

or if the editor is an instance of DefaultEditor, you can cast it as such and use 'getTextField()'. It would be handy if this were defined in the interface.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.