温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - TextField textProperty Listener across embedded scenes JavaFX
javafx listener javafx-8

其他 - 嵌入场景中的TextField textProperty Listener JavaFX

发布于 2020-04-11 12:35:53

这可能有点令人费解,但是请忍受我。

我有3个使用SceneBuilder构建的场景。我用作父场景的第一个(“ Main”)。该场景包含1个AnchorPane,其中包含a TabPane和a ToolBar,其中包含3个Buttons(“ Previous”,“ Next”和“ Close”)。

第二个场景(“ PersonaDetails”)包含一个AnchorPaneGridPane多个Textflow(我正在用作字段标签),多个TextFieldDatePicker整个场景被嵌入到TabPane第一个场景(“主”)上的一个选项卡中

第三个场景(“地址”)与第二个场景非常相似,第二个场景包含一个AnchorPaneGridPane多个Textflow(我用作字段标签),多个TextFieldComboBox整个场景被嵌入到TabPane第一个场景(“ Main”)上的另一个选项卡中

(我在下面包含了FXML脚本)

该应用程序稍后将在第一个场景(“主”)的TabPane的其他选项卡上包含其他场景。该应用程序将构成较大应用程序的一部分,并且是一种允许注册新客户端的向导。

此外,每个FXML文件及其控制器都在单独的程序包中。

我遇到的问题是,我需要.textProperty()在多个侦听器上添加侦听器,Textfield以便可以Button在第一个或父场景(“主”)上启用或禁用“下一个”

我已经在MainController该类中尝试了以下代码,但是虽然它不会产生任何错误,但是它不起作用。

package com.yas.registrationwizard.main;

import com.yas.registrationwizard.personaldetails.PersonalDetailsController;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TabPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class MainController implements Initializable {

    @FXML AnchorPane apMain;
    @FXML ToolBar tbMain;
    @FXML TabPane tpMain;

    @FXML Button btnPrevious;
    @FXML Button btnNext;
    @FXML Button btnClose;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../personaldetails/PersonalDetails.fxml"));
        try {
            fxmlLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
        PersonalDetailsController personalDetailsController = fxmlLoader.getController();
        personalDetailsController.tfFirstName.textProperty().addListener((obs, oldVal, newVal) -> {
            if(newVal.equals("")) {
                btnNext.setDisable(true);
            } else {
                btnNext.setDisable(false);
            }
        });
    }
}

FXML脚本如下:

主要

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

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="apMain" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.yas.registrationwizard.main.MainController">
    <children>
        <ToolBar fx:id="tbMain" layoutX="259.0" layoutY="339.0" prefHeight="40.0" prefWidth="200.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="355.0">
            <items>
                <Pane prefHeight="30.0" prefWidth="370.0" />
                <Button fx:id="btnPrevious" maxHeight="25.0" maxWidth="65.0" minHeight="25.0" minWidth="65.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Previous" />
                <Button fx:id="btnNext" layoutX="10.0" layoutY="13.0" maxHeight="25.0" maxWidth="65.0" minHeight="25.0" minWidth="65.0" mnemonicParsing="false"  prefHeight="25.0" prefWidth="65.0" text="Next" />
                <Button fx:id="btnClose" layoutX="66.0" layoutY="13.0" maxHeight="25.0" maxWidth="65.0" minHeight="25.0" minWidth="65.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Close" />
            </items>
        </ToolBar>
        <TabPane fx:id="tpMain" layoutX="14.0" layoutY="14.0" prefHeight="335.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
            <tabs>
                <Tab fx:id="tabPersonalDetails" text="Personal Deatils">
               <content>
                  <fx:include fx:id="apPersonalDetails" source="../personaldetails/PersonalDetails.fxml" />
               </content></Tab>
                <Tab fx:id="tabAddress" text="Address">
               <content>
                  <fx:include fx:id="apAddress" source="../address/Address.fxml" />
               </content></Tab>
            </tabs>
        </TabPane>
    </children>
</AnchorPane>

地址

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

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="apAddress" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="325.0" prefWidth="590.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.yas.registrationwizard.address.AddressController">
   <children>
      <GridPane fx:id="gpAddress" layoutX="195.0" layoutY="103.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="103.0" minWidth="3.0" prefWidth="82.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="219.0" minWidth="10.0" prefWidth="155.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="422.0" minWidth="10.0" prefWidth="274.0" />
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="93.0" minWidth="0.0" prefWidth="78.0" />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="295.0" text="House Name / Number:" GridPane.columnIndex="1" GridPane.rowIndex="2">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin></Label>
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="246.0" text="Address Line 1:" GridPane.columnIndex="1" GridPane.rowIndex="3">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin></Label>
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="239.0" text="Address Line 2:" GridPane.columnIndex="1" GridPane.rowIndex="4">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin></Label>
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="234.0" text="Town / City:" GridPane.columnIndex="1" GridPane.rowIndex="5">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin></Label>
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="237.0" text="Region / County:" GridPane.columnIndex="1" GridPane.rowIndex="6">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin></Label>
            <TextField fx:id="tfHseNameNum" GridPane.columnIndex="2" GridPane.rowIndex="2" />
            <TextField fx:id="tfAddLine1" GridPane.columnIndex="2" GridPane.rowIndex="3" />
            <TextField fx:id="tfAddLine2" GridPane.columnIndex="2" GridPane.rowIndex="4" />
            <TextField fx:id="tfTownCity" GridPane.columnIndex="2" GridPane.rowIndex="5" />
            <TextField fx:id="tfRegionCounty" GridPane.columnIndex="2" GridPane.rowIndex="6" />
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="234.0" text="Postcode:" GridPane.columnIndex="1" GridPane.rowIndex="7">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin>
            </Label>
            <TextField fx:id="tfPostcode" GridPane.columnIndex="2" GridPane.rowIndex="7" />
            <Label alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefHeight="17.0" prefWidth="234.0" text="Country:" GridPane.columnIndex="1" GridPane.rowIndex="8">
               <GridPane.margin>
                  <Insets right="10.0" />
               </GridPane.margin>
            </Label>
            <ComboBox fx:id="cboCountry" prefHeight="25.0" prefWidth="294.0" GridPane.columnIndex="2" GridPane.rowIndex="8" />
         </children>
      </GridPane>
   </children>
