Change/Update 另一个 class 中的 FXML 组件
Change/Update FXML components in another class
我的问题是:我想更改 .fxml 中的某些内容,但无论我做什么,都没有任何改变。这只是一个简单的例子。
我浏览了整个互联网,但 none 的解决方案对我有用。
在这里我想通过从主 class.
调用相应的方法来更改标签的文本
单击按钮时调用相同的方法(此处 setLabel()
),在控制器中使用事件处理程序 class,一切正常,但是当我尝试修改另一个按钮时class 没有任何效果。
主要class:
package sample;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
Controller controller = new Controller();
Platform.runLater(()->controller.setLabel());
}
FXML 代码:
<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<center>
<Label fx:id="label" text="This" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
控制器class:
包装样品;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class Controller {
@FXML
private Label label=new Label();
public void setLabel(){
label.setText("Test");
}
}
你的代码实际上有两个问题。
1) 在 Application
的 start
方法中,您使用 FXMLLoader
加载 sample.fxml
,这是正确的.但是创建一个像 Controller controller = new Controller();
这样的新控制器是不正确的,因为你应该使用 getController 方法从 FXMLLoader
本身获取控制器,而且你不应该使用静态 load
函数FXMLLoader
,但您应该创建它的一个实例。
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getResource("sample.fxml"));
Controller controller = loader.getController();
当您在 FXMLLoader
上调用 load
时,它将从 FXML 文件加载对象层次结构,并且还会创建一个控制器(在 FXML 文件中引用)。
2) 在 Controller
中,您从 FXML 文件中注入 Label
,但您重新创建了它。当 FXMLLoader
基于 fx:id
向您的控制器注入控件时,它还可以确保初始化。如果您创建一个新的 Label
,它将不会指向加载程序创建的 Label
实例。
这个
@FXML private Label label= new Label();
应替换为
@FXML private Label label;
这很简单...您可以通过在控制器 class 中为所需标签添加 getter 方法来更改 Main class 中的标签文本,并且然后使用控制器对象 (loader.getController()) 在 Main class 中获取它并更新其文本。或者使用 Main 中的控制器对象调用控制器 class 内的 setter 方法。
正如 DVagra 所说,使用 loader.getController() 获取控制器对象。
(其中 loader 是 FXMLLoader 的对象)。
此外,您不需要 Platform.runLater() 来更新 gui 控件。因为您已经 运行 在 FX 线程上了。
无论如何,这就是你需要的。
主要Class
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("sample.fxml"));
Parent root = loader.load();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
Controller controller = loader.getController();
controller.setLabel("Test");
// Or
// controller.getLabel().setText("Test");
}
public static void main(String[] args) {
launch(args);
}
}
控制器Class
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable{
@FXML
Label label;
//setter
public void setLabel(String labelText){
label.setText(labelText);
}
//getter for label
public Label getLabel() {
return label;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
Sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.60"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<center>
<Label fx:id="label" text="This" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
我的问题是:我想更改 .fxml 中的某些内容,但无论我做什么,都没有任何改变。这只是一个简单的例子。
我浏览了整个互联网,但 none 的解决方案对我有用。 在这里我想通过从主 class.
调用相应的方法来更改标签的文本单击按钮时调用相同的方法(此处 setLabel()
),在控制器中使用事件处理程序 class,一切正常,但是当我尝试修改另一个按钮时class 没有任何效果。
主要class:
package sample;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
Controller controller = new Controller();
Platform.runLater(()->controller.setLabel());
}
FXML 代码:
<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<center>
<Label fx:id="label" text="This" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
控制器class: 包装样品;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class Controller {
@FXML
private Label label=new Label();
public void setLabel(){
label.setText("Test");
}
}
你的代码实际上有两个问题。
1) 在 Application
的 start
方法中,您使用 FXMLLoader
加载 sample.fxml
,这是正确的.但是创建一个像 Controller controller = new Controller();
这样的新控制器是不正确的,因为你应该使用 getController 方法从 FXMLLoader
本身获取控制器,而且你不应该使用静态 load
函数FXMLLoader
,但您应该创建它的一个实例。
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getResource("sample.fxml"));
Controller controller = loader.getController();
当您在 FXMLLoader
上调用 load
时,它将从 FXML 文件加载对象层次结构,并且还会创建一个控制器(在 FXML 文件中引用)。
2) 在 Controller
中,您从 FXML 文件中注入 Label
,但您重新创建了它。当 FXMLLoader
基于 fx:id
向您的控制器注入控件时,它还可以确保初始化。如果您创建一个新的 Label
,它将不会指向加载程序创建的 Label
实例。
这个
@FXML private Label label= new Label();
应替换为
@FXML private Label label;
这很简单...您可以通过在控制器 class 中为所需标签添加 getter 方法来更改 Main class 中的标签文本,并且然后使用控制器对象 (loader.getController()) 在 Main class 中获取它并更新其文本。或者使用 Main 中的控制器对象调用控制器 class 内的 setter 方法。 正如 DVagra 所说,使用 loader.getController() 获取控制器对象。 (其中 loader 是 FXMLLoader 的对象)。
此外,您不需要 Platform.runLater() 来更新 gui 控件。因为您已经 运行 在 FX 线程上了。
无论如何,这就是你需要的。
主要Class
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("sample.fxml"));
Parent root = loader.load();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
Controller controller = loader.getController();
controller.setLabel("Test");
// Or
// controller.getLabel().setText("Test");
}
public static void main(String[] args) {
launch(args);
}
}
控制器Class
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable{
@FXML
Label label;
//setter
public void setLabel(String labelText){
label.setText(labelText);
}
//getter for label
public Label getLabel() {
return label;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
Sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.60"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<center>
<Label fx:id="label" text="This" BorderPane.alignment="CENTER" />
</center>
</BorderPane>