Мне нужно иметь элемент управления, который будет wordwrap, добавлять полосы прокрутки и т. Д., Но игнорировать клавишу ввода и перейти к следующему элементу управления с помощью вкладки/сдвига. Кажется, я не прав.Как использовать TAB/Enter KeyPressed в TextArea и заменять на Focustraversal или вводить ключ без использования внутреннего API?
Это контроль, который я сделал, и он просто просто остается в текстовой области. (Это использовалось из старого примера в Интернете и, похоже, работает только в том случае, если textArea находится в том же узле, что и остальные).
public class TabAndEnterIgnoringTextArea extends TextArea {
final TextArea myTextArea = this;
public TabAndEnterIgnoringTextArea() {
this.setWrapText(true);
addEventFilter(KeyEvent.KEY_PRESSED, new TabAndEnterHandler());
}
private class TabAndEnterHandler implements EventHandler<KeyEvent> {
private KeyEvent recodedEvent;
@Override
public void handle(KeyEvent event) {
if (recodedEvent != null) {
recodedEvent = null;
return;
}
Parent parent = getParent();
if (parent != null) {
switch (event.getCode()) {
case ENTER:
if (event.isControlDown()) {
recodedEvent = recodeWithoutControlDown(event);
myTextArea.fireEvent(recodedEvent);
} else {
Event parentEvent = event.copyFor(parent, parent);
myTextArea.getParent().fireEvent(parentEvent);
}
event.consume();
break;
case TAB:
if (event.isControlDown()) {
recodedEvent = recodeWithoutControlDown(event);
myTextArea.fireEvent(recodedEvent);
} else if (event.isShiftDown()) {
ObservableList<Node> children = FXCollections.observableArrayList();
addAllDescendents(parent, children);
int idx = children.indexOf(myTextArea);
if (idx > 0) {
for (int i = idx - 1; i > 0; i--) {
if (children.get(i).isFocusTraversable()) {
children.get(i).requestFocus();
break;
}
}
}
} else {
ObservableList<Node> children = FXCollections.observableArrayList();
addAllDescendents(parent, children);
int idx = children.indexOf(myTextArea);
if (idx >= 0) {
for (int i = idx + 1; i < children.size(); i++) {
if (children.get(i).isFocusTraversable()) {
children.get(i).requestFocus();
break;
}
}
if (idx + 1 >= children.size()) {
for (int i = 0; i < idx; i++) {
if (children.get(i).isFocusTraversable()) {
children.get(i).requestFocus();
break;
}
}
}
}
}
event.consume();
break;
default:
break;
}
}
}
private void addAllDescendents(Parent parent, ObservableList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
nodes.add(node);
if (node instanceof Parent)
addAllDescendents((Parent) node, nodes);
}
}
private KeyEvent recodeWithoutControlDown(KeyEvent event) {
return new KeyEvent(event.getEventType(), event.getCharacter(), event.getText(), event.getCode(),
event.isShiftDown(), false, event.isAltDown(), event.isMetaDown());
}
}
Как только я приземлюсь в своем поле, он не уйдет с клавиатуры. Есть идеи? Кроме того, я не должен предполагать, что следующий элемент управления фактически находится в узлах моего родителя, поскольку элемент управления может быть частью другого элемента управления, где его последний элемент управления и следующий могут быть на родительском элементе выше.
В принципе, я хочу следующий доступный предмет на сценографе.
Я могу сделать это с помощью внутреннего API, но я знаю, что это очень обескураживает.
public class TabAndEnterIgnoringTextArea extends TextArea {
final TextArea myTextArea = this;
public TabAndEnterIgnoringTextArea() {
addEventFilter(KeyEvent.KEY_PRESSED, new TabAndEnterHandler());
}
class TabAndEnterHandler implements EventHandler<KeyEvent> {
private KeyEvent recodedEvent;
@Override
public void handle(KeyEvent event) {
if (recodedEvent != null) {
recodedEvent = null;
return;
}
Parent parent = myTextArea.getParent();
Scene scene = parent.getScene();
while (scene == null){
parent = parent.getParent();
scene = parent.getScene();
}
SceneTraversalEngine engine = new SceneTraversalEngine(getScene());
if (parent != null) {
switch (event.getCode()) {
case ENTER:
if (event.isControlDown()) {
recodedEvent = recodeWithoutControlDown(event);
myTextArea.fireEvent(recodedEvent);
} else {
Event parentEvent = event.copyFor(parent, parent);
myTextArea.getParent().fireEvent(parentEvent);
}
event.consume();
break;
case TAB:
if(event.isShiftDown()){
engine.trav(myTextArea, Direction.PREVIOUS);
}else {
engine.trav(myTextArea, Direction.NEXT);
}
}
}
}
private KeyEvent recodeWithoutControlDown(KeyEvent event) {
return new KeyEvent(event.getEventType(), event.getCharacter(), event.getText(), event.getCode(),
event.isShiftDown(), false, event.isAltDown(), event.isMetaDown());
}
}
}
Благодаря
Фильтр событий - фильтрует событие до его попадания в узел. Это верно? В этом случае с textarea он не фильтрует сцену, другие узлы и сцену. Правильно? – Lealo
Это правильно, если вы поместили фильтр на узел. –