在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是一个问题/一个不行吗?
答案 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)
构造函数。此构造函数初始化firstName
,lastName
和email
。否则,您的引用将指向任何内容。