在JavaFx场景中编辑窗格
我试图设置一个JavaFx场景,在这个场景中可以在运行时更改嵌套的FlowPane。我希望能够将新元素添加到窗格中,并将它们渲染出来 主要在JavaFx场景中编辑窗格,java,javafx,Java,Javafx,我试图设置一个JavaFx场景,在这个场景中可以在运行时更改嵌套的FlowPane。我希望能够将新元素添加到窗格中,并将它们渲染出来 主要 包可渲染; 导入javafx.application.application; 导入javafx.event.ActionEvent; 导入javafx.event.EventHandler; 导入javafx.fxml.fxml; 导入javafx.fxml.fxmloader; 导入javafx.scene.Parent; 导入javafx.scene.
包可渲染;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.fxml.fxml;
导入javafx.fxml.fxmloader;
导入javafx.scene.Parent;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.layout.FlowPane;
导入javafx.stage.stage;
公共类主扩展应用程序实现EventHandler
我无法正确引用与当前根目录关联的RenderManager
对象,然后运行其“updateFlowPanel()”方法
如何在运行时将元素正确添加到窗格中?获得空指针异常的原因是
@FXML
-注入字段flowPane
仅在控制器中初始化。您正在对非控制器的Main
实例调用updateFlowPanel()
,因此flowPane
在该实例中为null,因此flowPane.getChildren()
引发null指针异常
具体来说:Application.launch()
创建Application
类的实例,并在该实例上调用start()
默认情况下,调用fxmloader.load()
,将创建由FXML根元素中的fx:controller
属性指定的类的实例。在该实例中初始化任何@FXML
-注入的字段,在该实例上调用事件处理程序方法,并在该实例上调用initialize()
方法
由于对应用程序
和控制器类使用相同的类Main
,总是一个错误,因此会出现两个Main
实例。您可以从start()
调用updateFlowPanel()
,即在Application.launch()创建的实例上调用它;但是,flowPane
仅在由fxmloader
创建的实例中初始化
您应该使用单独的控制器类。即做
package renderable;
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 {
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/renderable/ClientRender.fxml"));
Scene scene = new Scene(root, 1000, 720);
primaryStage.setTitle("The Game");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.show();
}
}
然后定义一个控制器类:
package renderable ;
import javafx.fxml.FXML ;
import javafx.scene.layout.FlowPane ;
import javafx.scene.control.Button ;
public class Controller {
@FXML
private FlowPane flowPane ;
public void updateFlowPanel(){
Button button = new Button("...");
flowPane.getChildren().add(button);
}
}
并更新FXML以引用它:
现在,您可以在initialize()
方法中调用updateFlowPanel()
:
package renderable ;
import javafx.fxml.FXML ;
import javafx.scene.layout.FlowPane ;
import javafx.scene.control.Button ;
public class Controller {
@FXML
private FlowPane flowPane ;
public void initialize() {
updateFlowPanel();
}
public void updateFlowPanel(){
Button button = new Button("...");
flowPane.getChildren().add(button);
}
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/renderable/ClientRender.fxml"));
Parent root = loader.load();
Controller controller = loader.getController();
controller.updateFlowPanel();
Scene scene = new Scene(root, 1000, 720);
primaryStage.setTitle("The Game");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.show();
}
或者,您可以从start()
方法在正确的控制器实例上调用它:
package renderable ;
import javafx.fxml.FXML ;
import javafx.scene.layout.FlowPane ;
import javafx.scene.control.Button ;
public class Controller {
@FXML
private FlowPane flowPane ;
public void initialize() {
updateFlowPanel();
}
public void updateFlowPanel(){
Button button = new Button("...");
flowPane.getChildren().add(button);
}
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/renderable/ClientRender.fxml"));
Parent root = loader.load();
Controller controller = loader.getController();
controller.updateFlowPanel();
Scene scene = new Scene(root, 1000, 720);
primaryStage.setTitle("The Game");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.show();
}
编辑:
您对问题所做的更新实际上阻止了代码的编译。如果您通过替换
loader.getController().updateFlowPanel();
与
但是,不使用该FXMLLoader
实例来加载FXML,而是调用静态方法:
由于您调用的是静态方法,因此从未对fxmloader
实例调用load()
,因此其controller
属性从未初始化。因此,loader.getController()
为空,loader.getController().updateFlowPanel()
引发空指针异常(与问题的前一版本中的空指针异常完全不同;它甚至不是从同一方法引发的)
如果要引用控制器,请使用我在上面发布的start()
方法的第二个版本中的代码。1。不太清楚为什么您似乎有两个Application
类。控制器类不应是应用程序
子类的子类。2.如果要更改FXML中定义的现有FlowPane
的内容,则不应创建新的FlowPane
。只需对现有的流程窗格进行更改即可。3.你可能需要在这里创建一个模型,这样我们就可以看到所有的部件是如何组合在一起的。创建一个尽可能简单的示例,说明您正在尝试做什么,并编辑您的问题以将其全部包含在内。我不知道如何更改现有的流程窗格。当我尝试使用fxid引用它时,我得到一个NullPointerException。然后您可能没有在实际控制器上调用fillFlowPane()
(您可能在RenderManager控制器的另一个实例上调用它)。但从你在这里发布的内容是无法判断的。我们甚至不知道您实际运行的是哪个类作为主类(同样,为什么有两个应用程序类??)。您需要发布一个。另外,
?我很确定这不是有效的FXML。您需要在控制器上调用updateFlowPanel()
:您在Main
的错误实例上调用它。为控制器使用单独的类(而不是应用程序
类)。决不能将应用程序
类用作控制器类。
loader.getController().updateFlowPanel();
loader.<Main>getController().updateFlowPanel();
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(getClass().getResource("/renderable/ClientRender.fxml"));