How to detect keys

I want to create a table in which I want to configure hotkeys.

I have this simple table:

public static final String Column1MapKey = "A"; public static final String Column2MapKey = "B"; private ObservableList<Map> generateDataInMap() { int max = 110; ObservableList<Map> allData = FXCollections.observableArrayList(); for (int i = 1; i < max; i++) { Map<String, String> dataRow = new HashMap<>(); String value1 = "A" + i; String value2 = "B" + i; dataRow.put(Column1MapKey, value1); dataRow.put(Column2MapKey, value2); allData.add(dataRow); } return allData; } public TabPane hotKeysContent(){ TableColumn<Map, String> firstDataColumn = new TableColumn<>("Actions"); TableColumn<Map, String> secondDataColumn = new TableColumn<>("Shortcut"); firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey)); firstDataColumn.setMinWidth(230); secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey)); secondDataColumn.setMinWidth(230); TableView table_view = new TableView<>(generateDataInMap()); table_view.setPadding(new Insets(5, 5, 5, 5)); table_view.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); // Autoresize when window size is changed table_view.setEditable(true); table_view.getSelectionModel().setCellSelectionEnabled(true); table_view.getColumns().setAll(firstDataColumn, secondDataColumn); Callback<TableColumn<Map, String>, TableCell<Map, String>> cellFactoryForMap = new Callback<TableColumn<Map, String>, TableCell<Map, String>>() { @Override public TableCell call(TableColumn p) { return new TextFieldTableCell(new StringConverter() { @Override public String toString(Object t) { return t.toString(); } @Override public Object fromString(String string) { return string; } }); } }; firstDataColumn.setCellFactory(cellFactoryForMap); secondDataColumn.setCellFactory(cellFactoryForMap); return null; } 

I want when I click on a row in the second column to get the key combination that I press, and then use these keys to activate keyboard shortcuts. Any example would be helpful.

PS Table with commands:

 public static final String Column1MapKey = "A"; public static final String Column2MapKey = "B"; private ObservableList<Map> generateDataInMap() { int max = 110; ObservableList<Map> allData = FXCollections.observableArrayList(); for (int i = 1; i < max; i++) { Map<String, String> dataRow = new HashMap<>(); String value1 = "A" + i; String value2 = "B" + i; dataRow.put(Column1MapKey, value1); dataRow.put(Column2MapKey, value2); allData.add(dataRow); } return allData; } public TabPane hotKeysContent(){ TabPane tabPane = new TabPane(); //tabPane.setStyle("-fx-font-size: 13pt;"); // Set size of the tab name Tab tabA = new Tab(); Label tabALabel = new Label("Shortcuts"); //tabALabel.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name tabA.setGraphic(tabALabel); tabA.setClosable(false); // da se mahne opciqta da se zatvarq tab TableColumn<Map, String> firstDataColumn = new TableColumn<>("Actions"); TableColumn<Map, String> secondDataColumn = new TableColumn<>("Shortcut"); firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey)); firstDataColumn.setMinWidth(230); secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey)); secondDataColumn.setMinWidth(230); TableView table_view = new TableView<>(generateDataInMap()); table_view.setPadding(new Insets(5, 5, 5, 5)); table_view.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); // Autoresize when window size is changed table_view.setEditable(true); table_view.getSelectionModel().setCellSelectionEnabled(true); table_view.getColumns().setAll(firstDataColumn, secondDataColumn); Callback<TableColumn<Map, String>, TableCell<Map, String>> cellFactoryForMap = new Callback<TableColumn<Map, String>, TableCell<Map, String>>() { @Override public TableCell call(TableColumn p) { return new TextFieldTableCell(new StringConverter() { @Override public String toString(Object t) { return t.toString(); } @Override public Object fromString(String string) { return string; } }); } }; firstDataColumn.setCellFactory(cellFactoryForMap); secondDataColumn.setCellFactory(cellFactoryForMap); tabA.setContent(table_view); tabPane.getTabs().add(tabA); return tabPane; } 
+4
source share
3 answers

Below is SSCCE, although there is no tableView no column or cell. However, the logic is similar. Examine it for tips and write your own code to suit your needs:

 public class ShortCutDemo extends Application { private KeyEvent shortcutKeyEvent; private EventHandler selectedEventHandler; private List<EventHandler> eventHandlers; private HBox root; @Override public void start(Stage primaryStage) { root = new HBox(10); root.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { // Do not filter for TextFields if (event.getTarget() instanceof TextField) { return; } if (isKeyEventsAreEqual(event, shortcutKeyEvent)) { // then apply shortcut event selectedEventHandler.handle(null); event.consume(); } } }); eventHandlers = new ArrayList<EventHandler>(); eventHandlers.add(new EventHandler() { @Override public void handle(Event event) { root.setStyle("-fx-background-color: lightgray"); } }); eventHandlers.add(new EventHandler() { @Override public void handle(Event event) { root.setSpacing(50); } }); ChoiceBox cb = new ChoiceBox(); cb.getItems().addAll("HBox background = gray", "HBox spacing = 50"); cb.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { selectedEventHandler = eventHandlers.get(newValue.intValue()); } }); cb.getSelectionModel().selectFirst(); // default value final TextField textField = new TextField(); textField.setEditable(false); textField.setOnKeyPressed(new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { if (event.getCode() == KeyCode.TAB) { // Platform.runLater(new Runnable() { // @Override // public void run() { // root.requestFocus(); // } // }); } else { // Clear the previous text textField.setText(""); // Process only desired key types if (event.getCode().isLetterKey() || event.getCode().isDigitKey() || event.getCode().isFunctionKey()) { String shortcut = event.getCode().getName(); if (event.isAltDown()) { shortcut = "Alt + " + shortcut; } if (event.isControlDown()) { shortcut = "Ctrl + " + shortcut; } if (event.isShiftDown()) { shortcut = "Shift + " + shortcut; } textField.setText(shortcut); shortcutKeyEvent = event; } else { shortcutKeyEvent = null; } } } }); Button button = new Button("Reset"); button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { textField.setText(""); root.setSpacing(10); root.setStyle("-fx-background-color: white"); shortcutKeyEvent = null; } }); root.getChildren().addAll(new Label("Define a shortcut for "), cb, textField, button); Scene scene = new Scene(root, 900, 150); primaryStage.setScene(scene); primaryStage.show(); } private boolean isKeyEventsAreEqual(KeyEvent event1, KeyEvent event2) { return event1 != null && event2 != null && event1.getCode() == event2.getCode() && event1.isAltDown() == event2.isAltDown() && event1.isControlDown() == event2.isControlDown() && event1.isShiftDown() == event2.isShiftDown(); } public static void main(String[] args) { launch(args); } } 

How it works?
1) Select the type of action (event) from the selection area.
2) Focus on the text field and enter the desired shortcut, for example Alt + F1 .
3) Press Tab to focus on the TextField.
4) In this case, click the shortcut ( Alt + F1 ) to see the event in action. 5) Press the "Reset" button to reset.

