Quantcast
Channel: Oracle Bloggers
Viewing all articles
Browse latest Browse all 19780

Keyboard Move Action for NetBeans Visual Library

$
0
0

By default, the MoveAction on Widgets in the NetBeans Visual Library lets the user move widgets via the mouse. But what about the keyboard? Using the code below, whenever the user presses Up/Down/Left/Right on a widget, it will move 20 pixels in that direction.

Note: Some little gotchas to be aware of are also solved below, e.g., include a SelectProvider so that when a widget is selected, it receives the focus and, more importantly, so that key event processing is correct.

public class AccountBuchWidget extends VMDNodeWidget {

    public AccountBuchWidget(final Scene scene, AccountBuch ab, Point point) {
        super(scene);
        setNodeName(ab.getDescription());
        setPreferredLocation(point);
        getActions().addAction(new KeyboardMoveAction());
        getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
            @Override
            public boolean isAimingAllowed(Widget widget, Point localLocation, boolean invertSelection) {
                return true;
            }
            @Override
            public boolean isSelectionAllowed(Widget widget, Point localLocation, boolean invertSelection) {
                return true;
            }
            @Override
            public void select(Widget widget, Point localLocation, boolean invertSelection) {
                scene.setFocusedWidget(widget);
            }
        }));
    }

    private final class KeyboardMoveAction extends WidgetAction.Adapter {
        private MoveProvider provider;
        private KeyboardMoveAction() {
            this.provider = ActionFactory.createDefaultMoveProvider();
        }
        @Override
        public WidgetAction.State keyPressed(Widget widget, WidgetAction.WidgetKeyEvent event) {
            Point originalSceneLocation = provider.getOriginalLocation(widget);
            int newY = originalSceneLocation.y;
            int newX = originalSceneLocation.x;
            if (event.getKeyCode() == KeyEvent.VK_UP) {
                newY =
newY - 20;
            } else if (event.getKeyCode() == KeyEvent.VK_DOWN) {
                newY =
newY + 20;
            } else if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
                newX =
newX + 20;
            } else if (event.getKeyCode() == KeyEvent.VK_LEFT) {
                newX =
newX - 20;
            }
            provider.movementStarted(widget);
            provider.setNewLocation(widget, new Point(newX, newY));
            return State.CONSUMED;
        }
        @Override
        public WidgetAction.State keyReleased(Widget widget, WidgetAction.WidgetKeyEvent event) {
            provider.movementFinished(widget);
            return State.REJECTED;
        }
    }

}

Here's the constructor of the related TopComponent, note especially the call to "setKeyEventProcessingType":

public EditorTopComponent() {

    initComponents();
    setName(Bundle.CTL_EditorTopComponent());
    setToolTipText(Bundle.HINT_EditorTopComponent());

    setLayout(new BorderLayout());

    JScrollPane pane = new JScrollPane();

    final LayerWidget layerWidget = new LayerWidget(scene);

    scene.getActions().addAction(ActionFactory.createAcceptAction(new AcceptProvider() {
        @Override
        public ConnectorState isAcceptable(Widget widget, Point point, Transferable t) {
            return ConnectorState.ACCEPT;
        }
        @Override
        public void accept(Widget widget, Point point, Transferable t) {
            Node node = NodeTransfer.node(t, NodeTransfer.DND_COPY_OR_MOVE);
            final AccountBuch ab = node.getLookup().lookup(AccountBuch.class);
            layerWidget.addChild(new AccountBuchWidget(scene, ab, point));
        }
    }));

    scene.setKeyEventProcessingType(EventProcessingType.FOCUSED_WIDGET_AND_ITS_CHILDREN);

    scene.addChild(layerWidget);

    pane.setViewportView(scene.createView());

    add(pane, BorderLayout.CENTER);

}

Also, make sure the TopComponent above includes this so that focus is on the Scene when the TopComponent is activated:

    @Override
    public void componentActivated() {
        scene.getView().requestFocusInWindow();
    }

For extra usability, you could include the above Action together with the default MoveAction:

    getActions().addAction(ActionFactory.createMoveAction());
    getActions().addAction(new KeyboardMoveAction());

Now your user can move widgets via the mouse as well as the keyboard. Maybe the keyboard would be used for finetuning the larger movements made by the mouse.


Viewing all articles
Browse latest Browse all 19780

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>