public class EffectTest extends Application { @Override public void start(final Stage stage) { final Keyboard keyboard = new Keyboard( new Key(KeyCode.W), new Key(KeyCode.S), new Key(KeyCode.A), new Key(KeyCode.D) ); final Scene scene = new Scene(new Group(keyboard.createNode())); stage.setScene(scene); stage.setTitle("Keyboard Example"); stage.show(); } private static final class Key { private final KeyCode keyCode; private final BooleanProperty pressedProperty; public Key(final KeyCode keyCode) { this.keyCode = keyCode; this.pressedProperty = new SimpleBooleanProperty(this, "pressed"); } public KeyCode getKeyCode() { return keyCode; } public boolean isPressed() { return pressedProperty.get(); } public void setPressed(final boolean value) { pressedProperty.set(value); } public Node createNode() { final StackPane keyNode = new StackPane(); keyNode.setFocusTraversable(true); installEventHandler(keyNode); final Rectangle keyBackground = new Rectangle(50, 50); keyBackground.fillProperty().bind( Bindings.when(pressedProperty) .then(Color.RED) .otherwise(Bindings.when(keyNode.focusedProperty()) .then(Color.LIGHTGRAY) .otherwise(Color.WHITE))); keyBackground.setStroke(Color.BLACK); keyBackground.setStrokeWidth(2); keyBackground.setArcWidth(12); keyBackground.setArcHeight(12); final Text keyLabel = new Text(keyCode.getName()); keyLabel.setFont(Font.font("Arial", FontWeight.BOLD, 20)); keyNode.getChildren().addAll(keyBackground, keyLabel); return keyNode; } private void installEventHandler(final Node keyNode) { // handler for enter key press / release events, other keys are // handled by the parent (keyboard) node handler final EventHandler<KeyEvent> keyEventHandler = new EventHandler<KeyEvent>() { public void handle(final KeyEvent keyEvent) { if (keyEvent.getCode() == KeyCode.ENTER) { setPressed(keyEvent.getEventType() == KeyEvent.KEY_PRESSED); keyEvent.consume(); } } }; keyNode.setOnKeyPressed(keyEventHandler); keyNode.setOnKeyReleased(keyEventHandler); } } private static final class Keyboard { private final Key[] keys; public Keyboard(final Key... keys) { this.keys = keys.clone(); } public Node createNode() { final HBox keyboardNode = new HBox(6); keyboardNode.setPadding(new Insets(6)); final List<Node> keyboardNodeChildren = keyboardNode.getChildren(); for (final Key key: keys) { keyboardNodeChildren.add(key.createNode()); } installEventHandler(keyboardNode); return keyboardNode; } private void installEventHandler(final Parent keyboardNode) { // handler for key pressed / released events not handled by // key nodes final EventHandler<KeyEvent> keyEventHandler = new EventHandler<KeyEvent>() { public void handle(final KeyEvent keyEvent) { final Key key = lookupKey(keyEvent.getCode()); if (key != null) { key.setPressed(keyEvent.getEventType() == KeyEvent.KEY_PRESSED); keyEvent.consume(); } } }; keyboardNode.setOnKeyPressed(keyEventHandler); keyboardNode.setOnKeyReleased(keyEventHandler); keyboardNode.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { public void handle( final KeyEvent keyEvent) { handleFocusTraversal( keyboardNode, keyEvent); } }); } private Key lookupKey(final KeyCode keyCode) { for (final Key key: keys) { if (key.getKeyCode() == keyCode) { return key; } } return null; } private static void handleFocusTraversal(final Parent traversalGroup, final KeyEvent keyEvent) { final Node nextFocusedNode; switch (keyEvent.getCode()) { case LEFT: nextFocusedNode = getPreviousNode(traversalGroup, (Node) keyEvent.getTarget()); keyEvent.consume(); break; case RIGHT: nextFocusedNode = getNextNode(traversalGroup, (Node) keyEvent.getTarget()); keyEvent.consume(); break; default: return; } if (nextFocusedNode != null) { nextFocusedNode.requestFocus(); } } private static Node getNextNode(final Parent parent, final Node node) { final Iterator<Node> childIterator = parent.getChildrenUnmodifiable().iterator(); while (childIterator.hasNext()) { if (childIterator.next() == node) { return childIterator.hasNext() ? childIterator.next() : null; } } return null; } private static Node getPreviousNode(final Parent parent, final Node node) { final Iterator<Node> childIterator = parent.getChildrenUnmodifiable().iterator(); Node lastNode = null; while (childIterator.hasNext()) { final Node currentNode = childIterator.next(); if (currentNode == node) { return lastNode; } lastNode = currentNode; } return null; } } } //
时间: 2024-10-11 16:40:00