【问题标题】:Listen to changes in TextField defined in FXML监听 FXML 中定义的 TextField 的变化
【发布时间】:2018-09-22 16:58:23
【问题描述】:

我正在编写一个简单的登录 GUI,它由一个主容器 GridPane、一个接受用户昵称的 TextField 和最后一个登录按钮组成。

我用 FXML 结合 CSS 编写了 GUI 结构。

我想要做的是保持禁用登录按钮,直到用户实际在 TextField 中写了一些东西。我只能找到与此相关的答案,但我想知道将此侦听器放入 FXML 代码本身的最佳方法是什么,以便我可以在 FXML 控制器中获得更清晰的代码。

我尝试使用 onKeyTyped 方法,但没有成功,因为我在 TextField 中输入时没有收到任何响应。

这是我的 FXML 代码

<TextField fx:id="usernameTextField"
                       promptText="Username"
                       onKeyTyped="#userTyped"
                       stylesheets="@loginStyle.css">

实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: javafx javafx-8 fxml


    【解决方案1】:

    这是一个老问题,但如果您想要 TextField 的侦听器,您可以通过 FXML 实现此操作,而无需 initialize() 中的任何代码。

    将带有处理程序的 onTextChange 属性添加到您的 TextField:

    <TextField fx:id="usernameTextField"
                       promptText="Username"
                       onTextChange="#userTyped">
    

    在 FXML 中,然后在你的控制器中有一个方法:

    public void userTyped(StringProperty property, String oldValue, String newValue) {
        // do stuff
    }
    

    (请注意,如果您只想禁用按钮,James_D 的表达式绑定答案会更简洁)

    您可以查看here 获取有关此的官方文档。

    【讨论】:

      【解决方案2】:

      一般来说,如果你想在文本字段的文本发生变化时执行一个动作,你需要用文本字段的textProperty()注册一个监听器,你必须在控制器中做:

      @FXML
      private TextField usernameTextField ;
      
      public void initialize() {
          usernameTextField.textProperty().addListener((obs, oldText, newText) -> {
              // do what you need with newText here, e.g.
              loginButton.setDisable(newText.isEmpty());
          });
      }
      

      但是,如果您只需将一个控件中的属性绑定到另一个控件中的属性(或该属性的一些简单依赖项),则可以使用FXML expression binding

      <TextField fx:id="usernameTextField"/>
      <Button text="Login" disable="${usernameTextField.text.empty}" />
      

      这是一个 SSCCE:

      ButtonDisableTest.fxml:

      <?xml version="1.0" encoding="UTF-8"?>
      
      <?import javafx.scene.layout.VBox?>
      <?import javafx.scene.control.TextField?>
      <?import javafx.scene.control.Button?>
      
      <VBox alignment="CENTER" spacing="5" xmlns:fx="http://javafx.com/fxml/1">
          <TextField fx:id="usernameTextField"/>
          <Button text="Login" disable="${usernameTextField.text.empty}" />
      </VBox>
      
      import javafx.application.Application;
      import javafx.fxml.FXMLLoader;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.stage.Stage;
      
      public class ButtonDisableTest extends Application {
      
          @Override
          public void start(Stage primaryStage) throws Exception {
              Parent root = FXMLLoader.load(getClass().getResource("ButtonDisableTest.fxml"));
              Scene scene = new Scene(root, 400, 400);
              primaryStage.setScene(scene);
              primaryStage.show();
          }
      
          public static void main(String[] args) {
              launch(args);
          }
      }
      

      【讨论】:

      • 不知道 FXML 表达式绑定!超级有用的提示,非常感谢!
      【解决方案3】:

      假设您的登录按钮有一个 fx:id="loginButton" 并且它被禁用

      @FXML
      public void userTyped(KeyEvent event) {
          loginButton.setDisable(false);
      }
      

      【讨论】:

      • 这可以完成这项工作,但我希望将一些内容直接添加到 TextField 的 FXML 中
      • 我不认为可以直接从 FXML 完成
      • 此外,这并非在所有情况下都有效:例如如果用户使用鼠标将文本复制并粘贴到文本字段中,则不会调用键处理程序。
      猜你喜欢
      • 2020-09-23
      • 2018-10-13
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多