如何从不同的文件控制器访问组件?
How to access components from different file controller?
假设我有两个 FXML 文件:主文件和带有自定义组件的文件。我想从自定义控制器访问主要文件组件,如下所示:
Main.fxml:
<FlowPane>
<children>
<TextField fx:id="source" />
<CustomBox fx:id="cbox" />
</children>
</FlowPane>
Custom.fxml:
<fx:root type="HBox">
<children>
<Button fx:id="showButton" onAction="#show" text="Show" />
</children>
</fx:root>
CustomBox.java:
public class CustomBox extends HBox {
@FXML
private TextField source;
public CustomBox() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Custom.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
@FXML
protected void show() {
System.out.println(source.getText());
}
}
但是方法 show() 给了我 NPE。如何绑定来自不同文件的组件和控制器?
您可以为主 FXML 文件定义一个控制器,并公开其中的文本:
public class MainController {
@FXML
private TextField source ;
@FXML
private CustomBox cbox ;
public String getText() {
return source.getText();
}
@FXML
protected void initialize() {
cbox.setMainController(this);
}
}
当然在Main.fxml
文件
中将其指定为控制器class
<FlowPane fx:controller="my.package.MainController">
<children>
<TextField fx:id="source" />
<CustomBox fx:id="cbox" />
</children>
</FlowPane>
然后将你的CustomBox
修改为
public class CustomBox extends HBox {
private MainController mainController ;
public CustomBox() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Custom.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setMainController(MainController mainController) {
this.mainController = mainController ;
}
public MainController getMainController() {
return mainController ;
}
@FXML
protected void show() {
System.out.println(mainController.getText());
}
}
我还没有对此进行测试,但您也许可以在 FXML 文件中指定主控制器:
<FlowPane fx:controller="my.package.MainController">
<children>
<TextField fx:id="source" />
<CustomBox fx:id="cbox" mainController="$controller" />
</children>
</FlowPane>
然后在MainController
中省略initialize()
方法:
public class MainController {
@FXML
private TextField source ;
public String getText() {
return source.getText();
}
}
假设我有两个 FXML 文件:主文件和带有自定义组件的文件。我想从自定义控制器访问主要文件组件,如下所示:
Main.fxml:
<FlowPane>
<children>
<TextField fx:id="source" />
<CustomBox fx:id="cbox" />
</children>
</FlowPane>
Custom.fxml:
<fx:root type="HBox">
<children>
<Button fx:id="showButton" onAction="#show" text="Show" />
</children>
</fx:root>
CustomBox.java:
public class CustomBox extends HBox {
@FXML
private TextField source;
public CustomBox() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Custom.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
@FXML
protected void show() {
System.out.println(source.getText());
}
}
但是方法 show() 给了我 NPE。如何绑定来自不同文件的组件和控制器?
您可以为主 FXML 文件定义一个控制器,并公开其中的文本:
public class MainController {
@FXML
private TextField source ;
@FXML
private CustomBox cbox ;
public String getText() {
return source.getText();
}
@FXML
protected void initialize() {
cbox.setMainController(this);
}
}
当然在Main.fxml
文件
<FlowPane fx:controller="my.package.MainController">
<children>
<TextField fx:id="source" />
<CustomBox fx:id="cbox" />
</children>
</FlowPane>
然后将你的CustomBox
修改为
public class CustomBox extends HBox {
private MainController mainController ;
public CustomBox() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Custom.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setMainController(MainController mainController) {
this.mainController = mainController ;
}
public MainController getMainController() {
return mainController ;
}
@FXML
protected void show() {
System.out.println(mainController.getText());
}
}
我还没有对此进行测试,但您也许可以在 FXML 文件中指定主控制器:
<FlowPane fx:controller="my.package.MainController">
<children>
<TextField fx:id="source" />
<CustomBox fx:id="cbox" mainController="$controller" />
</children>
</FlowPane>
然后在MainController
中省略initialize()
方法:
public class MainController {
@FXML
private TextField source ;
public String getText() {
return source.getText();
}
}