A further improvement should be the definition of the model class with the ShortCut key, logical for Ctrl, Alt and Shift, an event handler for processing and overriding the equals(...) method accordingly.

+8
source

Here is something that should get you started. For simplicity, I only processed the ctrl and alt meta keys and only one column, but it should be obvious how to proceed. My approach was to use a TextFieldTableCell with an onKeyPressed user listener that listens for key shortcuts and translates them into KeyCharacterCombination s.

Please note that this example is not very complete or reliable. For example, individual characters are not processed correctly. Standard keyboard shortcuts (Ctrl-C, Ctrl-V, etc.) are not overridden. You may have to implement your own TableCell class so that you can completely control what text is typed.

 public class KeyCombinationTableExample extends Application { public static void main(String[] args) { launch(KeyCombinationTableExample.class); } @Override public void start(Stage stage) throws Exception { final ObservableList<KeyCharacterCombination> items = FXCollections.observableArrayList(); for (int i = 0; i < 110; i++) { items.add(null); } TableView<KeyCharacterCombination> table = new TableView<>(items); table.setEditable(true); final TableColumn<KeyCharacterCombination, KeyCharacterCombination> column = new TableColumn<>(); column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<KeyCharacterCombination, KeyCharacterCombination>, ObservableValue<KeyCharacterCombination>>() { @Override public ObservableValue<KeyCharacterCombination> call(TableColumn.CellDataFeatures<KeyCharacterCombination, KeyCharacterCombination> cellDataFeatures) { return new ReadOnlyObjectWrapper<>(cellDataFeatures.getValue()); } }); column.setCellFactory(new Callback<TableColumn<KeyCharacterCombination, KeyCharacterCombination>, TableCell<KeyCharacterCombination, KeyCharacterCombination>>() { @Override public TableCell<KeyCharacterCombination, KeyCharacterCombination> call(TableColumn<KeyCharacterCombination, KeyCharacterCombination> tableColumn) { final TableCell<KeyCharacterCombination, KeyCharacterCombination> cell = new TextFieldTableCell<KeyCharacterCombination, KeyCharacterCombination>() { @Override public void updateItem(KeyCharacterCombination keyCharacterCombination, boolean b) { super.updateItem(keyCharacterCombination, b); if (this.getItem() == null || b) { setText(null); } else { StringBuilder sb = new StringBuilder(); if (keyCharacterCombination.getControl() == KeyCombination.ModifierValue.DOWN) { sb.append("Ctrl + "); } if (keyCharacterCombination.getAlt() == KeyCombination.ModifierValue.DOWN) { sb.append("Alt + "); } sb.append(keyCharacterCombination.getCharacter()); setText(sb.toString()); } } }; cell.setOnKeyPressed(new EventHandler<KeyEvent>() { Set<KeyCombination.Modifier> keys = new HashSet<>(); @Override public void handle(KeyEvent keyEvent) { if (keyEvent.getCode() == KeyCode.CONTROL) { keys.add(KeyCombination.CONTROL_DOWN); } else if (keyEvent.getCode() == KeyCode.ALT) { keys.add(KeyCombination.ALT_DOWN); } else if (keyEvent.getCode().isLetterKey()) { items.set(cell.getIndex(), new KeyCharacterCombination(keyEvent.getCode().getName(), keys.toArray(new KeyCombination.Modifier[keys.size()]))); keys.clear(); } } }); return cell; } }); table.getColumns().add(column); stage.setScene(new Scene(table)); stage.show(); } } 
+1
source
 public class KeyboardExample extends Application{ @Override public void start(final Stage stage) { final Keyboard keyboard = new Keyboard(new Key(KeyCode.A), new Key(KeyCode.S), new Key(KeyCode.D), new Key(KeyCode.F)); final Scene scene = new Scene(new Group(keyboard.createNode())); stage.setScene(scene); stage.setTitle("Keyboard Example"); stage.show(); } public static void main(final String[] args) { launch(args); } 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.WHITE) .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; } } 

}

0
source

Source: https://habr.com/ru/post/1500243/


All Articles