我的FXML注入有问题。据我所知,我已经设置了程序,但似乎缺少了一些东西。我的代码如下:
主要:
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("NoteKeeper.fxml"));
BorderPane root = (BorderPane)loader.load();
Scene scene = new Scene(root,root.getHeight(),root.getWidth());
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
控制器:
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
public class NoteKeeperController implements Initializable{
NoteBook noteBook;
TreeItem<String> rootItem;
public BorderPane root;
@FXML private TreeView<String> noteTree;
@FXML private ScrollPane sp;
@FXML private Button newNoteButton;
public NoteKeeperController(){
rootItem = new TreeItem<String> ("FirstNote");
rootItem.setExpanded(true);
noteTree.setRoot(rootItem);
noteBook= new NoteBook();
}
@FXML
private void closeProgram(){
System.exit(0);
}
@FXML
private void addNewNote(){
Note note = noteBook.newNote("test", "Problem");
TreeItem<String> newItem= new TreeItem<>(note.getNoteName());
rootItem.getChildren().add(newItem);
}
public BorderPane getRoot() {
return root;
}
public void setRoot(BorderPane root) {
this.root = root;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
}
}
FXML文件:
<BorderPane fx:id="root" prefHeight="719.0" prefWidth="893.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="application.NoteKeeperController">
<center>
<BorderPane prefHeight="641.0" prefWidth="872.0" BorderPane.alignment="CENTER">
<center>
<TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</center>
<left>
<ScrollPane fx:id="sp" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="650.0" prefWidth="200.0">
<children>
<TreeView fx:id="noteTree" prefHeight="650.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
Scenebuilder
识别我正在注入 noteTree,sp和newNoteButton的字段
。但是,当我尝试将项目加载到树形视图时,我得到了NPE。我确认使用if语句表明我的3个字段是null
。堆栈跟踪如下:
Caused by: java.lang.NullPointerException
at application.NoteKeeperController.<init>(NoteKeeperController.java:31)
事实证明我@FXML closeProgram()
和我的@FXML addNewNote()
功能都可以通过。
谁能指出我缺少/做错了什么?
您试图在控制器的构造函数中设置树视图的根项。
当FXMLLoader
负载FXML文件,它将解析FXML文件,并指出任何fx:id
属性。它将实例化控制器(通过调用其no-
arg构造函数),然后它将@FXML
使用具有匹配fx:id
属性的相应对象初始化任何带注释的字段。完成后,它将调用控制器的initialize()
方法(如果有的话)。
因此,构造函数是在noteTree
初始化之前执行的FXMLLoader
(当然,这是可能发生的唯一顺序)。因此,当您致电
noteTree.setRoot(rootItem);
noteTree
还是null
。
解决方法只是将构造函数中的代码移至initialize
方法:
public class NoteKeeperController implements Initializable{
NoteBook noteBook;
TreeItem<String> rootItem;
public BorderPane root;
@FXML private TreeView<String> noteTree;
@FXML private ScrollPane sp;
@FXML private Button newNoteButton;
@Override
public void initialize(URL location, ResourceBundle resources){
rootItem = new TreeItem<String> ("FirstNote");
rootItem.setExpanded(true);
noteTree.setRoot(rootItem);
noteBook= new NoteBook();
}
// ...
}
从正在运行的javafx应用程序打开新的javafx窗口时,我无法将fxml变量绑定到控制器类中的局部变量。 请注意,对于正在运行的应用程序,我可以毫无问题地绑定到同名变量,在运行时在正在运行的应用程序中填充ComboBox。欢迎任何解决方案。 调用新类的代码(ServerConfigChooser) 在运行的应用程序中工作的绑定示例(运行时执行的代码) 控制器类中的fxid“cb_01_fxid
变量绑定默认是不可变的,但加上 mut 修饰语后变量就可以改变。 fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; println!("Before mutation: {}", mutable_binding); // 正确代码 mutable_binding += 1
Rust 通过静态类型确保类型安全。变量绑定可以在声明变量时标注类型。不过在多数情况下,编译器能够 从字面内容推导出变量的类型,大大减少了标注类型的负担。 使用 let 绑定操作可以将值(像具体数据)绑定到变量中。 fn main() { let an_integer = 1u32; let a_boolean = true; let unit = (); // 将
Rust 语言可以先声明变量绑定,后面才将它们初始化。但是这种情况用得很少,因为这样很可能导致使用未 初始的变量。 fn main() { // 声明一个变量绑定 let a_binding; { let x = 2; // 初始化一个绑定 a_binding = x * x; } println!("a bi
事实上每一个非“Hello World” Rust 程序都用了变量绑定。他们将一些值绑定到一个名字上,这样可以在之后使用他们。let被用来声明一个绑定,像这样: fn main() { let x = 5; } 在每个例子中都写上fn main() {有点冗长,所以之后我们将省略它。如果你是一路看过来的,确保你写了main()函数,而不是省略不写。否则,你将得到一个错误。 模式(Patt
我目前正在为我的学习做一个Java(+使用MySQL)应用程序:一个Hopital的数据库 我使用JavaFX编写接口代码。我有一个主FXML(用于一般视图),其中有选项卡,在每个选项卡中,我使用(fx:include)导入另一个FXML。以便我的应用程序的每个模块都有自己的控制器和自己设计的视图。 如何将变量从主控制器传递给其他控制器? 谢谢!编辑:让我给你看我的代码 首先,这是我加载我的fxm