0

From a java textbook, I copied a program that lets users move a body of text around their screens, using their arrow keys. The program will only work on non-OSX operating systems (I confirmed this with my mac and, presumably, it ran on the computer of the java textbook writer). I found a resolution to this discrepancy (Java KeyEvents on Mac), which recommended that I use KeyBindings instead of ActionListeners to process the firing and listening of events, with the vague rationale that

Note: To define special reactions to particular keys, use key bindings instead of a key listener.

While my code now runs, I still don't understand the resolution's rationale. Why is it that KeyBindings, but not KeyListeners, detect Mac arrowkey commands? The arrowkey commands are not "special reactions" that involve multiple keys (like Shift + a + b).

This is a segment of what I copied, the code that used a KeyListener

addKeyListener(new KeyListener()
        {

            @Override
            public void keyReleased(KeyEvent e) {

                switch (e.getKeyCode())
                {
                    case KeyEvent.VK_DOWN: 
                        y -= 10;
                        break;
                    case KeyEvent.VK_UP: 
                        y += 10; 
                        break;

                    //.... more code

And a segment with KeyBindings

 class DownAction extends AbstractAction
    {

        @Override
        public void actionPerformed(ActionEvent e) {
            y += 10;
            repaint();
        }
    }

    class UpAction extends AbstractAction
    {

        @Override
        public void actionPerformed(ActionEvent e) {
            y -= 10;
            repaint();
        }
    }
        this.getInputMap().put(KeyStroke.getKeyStroke("DOWN"),"down");
        this.getActionMap().put("down", new DownAction ());
        this.getInputMap().put(KeyStroke.getKeyStroke("UP"),"up");
        this.getActionMap().put("up", new UpAction ());

        // this segment is within a class that extends JPane
Community
  • 1
  • 1
Muno
  • 575
  • 2
  • 5
  • 20
  • 2
    You're confusing ActionListener with KeyListener -- two **very** different things. When asking programming questions, accuracy in communication is an absolute necessity, so please clean up your question. I don't have a Mac and so cannot test or answer your question, but can say that in general Key Bindings should be preferred over KeyListeners since they are higher-level constructs, since they can get around the focus issues that plague KeyListeners, and since that's what the Oracle gods recommend that you do (check the tutorial to see). – Hovercraft Full Of Eels Jun 21 '15 at 20:56
  • 1
    I would argue that it's possible to detect arrow keys on Mac OS, but key bindings are simply a bette, more reusable solution – MadProgrammer Jun 21 '15 at 22:31

1 Answers1

1

With a key listener, "a component must have the keyboard focus." In contrast, key bindings "take the containment hierarchy into account." You may have encountered a platform-specific vagary in how the containment hierarchy is searched or how the focus subsystem works.

As a concrete example, LinePanel contains a ControlPanel containing a number of MoveButton instances. Each MoveButton has an Action that moves the line. The enclosing ControlPanel also gets a WHEN_IN_FOCUSED_WINDOW map entry that binds the matching arrow key to an Action that clicks the corresponding button. In this way, a particular arrow buttons displays visual feedback, even if another button has focus.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045