我想创建一个表,我想在其中配置热键快捷键。
我有这个简单的表格:
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;
}
我希望当我点击第二列中的行以获取我将按下的键组合,然后使用这些键激活键盘快捷键。任何例子都会有所帮助。
P.S表及命令:
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;
}
答案 0 :(得分:8)
下面是SSCCE,但没有tableView没有列或单元格。但逻辑是相似的。检查它是否有线索,并根据您的需要编写自己的代码:
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);
}
}
如何运作?
1)从选择框中选择一个动作(事件)类型
2)聚焦到文本字段并键入所需的快捷方式,例如 Alt + F1 。
3)按 Tab 从TextField中聚焦
4)再次按下快捷键(在这种情况下为 Alt + F1 )以查看实际操作中的事件。
5)按“重置”按钮确定重置状态。
进一步的改进应该是定义一个模型类,它具有ShortCut键,用于Ctrl,Alt和Shift的布尔值,用于处理的事件处理程序并适当地覆盖equals(...)
方法。
答案 1 :(得分:1)
这是应该让你开始的东西。为简单起见,我只处理了ctrl和alt元组键,只处理了一列,但应该很明显如何继续。我的方法是使用TextFieldTableCell和一个自定义的onKeyPressed监听器来监听密钥快捷方式,并将它们转换为KeyCharacterCombination。
请注意,此示例不是非常完整或健壮。例如,单个字符未正确处理。不会覆盖标准快捷方式(Ctrl-C,Ctrl-V等)。您可能必须实现自己的TableCell类,以便完全控制键入的文本。
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();
}
}
答案 2 :(得分:0)
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;
}
}
}