![](/img/trans.png)
[英]JavaFX TableColumn.setCellValueFactory() throws null pointer
[英]JavaFX, why is TableColumn null?
正如您將看到的那樣,在Java和Javafx方面,我是一個菜鳥。 我花了很多時間閱讀(各種論壇帖子和Tut),並試圖弄清楚自己在哪里得到了這個問題,但是現在我要發表自己的觀點來征求了解他們業務的人的反饋。
回復時,請您抽出些時間來解釋為什么某些功能不起作用以及一些一般性提示嗎? 到目前為止,這是我所擁有的(我的FXML和我的兩個類)任何指針都很棒!
我的FXML;
<Pane id="myScene" fx:id="myScene" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.TestController">
<children>
<TableView id="employeesTable" fx:id="employeesTable" layoutX="131.0" layoutY="64.0" prefHeight="200.0" prefWidth="360.0">
<columns>
<TableColumn id="colFirstName" fx:id="colFirstName" prefWidth="75.0" text="First Name" />
<TableColumn id="colLastName" fx:id="colLastName" prefWidth="75.0" text="Last Name" />
<TableColumn id="colEmail" fx:id="colEmail" prefWidth="75.0" text="email" />
</columns>
</TableView>
</children>
</Pane>
現在我有了Employee類;
public class Employee {
private StringProperty firstName;
private StringProperty lastName;
private StringProperty email;
public Employee(String a, String b, String c) {
this.firstName = new SimpleStringProperty(a);
this.lastName = new SimpleStringProperty(b);
this.email = new SimpleStringProperty(c);
}
public Employee() {
}
public String getFirstName() {
return firstName.get();
}
public StringProperty firstNameProperty() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
return lastName.get();
}
public StringProperty lastNameProperty() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public String getEmail() {
return email.get();
}
public StringProperty emailProperty() {
return email;
}
public void setEmail(String email) {
this.email.set(email);
}
}
最后,我的測試控制器的類是
public class TestController {
public Label login;
public TextField loginUserName;
public PasswordField loginPassword;
public TextField testOutput;
@FXML TableView<Employee> employeesTable;
@FXML TableColumn<Employee, String> colFirstName;
@FXML TableColumn<Employee, String> colLastName;
@FXML TableColumn<Employee, String> colEmail;
@FXML Pane myScene;
//public javafx.scene.control.TableView employeesTable;
private ObservableList<Employee> myData;
private MainController MainController;
public void loadEmployeeForm(ActionEvent actionEvent) throws IOException, SQLException, ClassNotFoundException {
myData = FXCollections.observableArrayList(DBCON.getEmployees());
System.out.println(myData.size());
Parent root = FXMLLoader.load(getClass().getResource("frmEmployees.fxml"));
Scene myScene = new Scene( root );
sample.MainController.setScene(myScene);
colFirstName.setCellValueFactory(new PropertyValueFactory<Employee, String>("firstName"));
colLastName.setCellValueFactory(new PropertyValueFactory<Employee, String>("lastName"));
colEmail.setCellValueFactory(new PropertyValueFactory<Employee, String>("email"));
employeesTable.setItems(null);
employeesTable.setItems(myData);
employeesTable.setVisible(true);
}
當我將colFirstName設置為屬性值工廠時,我得到一個空指針異常,這使我認為我尚未在某處進行初始化,但是我對如何添加它一無所知。
如果我添加如下行: TableColumn colFirstName =新的TableColumn(“ firstName”);
對於我的每個列和表名,它都是這樣工作的(即,它不會向我拋出錯誤消息),但是然后我沒有將任何數據加載到tableview中,因為我認為那是我創建的新tableView不使用從FXML生成的?
我覺得這將非常簡單,但是正如我所說的,我是一個笨拙的菜鳥,任何要點都必須承擔。
謝謝馬克
更新1;
從myMain.fxml上的按鈕調用用於加載員工表單的方法。
<GridPane alignment="CENTER" hgap="10" prefHeight="300" prefWidth="300" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8"
fx:controller="sample.TestController" stylesheets="/sample/myFirst.css">
<children>
<Button onAction="#login" text="Login" GridPane.halignment="CENTER" GridPane.rowIndex="5" GridPane.valignment="CENTER" />
<Button text="GoEmployees" onAction="#loadEmployeeForm" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER" />
<Label fx:id="login" GridPane.rowIndex="1" />
<Label text="UserName" GridPane.columnIndex="0" GridPane.rowIndex="1" />
<Label text="Password" GridPane.columnIndex="0" GridPane.rowIndex="2" />
<TextField fx:id="loginUserName" GridPane.rowIndex="1" GridPane.columnIndex="1" />
<PasswordField fx:id="loginPassword" GridPane.rowIndex="2" GridPane.columnIndex="1" blendMode="OVERLAY" />
<TextField fx:id="testOutput" GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="3" />
</children>
<columnConstraints>
<ColumnConstraints prefWidth="125.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints prefHeight="50.0" />
</rowConstraints>
<padding>
<Insets bottom="10.0" left="9.0" right="10.0" top="10.0" />
</padding>
</GridPane>
讓我的testController控制兩個不同的FXML是一個問題/行不通嗎?
當FXMLLoader
嘗試加載fxml文件時,它將在fxml文件中創建使用fx:controller
定義的控制器類的新實例。 然后,它在fxml文件中使用fx:id
組件創建並映射@FXML帶注釋的字段。 最后,它調用控制器的initialize()
方法。 您可以在fxmlloader.load()之后使用fxmlloader.getController()獲取實例化的控制器。
根據此基本工作流程,代碼中的陷阱是:
myMain.fxml的控制器是TestController,但myMain.fxml不包含帶有fx:id colFirstName等的TableColumns。因此,在加載myMain.fxml時,這些字段為null。 結果,嘗試使用這些字段時,loadEmployeeForm()中將存在NPE。
將TableView和TableColumns移動到frmEmployees.fxml的控制器,並在此控制器的initialize()方法中對其進行配置(setCellValueFactory,初始數據等)。
您永遠不會使用Employee(String, String, String)
構造函數。 此構造函數初始化firstName
, lastName
和email
。 否則,您的引用將毫無意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.