JavaFX 8 TextArea 松散关注选项卡
JavaFX 8 TextArea loose focus on tab
是否可以更改 JavaFX TextArea
的默认行为,以便按 Tab
将焦点传递到下一个组件?
当然可以,但这取决于添加 TextArea 的布局。我创建了一个简单的示例,其中 TextArea
和 TextField
都添加到 VBox
。有一个 keyEventHandler
监听 TextArea
上的 keyPress
事件并将 focus
发送到下一个 child(如果有)
import java.util.Iterator;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextAreaTabFocus extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
VBox box = new VBox();
TextArea textArea = new TextArea();
TextField textField = new TextField();
box.getChildren().addAll(textArea, textField);
final EventHandler<KeyEvent> keyEventHandler =
keyEvent -> {
if (keyEvent.getCode() == KeyCode.TAB) {
Iterator<Node> itr = box.getChildren().iterator();
while(itr.hasNext()) {
if(itr.next() == keyEvent.getSource()) {
if(itr.hasNext()){
itr.next().requestFocus();
}
//If TextArea is the last child
else {
box.getChildren().get(0).requestFocus();
}
break;
}
}
keyEvent.consume();
}
};
textArea.setOnKeyPressed(keyEventHandler);
Scene scene = new Scene(box, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
虽然 @ItachiUchiha 解决方案有效,但正如他所说,这取决于布局(box
在他的示例中)。
基于此 question,您可以修改 TextArea
的默认行为,而不考虑布局。
但是您将需要使用这个私人 API,它可能随时更改,恕不另行通知。
在此示例中,Tab
和 Shitf+Tab
将具有所需的行为,而 Ctrl+Tab
将在文本区域插入 "\t"
。
@Override
public void start(Stage primaryStage) {
TextArea area = new TextArea();
area.addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent event) -> {
if (event.getCode() == KeyCode.TAB) {
TextAreaSkin skin = (TextAreaSkin) area.getSkin();
if (skin.getBehavior() instanceof TextAreaBehavior) {
TextAreaBehavior behavior = (TextAreaBehavior) skin.getBehavior();
if (event.isControlDown()) {
behavior.callAction("InsertTab");
} else if (event.isShiftDown()) {
behavior.callAction("TraversePrevious");
} else {
behavior.callAction("TraverseNext");
}
event.consume();
}
}
});
VBox root = new VBox(20, new Button("Button 1"), area, new Button("Button 2"));
Scene scene = new Scene(root, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
是否可以更改 JavaFX TextArea
的默认行为,以便按 Tab
将焦点传递到下一个组件?
当然可以,但这取决于添加 TextArea 的布局。我创建了一个简单的示例,其中 TextArea
和 TextField
都添加到 VBox
。有一个 keyEventHandler
监听 TextArea
上的 keyPress
事件并将 focus
发送到下一个 child(如果有)
import java.util.Iterator;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextAreaTabFocus extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
VBox box = new VBox();
TextArea textArea = new TextArea();
TextField textField = new TextField();
box.getChildren().addAll(textArea, textField);
final EventHandler<KeyEvent> keyEventHandler =
keyEvent -> {
if (keyEvent.getCode() == KeyCode.TAB) {
Iterator<Node> itr = box.getChildren().iterator();
while(itr.hasNext()) {
if(itr.next() == keyEvent.getSource()) {
if(itr.hasNext()){
itr.next().requestFocus();
}
//If TextArea is the last child
else {
box.getChildren().get(0).requestFocus();
}
break;
}
}
keyEvent.consume();
}
};
textArea.setOnKeyPressed(keyEventHandler);
Scene scene = new Scene(box, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
虽然 @ItachiUchiha 解决方案有效,但正如他所说,这取决于布局(box
在他的示例中)。
基于此 question,您可以修改 TextArea
的默认行为,而不考虑布局。
但是您将需要使用这个私人 API,它可能随时更改,恕不另行通知。
在此示例中,Tab
和 Shitf+Tab
将具有所需的行为,而 Ctrl+Tab
将在文本区域插入 "\t"
。
@Override
public void start(Stage primaryStage) {
TextArea area = new TextArea();
area.addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent event) -> {
if (event.getCode() == KeyCode.TAB) {
TextAreaSkin skin = (TextAreaSkin) area.getSkin();
if (skin.getBehavior() instanceof TextAreaBehavior) {
TextAreaBehavior behavior = (TextAreaBehavior) skin.getBehavior();
if (event.isControlDown()) {
behavior.callAction("InsertTab");
} else if (event.isShiftDown()) {
behavior.callAction("TraversePrevious");
} else {
behavior.callAction("TraverseNext");
}
event.consume();
}
}
});
VBox root = new VBox(20, new Button("Button 1"), area, new Button("Button 2"));
Scene scene = new Scene(root, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
}