这可能有点令人费解,但是请忍受我。
我有3个使用SceneBuilder构建的场景。我用作父场景的第一个(“ Main”)。该场景包含1个AnchorPane
,其中包含a TabPane
和a ToolBar
,其中包含3个Buttons
(“ Previous”,“ Next”和“ Close”)。
第二个场景(“ PersonaDetails”)包含一个AnchorPane
,GridPane
多个Textflow
(我正在用作字段标签),多个TextField
和DatePicker
。整个场景被嵌入到TabPane
第一个场景(“主”)上的一个选项卡中。
第三个场景(“地址”)与第二个场景非常相似,第二个场景包含一个AnchorPane
,GridPane
多个Textflow
(我用作字段标签),多个TextField
和ComboBox
。整个场景被嵌入到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>
下图显示了项目的文件夹结构:
首先,我对问题中的“现场”一词感到困惑。我相信您在问题中提到的是关于节点的处理,因为所有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);
}
});
}
}
措辞很抱歉。我还是这个新手。我尝试了您提供的代码,但在“ personalDetailsController.tfFirstName.textProperty()。addListener ...”行中仍出现nullPointerException
抱歉,有些误导信息。更新了我的答案。