【问题标题】:Why doesn't JavaFX TextField listener work?为什么 JavaFX TextField 侦听器不起作用?
【发布时间】:2019-06-12 07:52:16
【问题描述】:

我想在我按下前一个窗口上的按钮时出现的窗口中的文本字段中添加一个侦听器。问题是监听器根本不起作用。它没有检测到任何变化。

public class WindowTwoController {

private Stage stage;

@FXML
private TextField imieTF = new TextField();


public void show() throws IOException {

    FXMLLoader loader = new FXMLLoader(getClass().getResource("winTwo.fxml"));
    Parent root = loader.load();

    stage = new Stage();
    stage.initModality(Modality.APPLICATION_MODAL);

    stage.setTitle("Sell Art");
    stage.setScene(new Scene(root, 500, 500));

    imieTF.textProperty().addListener((observable, oldValue, newValue) -> {
        System.out.println("textfield changed from " + oldValue + " to " + newValue);
    });

    stage.showAndWait();

}

我正在更改 textField 的值,但没有任何内容打印到控制台。当在前一个窗口上按下按钮时调用 show 方法。请帮我。这是我的 winTwo.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<GridPane alignment="center" hgap="10" prefHeight="441.0" prefWidth="500.0" vgap="10" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="windowTwo.WindowTwoController">
<columnConstraints>
    <ColumnConstraints />
</columnConstraints>
<rowConstraints>
    <RowConstraints />
</rowConstraints>
<children>
    <VBox prefHeight="354.0" prefWidth="455.0">
        <children>
            <Label alignment="CENTER" prefHeight="45.0" prefWidth="457.0" text="Sprzedaż dzieła">
                <font>
                    <Font size="30.0" />
                </font>
            </Label>
            <Separator prefWidth="200.0" />
            <GridPane prefHeight="139.0" prefWidth="455.0">
                <columnConstraints>
                    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                </columnConstraints>
                <rowConstraints>
                    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                </rowConstraints>
                <children>
                    <Label alignment="CENTER" prefHeight="40.0" prefWidth="220.0" text="Imię">
                        <font>
                            <Font size="28.0" />
                        </font>
                    </Label>
                    <Label alignment="CENTER" prefHeight="40.0" prefWidth="220.0" text="Nazwisko" GridPane.rowIndex="1">
                        <font>
                            <Font size="28.0" />
                        </font>
                    </Label>
                    <TextField fx:id="imieTF" GridPane.columnIndex="1">
                        <GridPane.margin>
                            <Insets right="20.0" />
                        </GridPane.margin></TextField>
                    <TextField fx:id="nazwiskoTF" GridPane.columnIndex="1" GridPane.rowIndex="1">
                        <GridPane.margin>
                            <Insets right="20.0" />
                        </GridPane.margin>
                    </TextField>
                </children>
            </GridPane>
            <Separator prefWidth="200.0" />
            <Label alignment="CENTER" prefHeight="17.0" prefWidth="450.0" text="Klient powracający">
                <font>
                    <Font size="22.0" />
                </font>
            </Label>
            <Separator prefWidth="200.0" />
            <GridPane prefHeight="126.0" prefWidth="455.0">
                <columnConstraints>
                    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                </columnConstraints>
                <rowConstraints>
                    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                </rowConstraints>
                <children>
                    <Label alignment="CENTER" prefHeight="40.0" prefWidth="220.0" text="Poziom Zaprzyjaźnienia" textFill="#00000080">
                        <font>
                            <Font size="19.0" />
                        </font>
                    </Label>
                    <ComboBox fx:id="cb" opacity="0.5" prefHeight="25.0" prefWidth="207.0" GridPane.columnIndex="1" />
                    <Button mnemonicParsing="false" prefHeight="25.0" prefWidth="175.0" text="Akceptuj" GridPane.rowIndex="1">
                        <GridPane.margin>
                            <Insets left="25.0" />
                        </GridPane.margin>
                    </Button>
                    <Button mnemonicParsing="false" prefHeight="25.0" prefWidth="175.0" text="Anuluj" GridPane.columnIndex="1" GridPane.rowIndex="1">
                        <GridPane.margin>
                            <Insets left="27.0" />
                        </GridPane.margin>
                    </Button>
                </children>
            </GridPane>
        </children>
    </VBox>
</children>
</GridPane>

【问题讨论】:

  • 旁注:我不知道为什么“public void show() throws IOException {”没有显示为代码的一部分。是的。
  • 请提供一个minimal reproducible example 来说明问题。至于格式:该行需要以4个空格开头
  • 文本字段 imieTF 是您正在显示的舞台中实际显示的那个吗?如果不是,那么事件不传播到 imieTF 也就不足为奇了
  • 您的TextField imieTF 似乎没有添加到任何窗口。如果这个 imieTF 是 winTwo.fxml 的一部分,它应该在 winTwo 控制器中管理。

标签: java javafx


【解决方案1】:

您应该像这样向私有成员 imieTF 添加注释

public class WindowTwoController {
  @FXML
  private TextField imieTF;

  @FXML
  private void initialize() {
      imieTF.textProperty().addListener((observable, oldValue, newValue) -> 
       {
         System.out.println("textfield changed from " + oldValue + " to " + newValue);
       });
  }

  public static void show() {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("winTwo.fxml"));
    Parent root = loader.load();

    stage = new Stage();
    stage.initModality(Modality.APPLICATION_MODAL);

    stage.setTitle("Sell Art");
    stage.setScene(new Scene(root, 500, 500));
    stage.showAndWait();
  }
}

这应该将 TextField 实例绑定到控制器。但据我所知,当创建属于 fxml 文件的窗口时,FXML 将创建一个新的 WindowTwoController 实例。

另请参阅https://www.callicoder.com/javafx-fxml-form-gui-tutorial/,了解有关其工作原理的基本示例。

请注意,文本字段的所有操作都应该是 JavaFX 流程的一部分,并且不能在 WindowTwoController 的手动实例中完成。请记住,JavaFX 将在 loader.load(); 操作期间创建它自己的 WindowTwoController 实例。

【讨论】:

  • 哦,我忘了把那部分复制到问题中。 @FXML 标记在那里。对此我感到非常抱歉。
  • 它可能在那里,但你不应该在java代码中实例化它。它应该只是@GerbenJongerius 提到的@FXML private TextField imieTF;,而不是@FXML private TextField imieTF = new TextField();
  • 您还应该使用 @FXML 注释您的方法“显示”,以在 JavaFX 创建控制器后触发它被调用。它怎么知道调用该方法。这个方法是如何被调用的,因为它是 WindowTwoController 的一部分,但它应该由 JavaFX 而不是你来实例化。
  • 当我将其更改为“@FXML private TextField imieTF;”时我在“imieTF.textProperty().addListener((observable, oldValue, newValue) -> {...”行得到一个 nullPointerException。有人知道为什么吗?
  • 我已经扩展了一些答案。您需要记住,您调用 show 方法的 WindowTwoController 实例与 JavaFX 在加载文件 winTwo.fxml 时创建的实例不同。
猜你喜欢
  • 2019-04-21
  • 2016-10-10
  • 2015-07-21
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多