首页 文章

JavaFX,为什么TableColumn为null?

提问于
浏览
0

正如您将看到的,当谈到Java和Javafx时,我是一个巨大的菜鸟 . 我花了很多时间阅读(各种论坛帖子和tuts),并试图找出自己在哪里得到这个问题,但我已经到了这一点,我发布了一些了解他们业务的人的反馈 .

在回复时,请你花点时间解释为什么有些东西不起作用以及一些一般性的指示?这是我到目前为止(我的FXML和我的两个 class )任何指针都会很棒!

我的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中,因为我认为这是我创建一个新的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

    FXMLLoader 尝试加载fxml文件时,它将创建在fxml文件中使用 fx:controller 定义的控制器类的新实例 . 然后它 creates 并使用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

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

相关问题