0

Neither of handlers below executed on key pressing:

public class Try_KeyboardInput_01 {

    private static final Logger log = LoggerFactory.getLogger(Try_KeyboardInput_01.class);

    @SuppressWarnings("serial")
    public static void main(String[] args) {
        new PFrame() {
            @Override
            public void initialize() {

                PPath circle = PPath.createEllipse(-100, -100, 200, 200);

                getCanvas().getLayer().addChild(circle);

                circle.addInputEventListener(new PBasicInputEventHandler() {
                    @Override
                    public void keyPressed(PInputEvent event) {
                        log.info("Key pressed on circle");
                    }
                });

                getCanvas().getLayer().addInputEventListener(new PBasicInputEventHandler() {
                    @Override
                    public void keyPressed(PInputEvent event) {
                        log.info("Key pressed on layer");
                    }
                });

                getCanvas().addInputEventListener(new PBasicInputEventHandler() {
                    @Override
                    public void keyPressed(PInputEvent event) {
                        log.info("Key pressed on canvas");
                    }
                });



            }
        };
    }
}

How to activate the feature?

UPDATE

In some demos I see, that keyboard focus can be turned on from within mouse handler. But this is unacceptable if computer has no mouse, or if keyboard handling should be turned on by default.

How to turn on keyboard handling explicitly?

UPDATE 2

Still didn't understand, if it is possible to set keyboard focus on specific node (without a mouse).

Suzan Cioc
  • 29,281
  • 63
  • 213
  • 385
  • You can `setKeyboardFocus` on root and then handle the events or dispatch as needed, to other handlers or nodes. *update 2* is not clear, which node is expected to receive the event? – tenorsax Nov 21 '13 at 21:28
  • For example, a circle. I can attach mouse handler to a circle in code. How to attach keyboard handler to it? – Suzan Cioc Nov 22 '13 at 09:35
  • P.S. So, you mean I should create 2 handlers: (1) for root with dispatcher, and (2) another one for receiving object? – Suzan Cioc Nov 22 '13 at 09:36
  • The number of handlers depends on the scenario - if several handlers need to receive keyboard events (ie - selection handler, panning handler, etc), then a single handler may dispatch to the rest of them. In a simple scenario, one handler may receive keyboard events and dispatch it to relevant nodes, to a circle node for example. The question is, which node should receive the event? – tenorsax Nov 22 '13 at 17:41
  • What did you did in your second snipped? Didn't you assign some node to receive keyboard events? So, I want the same, but not in response to mouse click, but from code. Is it possible? – Suzan Cioc Nov 22 '13 at 18:55
  • In the second snippet the handler was attached to nodes to catch `mousePressed` to setup `setKeyboardFocus`. If you know which node is supposed to react to keyboard then use something similar to a first snippet and just delegate the events to the node in question. See if the last edit helps. – tenorsax Nov 22 '13 at 23:21

1 Answers1

1

To receive keyboard event you have to setup a handler using PInputManager.setKeyboardFocus. For example:

getCanvas().getRoot().getDefaultInputManager().setKeyboardFocus(new PBasicInputEventHandler() {
    @Override
    public void keyPressed(PInputEvent event) {
        switch (event.getKeyCode()) {
        //TODO
        }
    }
});

Or on nodes basis:

PBasicInputEventHandler handler = new PBasicInputEventHandler() {
    @Override  
    public void mousePressed(final PInputEvent event) {
        event.getInputManager().setKeyboardFocus(event.getPath());
        event.setHandled(true);
    }

    @Override
    public void keyPressed(PInputEvent event) {
        System.out.println(event.getPickedNode());
    }
};

There are many variations, depending on the actual scenario. See PSelectionEventHandler and KeyEventFocusExample sources for some examples how the developers intended to deal with keyboard events.

EDIT:

import java.awt.event.KeyEvent;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolox.PFrame;

public class DemoKeyboard {
    static class SampleHandler extends PBasicInputEventHandler {
        private PNode activeNode;

        public void setActiveNode(PNode activeNode) {this.activeNode = activeNode;}
        public PNode getActiveNode() {return activeNode;}

        @Override
        public void keyPressed(PInputEvent event) {
            if (activeNode == null)
                return;
            switch (event.getKeyCode()) {
            case KeyEvent.VK_LEFT: activeNode.translate(-5, 0); break;
            case KeyEvent.VK_UP: activeNode.translate(0, -5); break;
            case KeyEvent.VK_RIGHT: activeNode.translate(5, 0); break;
            case KeyEvent.VK_DOWN: activeNode.translate(0, 5); break;
            }
        }
    };

    public static void main(String[] args) {
        new PFrame() {
            @Override
            public void initialize() {
                final PPath circle = PPath.createEllipse(0, 0, 200, 200);
                getCanvas().getLayer().addChild(circle);

                SampleHandler handler = new SampleHandler();
                handler.setActiveNode(circle);
                getCanvas().getRoot().getDefaultInputManager().setKeyboardFocus(handler);
            }
        };
    }
}
tenorsax
  • 21,123
  • 9
  • 60
  • 107