【问题标题】:remove default focus from TextField JavaFX从 TextField JavaFX 中删除默认焦点
【发布时间】:2015-05-17 01:20:55
【问题描述】:

我在 SceneBuilder 的表单中设计了一些 TextField,当我运行代码时,默认情况下单击了其中一个 TextField,我希望在运行代码时,默认情况下没有选择任何 TextField,用户选择一个文本文件。

更新:正如您在this 图像中看到的那样,我想在代码运行时使第一个字段像其他两个字段一样(字段中没有光标)

我该怎么做?

【问题讨论】:

  • @maxd 不!我已经尝试过该解决方案,但对我不起作用
  • setFocus(false) 不适合你?
  • @ItachiUchiha TextField 没有 setFocus 函数
  • @Yashar Ahh,我的错,这是一种受保护的方法。检查我的答案。

标签: javafx textfield scenebuilder


【解决方案1】:

由于没有公共方法可以实现这一点,因此没有直接的方法。不过,您可以使用技巧来做到这一点。您可以使用BooleanProperty 来检查控件何时首次聚焦。监听控件的focusProperty(),当它第一次获得焦点时,将焦点委托给它的容器。对于其余的重点,它将按应有的方式工作。

示例:

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        final BooleanProperty firstTime = new SimpleBooleanProperty(true); // Variable to store the focus on stage load
        VBox vBox = new VBox(10);
        vBox.setPadding(new Insets(20));
        TextField t1 = new TextField();
        TextField t2 = new TextField();
        TextField t3 = new TextField();
        t1.setPromptText("FirstName");
        t2.setPromptText("LastName");
        t3.setPromptText("Email");
        vBox.getChildren().addAll(new HBox(t1, t2), t3);
        primaryStage.setScene(new Scene(vBox, 300, 300));
        primaryStage.show();
        t1.focusedProperty().addListener((observable,  oldValue,  newValue) -> {
            if(newValue && firstTime.get()){
                vBox.requestFocus(); // Delegate the focus to container
                firstTime.setValue(false); // Variable value changed for future references
            }
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}

在初始屏幕加载时:

【讨论】:

  • 我遇到了同样的情况并有一个问题:一个简单的布尔值不适合?为什么将 firstTime 作为 BooleanProperty
  • 在使用 JavaFX 时,您应该将所有变量声明为属性。此外,firstTime 在 lambda 中使用,这意味着它必须是最终的,并且其状态不能更改。如果您将其声明为 boolean,您将无法重新分配其值。
【解决方案2】:

在我的情况下,接受的答案不起作用。但这有效:

我为包裹在 runLater 中的父请求焦点。

@FXML
public void initialize() {

    //unfocus pathField
    Platform.runLater( () -> root.requestFocus() );
}

requestFocuss 直接调用不起作用。

【讨论】:

    【解决方案3】:

    对于不可编辑的 TextField 也有同样的问题,每次都会被选中并突出显示。

    通过设置myTextField.setFocusTraversable(false);解决了

    请注意,在这种情况下,焦点转到下一个 UI 元素,您必须设置每个不希望聚焦的元素。您也无法通过 Tab 键选择元素。

    ApiDoc 声明 setFocusTraversable() 默认为 false,但这似乎不起作用,除非明确调用。

    【讨论】:

      【解决方案4】:

      您可以在初始化方法中简单地将可遍历的焦点设置为 false。这是一个例子:

      @Override
      public void initialize(URL location, ResourceBundle resources) {
          yourTextField.setFocusTraversable(false);
      }
      

      【讨论】:

      【解决方案5】:

      您可以简单地使用Bindings

      TextField textField = new TextField();
      textField.styleProperty().bind(
                      Bindings
                              .when(textField.focusedProperty())
                              .then("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);")
                              .otherwise("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);"));
      

      这将使您的提示文本即使在 TextField 处于焦点时也可见,只要它是空的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-15
        • 2019-09-13
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多