JavaFX,为什么TableColumn为null?

时间:2015-04-06 00:22:20

标签: javafx javafx-2 tableview

在Java和Javafx方面,你会看到我是一个巨大的菜鸟。我花了很多时间阅读(各种论坛帖子和tuts)并试图弄清楚自己在哪里得到这个问题,但我已经找到了从知道他们业务的人发布反馈的点。 / p>

在回复时,请你花点时间解释为什么有些东西不起作用以及一些一般性的指示?这是我到目前为止(我的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>

现在是我的员工班;

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设置为属性值factory时,我得到一个空指针异常,这让我觉得我没有在某个地方初始化某些内容,但我完全不知道如何添加它。

如果我添加如下行; TableColumn colFirstName = new TableColumn(“firstName”);

对于我的每一列及其工作的表名(即它不会向我发送大量错误消息),但是我没有将任何数据加载到tableview中,因为我认为这是我创建的new 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是一个问题/一个不行吗?

2 个答案:

答案 0 :(得分:1)

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时,这些字段为空。因此,在尝试使用这些字段时,loadEmployeeForm()中会有NPE。

将TableView和TableColumns移动到frmEmployees.fxml的控制器,并在此控制器的initialize()方法中配置它们(setCellValueFactory,初始数据等)。

答案 1 :(得分:0)

您永远不会使用Employee(String, String, String)构造函数。此构造函数初始化firstNamelastNameemail。否则,您的引用将指向任何内容。