</AnchorPane>

人员详细信息

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

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane fx:id="apPersonalDetails" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="325.0" prefWidth="590.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.yas.registrationwizard.personaldetails.PersonalDetailsController">
   <children>
      <GridPane fx:id="gpPersonalDetails" layoutX="195.0" layoutY="103.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="37.0" prefWidth="37.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="236.0" minWidth="10.0" prefWidth="236.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="422.0" minWidth="10.0" prefWidth="277.0" />
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="80.0" minWidth="38.0" prefWidth="41.0" />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <TextField fx:id="tfFirstName" GridPane.columnIndex="2" GridPane.rowIndex="2" />
            <TextField fx:id="tfMidNameInit" GridPane.columnIndex="2" GridPane.rowIndex="3" />
            <TextField fx:id="tfLastName" GridPane.columnIndex="2" GridPane.rowIndex="4" />
            <DatePicker fx:id="dpDoB" prefHeight="25.0" prefWidth="365.0" GridPane.columnIndex="2" GridPane.rowIndex="5" />
            <TextField fx:id="tfNatInsNum" GridPane.columnIndex="2" GridPane.rowIndex="6" />
            <TextFlow fx:id="tflFirstName" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="2">
               <GridPane.margin>
                  <Insets right="10.0" top="10.0" />
               </GridPane.margin></TextFlow>
            <TextFlow fx:id="tflLastName" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="4">
               <padding>
                  <Insets right="10.0" top="10.0" />
               </padding>
            </TextFlow>
            <TextFlow fx:id="tflDoB" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="5">
               <padding>
                  <Insets right="10.0" top="10.0" />
               </padding>
            </TextFlow>
            <TextFlow fx:id="tflNatInsNum" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="6">
               <padding>
                  <Insets right="10.0" top="10.0" />
               </padding>
            </TextFlow>
            <TextFlow fx:id="tflMidNameInit" prefHeight="16.0" prefWidth="162.0" style="-fx-text-alignment: right;" styleClass="txtFlow" GridPane.columnIndex="1" GridPane.rowIndex="3">
               <padding>
                  <Insets right="10.0" top="10.0" />
               </padding>
            </TextFlow>
         </children>
      </GridPane>
   </children>
</AnchorPane>

下图显示了项目的文件夹结构:

资料夹结构

查看更多

提问者
Yasterfari
被浏览
76
Sai Dandem 2020-02-04 06:14

首先,我对问题中的“现场”一词感到困惑。我相信您在问题中提到的是关于节点的处理,因为所有fxml都是在同一场景/舞台中处理的。

无论如何,问题的主要问题在于MainController的initialize方法。您正在加载PersonalDetailsController的新实例并对其进行处理,而不是在实际上绑定到MainController的控制器上进行处理。

当在fxml中包含fxml时,子fxml的控制器将已经注入到主fxml控制器中。因此,我相信如下所述更改MainController代码应该可以正常工作。

更新:很抱歉有些误导信息。正确的是,您需要使用特定的命名约定注入控制器。如果要使用fx:include包含fxml,则要获取控制器,需要注入命名约定<fxid>Controller<fxid>获取节点引用。

因此,考虑您的示例,对于给定的fx:include行:

<fx:include fx:id="apPersonalDetails" source="../personaldetails/PersonalDetails.fxml" />

您在MainController中的代码应为:

// For controller reference
@FXML PersonalDetailsController apPersonalDetailsController;

// For Node reference
@FXML AnchorPane apPersonalDetails;

因此,更新后的代码如下:

import com.yas.registrationwizard.personaldetails.PersonalDetailsController;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TabPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class MainController implements Initializable {

    @FXML AnchorPane apMain;
    @FXML ToolBar tbMain;
    @FXML TabPane tpMain;

    @FXML Button btnPrevious;
    @FXML Button btnNext;
    @FXML Button btnClose;

    @FXML PersonalDetailsController apPersonalDetailsController;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        apPersonalDetailsController.tfFirstName.textProperty().addListener((obs, oldVal, newVal) -> {
            if(newVal.equals("")) {
                btnNext.setDisable(true);
            } else {
                btnNext.setDisable(false);
            }
        });
    }
}