views:

1487

answers:

3

So I want to trigger an event (pausing/unpausing some media) whenever the user presses spacebar anywhere in the my Swing app.

Since there are so many controls and panels that could have focus, its not really possible to add keyevents to them all(not to mention gross).

So I found

KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher()

which is awesome, you can register global keypress pre-handlers. There's a major problem though - spaces will be typed all the time in input fields, table cells, etc, and I obviously dont want to trigger the pause event then!

So any ideas? Perhaps there is way to detect globally whether the cursor is focused on something that allows text input, without having to check through a list of all the editable controls(vomit!)?

+2  A: 

I think you answered that yourself - yes I think you can find out the current element that has focus, and if it is an instanceof a certain field class, you ignore the space for the purpose of pause event. If it seams heavy handed, don't worry, instanceof is VERY fast for the JVM (and in any cause you are talking human scale events which are an eon to a processor).

Michael Neale
+1  A: 

I'm rusty on my Swing, but I think you should try registering a global listener using Toolkit.addAWTEventListener with a KEY_EVENT_MASK. You can then filter the AWTEvent processing based on its type and source.

ykaganovich
A: 

Ok... Well im trying to filter based on source. Problem is my editable ComboBoxes... They are instanceof

javax.swing.plaf.basic.BasicComboBoxEditor$BorderlessTextField

And since BorderlessTextField is a private inner class, I apparently cant do an instanceof check against it.

ideas?

EDIT: ok so this works....

 KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {

            public boolean postProcessKeyEvent(KeyEvent e) {
                if (e.getID() == KeyEvent.KEY_PRESSED) {
                    Object s = e.getComponent();
                    if (!(s instanceof JTextField) &&
                        !(s instanceof JTable && ((JTable) s).isEditing())
                        ) {
                        music_player.pauseEvent();
                    }

                    //System.out.println(s.getClass().toString());
                }
                return true;
            }
        });

Its totally gross and I hate it. I wish I could figure out a way to check if the keypress has been consumed by any component - then I could only perform the pause event when the keypress was not actioned by any component.

dalyons