javaFX - 如何使用来自另一个控制器的控制器的功能或对象
javaFX - how to use function or object of a controller from another controller
我看到很多和我类似的问题,但我没有弄清楚如何解决我的问题,所以有我的代码:
我有一个简单的主程序:
MainClassFXGui.java
public class MainClassFXGui extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
和三个 fxml 文件,其中一个包含另外两个,标签为
<fx:include source="MyTab1.fxml" />
MyProgramMainGuiTab.fxml
...
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5000.0" prefWidth="5000.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab closable="false" text="MyTab1">
<content>
<fx:include source="MyTab1.fxml" />
</content>
</Tab>
<Tab closable="false" text="MyTab2">
<content>
<fx:include source="MyTab2.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
...
和三个控制器:
MyProgramMainGuiTabController.java
....
@FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
public void setLeftSt(String st){
LeftSt.setText(st);
}
...
MyTab1Controller.java
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
我这样试过:
MyTab1Controller.java
private MyProgramMainGuiTabController controller;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
controller.setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
FXMLLoader fxmlLoader = new
FXMLLoader(getClass().getResource("MyProgramMainGuiTab.fxml"));
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
controller = (MyProgramMainGuiTabController)fxmlLoader.getController();
}
但是我有一个空指针异常,或者如果我将对象 'controller' 实例化的代码移动到 handleButtonAction 函数中,我没有任何错误,但标签没有改变。
也许我可以在 MainClassFXGui.java 中创建静态场景和静态舞台?
但后来我不知道如何使用它们...
MainClassFXGui.java
public class MainClassFXGui extends Application {
static private Scene scene;
static private Stage stage;
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
this.scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
this.stage = stage;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static Scene getScene(){
return AssicurazioneFXGui.scene;
}
public static Stage getStage(){
return AssicurazioneFXGui.stage;
}
}
我可以用 getScene() 或 getStage() 做些什么吗?有什么想法或建议吗?
感谢大家
目前我是这样解决的。如果无论如何有人有更好的解决方案,请写信。也因为如果我需要执行一个功能,这并不能解决问题。谢谢
MyProgramMainGuiTabController.fxml
...
@FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
...
MyTab1Controller.fxml
@FXML
private Button myObject;
private Scene scene;
private Label lblDataLeft;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("this works!");
}
public void setLeftSt(String st){
if(this.scene == null)
this.scene = myObject.getScene();
if(this.lblDataLeft==null)
this.lblDataLeft = (Label) scene.lookup("#LeftSt");
if (this.lblDataLeft!=null)
this.lblDataLeft.setText(st);
}
在MyTab1Controller
中定义一个StringProperty
,用通常的方法:
public class MyTab1Controller {
private final StringProperty leftSt = new SimpleStringProperty();
public StringProperty leftStProperty() {
return leftSt ;
}
public final String getLeftSt() {
return leftStProperty().get();
}
public final void setLeftSt(String leftSt) {
leftStProperty().set(leftSt);
}
// ...
@FXML
public void handleButtonAction() {
setLeftSt(...);
}
// ...
}
现在将 fx:id
属性分配给 fx:include
标签:
<Tab closable="false" text="MyTab1">
<content>
<fx:include fx:id="myTab1" source="MyTab1.fxml" />
</content>
</Tab>
这意味着您可以将 MyTab1.fxml
的 控制器 注入包含它的 FXML 的控制器中 (MyProgramMainGuiTabController
):
public class MyProgramMainGuiTabController {
@FXML
private MyTab1Controller myTab1Controller ;
}
然后你可以只观察 属性 并在它改变时更新标签:
public class MyProgramMainGuiTabController {
@FXML
private MyTab1Controller myTab1Controller ;
@FXML
private Label leftSt;
public void initialize() {
leftSt.setText("");
myTab1Controller.leftStProperty().addListener((obs, oldValue, newValue) ->
leftSt.setText(newValue));
}
}
注意这里的规则是控制器的字段名称是 fx:id
属性的值加上 "Controller" 词: myTab1
在 fx:id
对于注入控制器的字段解析为 myTab1Controller
。有关详细信息,请参阅 NestedControllers。
我看到很多和我类似的问题,但我没有弄清楚如何解决我的问题,所以有我的代码:
我有一个简单的主程序:
MainClassFXGui.java
public class MainClassFXGui extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
和三个 fxml 文件,其中一个包含另外两个,标签为
<fx:include source="MyTab1.fxml" />
MyProgramMainGuiTab.fxml
...
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5000.0" prefWidth="5000.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab closable="false" text="MyTab1">
<content>
<fx:include source="MyTab1.fxml" />
</content>
</Tab>
<Tab closable="false" text="MyTab2">
<content>
<fx:include source="MyTab2.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
...
和三个控制器:
MyProgramMainGuiTabController.java
....
@FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
public void setLeftSt(String st){
LeftSt.setText(st);
}
...
MyTab1Controller.java
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
我这样试过:
MyTab1Controller.java
private MyProgramMainGuiTabController controller;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
controller.setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
FXMLLoader fxmlLoader = new
FXMLLoader(getClass().getResource("MyProgramMainGuiTab.fxml"));
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
controller = (MyProgramMainGuiTabController)fxmlLoader.getController();
}
但是我有一个空指针异常,或者如果我将对象 'controller' 实例化的代码移动到 handleButtonAction 函数中,我没有任何错误,但标签没有改变。
也许我可以在 MainClassFXGui.java 中创建静态场景和静态舞台? 但后来我不知道如何使用它们...
MainClassFXGui.java
public class MainClassFXGui extends Application {
static private Scene scene;
static private Stage stage;
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
this.scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
this.stage = stage;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static Scene getScene(){
return AssicurazioneFXGui.scene;
}
public static Stage getStage(){
return AssicurazioneFXGui.stage;
}
}
我可以用 getScene() 或 getStage() 做些什么吗?有什么想法或建议吗?
感谢大家
目前我是这样解决的。如果无论如何有人有更好的解决方案,请写信。也因为如果我需要执行一个功能,这并不能解决问题。谢谢
MyProgramMainGuiTabController.fxml
...
@FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
...
MyTab1Controller.fxml
@FXML
private Button myObject;
private Scene scene;
private Label lblDataLeft;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("this works!");
}
public void setLeftSt(String st){
if(this.scene == null)
this.scene = myObject.getScene();
if(this.lblDataLeft==null)
this.lblDataLeft = (Label) scene.lookup("#LeftSt");
if (this.lblDataLeft!=null)
this.lblDataLeft.setText(st);
}
在MyTab1Controller
中定义一个StringProperty
,用通常的方法:
public class MyTab1Controller {
private final StringProperty leftSt = new SimpleStringProperty();
public StringProperty leftStProperty() {
return leftSt ;
}
public final String getLeftSt() {
return leftStProperty().get();
}
public final void setLeftSt(String leftSt) {
leftStProperty().set(leftSt);
}
// ...
@FXML
public void handleButtonAction() {
setLeftSt(...);
}
// ...
}
现在将 fx:id
属性分配给 fx:include
标签:
<Tab closable="false" text="MyTab1">
<content>
<fx:include fx:id="myTab1" source="MyTab1.fxml" />
</content>
</Tab>
这意味着您可以将 MyTab1.fxml
的 控制器 注入包含它的 FXML 的控制器中 (MyProgramMainGuiTabController
):
public class MyProgramMainGuiTabController {
@FXML
private MyTab1Controller myTab1Controller ;
}
然后你可以只观察 属性 并在它改变时更新标签:
public class MyProgramMainGuiTabController {
@FXML
private MyTab1Controller myTab1Controller ;
@FXML
private Label leftSt;
public void initialize() {
leftSt.setText("");
myTab1Controller.leftStProperty().addListener((obs, oldValue, newValue) ->
leftSt.setText(newValue));
}
}
注意这里的规则是控制器的字段名称是 fx:id
属性的值加上 "Controller" 词: myTab1
在 fx:id
对于注入控制器的字段解析为 myTab1Controller
。有关详细信息,请参阅 NestedControllers。