繁体   English   中英

JavaFX,为什么TableColumn为null?

[英]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)构造函数。 此构造函数初始化firstNamelastNameemail 否则,您的引用将毫无意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM