【问题标题】:JavaFX 8 TextArea loose focus on tabJavaFX 8 TextArea 放松对选项卡的关注
【发布时间】:2015-04-24 14:09:15
【问题描述】:

是否可以更改 JavaFX TextArea 的默认行为,以便按下 Tab 将焦点传递到下一个组件?

【问题讨论】:

标签: javafx-8


【解决方案1】:

正如他所说,虽然@ItachiUchiha 解决方案有效,但它取决于布局(在他的示例中为box)。

基于此question,您可以修改TextArea 的默认行为,而不管布局如何。

但您需要使用此私有 API,该 API 可能随时更改,恕不另行通知。

在此示例中,TabShitf+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();
}

【讨论】:

  • 在 Java 9 (2017) 中不起作用,因为您不能再使用 skin.getBehavior()
  • 它不适用于 Java 1.8.0_311-b11 但 this one 完美运行:
【解决方案2】:

嗯,你当然可以这样做,但这取决于 TextArea 添加到的布局。我创建了一个简单的示例,其中TextAreaTextField 都添加到VBox。有一个keyEventHandler 监视TextArea 上的keyPress 事件并将focus 发送给下一个孩子(如果有)

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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多