添加 rowfactory 后,Javafx tableviews 不显示
Javafx tableviews don't display after adding rowfactory
我正在尝试设置一个 netbeans/javafx 程序来显示宠物对象列表,并为每一行提供一个 onclick 侦听器。
我在 fxml 中有以下内容:
MyTables.fxml
<VBox alignment="CENTER" layoutX="11.0" layoutY="12.0" prefWidth="345.0">
<children>
<TableView id="Table1" fx:id="Table1" styleClass="mytable"/>
<TableView id="Table2" fx:id="Table2" styleClass="mytable"/>
<TableView id="Table3" fx:id="Table3" styleClass="mytable"/>
<TableView id="Table4" fx:id="Table4" styleClass="mytable"/>
</children>
</VBox>
我使用的是 netbeans,所以我为加载 FXML 的视图设置了一个 topComponent,后者又加载了一个控制器 class。
在我的控制器 class 中,我使用以下代码将内容添加到 table。目的是让每个 table 有 3 行,分别对应所含 Pet 对象的 ID、名称和所有者。
MyTablesController.java
public class MyTablesController implements Initializable {
@FXML
private TableView<Pet> Table1;
@FXML
private TableView<Pet> Table2;
@FXML
private TableView<Pet> Table3;
@FXML
private TableView<Pet> Table4;
private TableView<Pet>[] allTables;
public MyTablesController() {
allTables = new TableView[4];
allTables[0] = Table1;
allTables[1] = Table2;
allTables[2] = Table3;
allTables[3] = Table4;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
for(TableView<Pet> table : allTables) {
table.getColumns().add(createCol("ID", Pet::idProperty, 100));
table.getColumns().add(createCol("Name", Pet::nameProperty, 140));
table.getColumns().add(createCol("Owner", Pet::ownerProperty, 100));
table.getItems().addAll(
new Pet("1234", "spot", "joe"),
new Pet("5432", "snowball", "bill"),
new Pet("7612", "snoopy", "frank")
);
}
setupTableRowDragEvents();
}
private TableColumn<Pet, String> createCol(String title,
Function<Pet, ObservableValue<String>> mapper, double size) {
TableColumn<Pet, String> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> mapper.apply(cellData.getValue()));
col.setPrefWidth(size);
return col ;
}
private void setupTableRowDragEvents() {
for (TableView<Pet> table : allTables) {
table.setRowFactory(tv -> {
TableRow<Pet> row = new TableRow<>();
row.setOnMouseClicked(event -> {
System.out.println("I CLICKED ON " + row.getItem().getName()");
});
return row;
});
}
}
}
最后,这里是 Pet 对象:
Pet.java
public final class Pet {
public final StringProperty id = new SimpleStringProperty(this, "id");
public final StringProperty name = new SimpleStringProperty(this, "name");
public final StringProperty owner = new SimpleStringProperty(this, "owner");
public Pet() {}
public Pet(String id, String name, String owner) {
this.id.set(id);
this.name.set(name);
this.owner.set(owner);
}
public String getId() {
return id.get();
}
public void setId(String id) {
this.id.set(id);
}
public StringProperty idProperty() {
return id;
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
public String getOwner() {
return owner.get();
}
public void setOwner(String owner) {
this.owner.set(owner);
}
public StringProperty ownerProperty() {
return owner;
}
}
这是我的问题。
如果我将 MyTablesController.initialize 留空,则 4 个图表显示得很好。只有当我添加其余代码时(setCols 调用和 setupTableRowDragEvents() 调用)...
如果 initialize() 中的其中一个或两个存在,则不会显示图表。除了 window 完全为空且图表未显示之外,我没有收到任何错误消息或奇怪的行为。
我的代码基于 sort tableview with drag and drop (rows) 。与此相比,我无法弄清楚我在哪里搞砸了。这个答案是不是错了,没有人费心去检查它?
我做错了什么?
在填充数组时,table 视图引用都是 null
,因此您用空引用填充数组。那么在遍历数组的时候,第一次调用table.getColumns()
就会出现空指针异常。将代码从控制器构造函数移动到 initialize()
:
的开头
public class MyTablesController implements Initializable {
@FXML
private TableView<Pet> Table1;
@FXML
private TableView<Pet> Table2;
@FXML
private TableView<Pet> Table3;
@FXML
private TableView<Pet> Table4;
private TableView<Pet>[] allTables;
@Override
public void initialize(URL location, ResourceBundle resources) {
allTables = new TableView[4];
allTables[0] = Table1;
allTables[1] = Table2;
allTables[2] = Table3;
allTables[3] = Table4;
for(TableView<Pet> table : allTables) {
table.getColumns().add(createCol("ID", Pet::idProperty, 100));
table.getColumns().add(createCol("Name", Pet::nameProperty, 140));
table.getColumns().add(createCol("Owner", Pet::ownerProperty, 100));
table.getItems().addAll(
new Pet("1234", "spot", "joe"),
new Pet("5432", "snowball", "bill"),
new Pet("7612", "snoopy", "frank")
);
}
setupTableRowDragEvents();
}
// ...
}
我正在尝试设置一个 netbeans/javafx 程序来显示宠物对象列表,并为每一行提供一个 onclick 侦听器。
我在 fxml 中有以下内容:
MyTables.fxml
<VBox alignment="CENTER" layoutX="11.0" layoutY="12.0" prefWidth="345.0">
<children>
<TableView id="Table1" fx:id="Table1" styleClass="mytable"/>
<TableView id="Table2" fx:id="Table2" styleClass="mytable"/>
<TableView id="Table3" fx:id="Table3" styleClass="mytable"/>
<TableView id="Table4" fx:id="Table4" styleClass="mytable"/>
</children>
</VBox>
我使用的是 netbeans,所以我为加载 FXML 的视图设置了一个 topComponent,后者又加载了一个控制器 class。
在我的控制器 class 中,我使用以下代码将内容添加到 table。目的是让每个 table 有 3 行,分别对应所含 Pet 对象的 ID、名称和所有者。
MyTablesController.java
public class MyTablesController implements Initializable {
@FXML
private TableView<Pet> Table1;
@FXML
private TableView<Pet> Table2;
@FXML
private TableView<Pet> Table3;
@FXML
private TableView<Pet> Table4;
private TableView<Pet>[] allTables;
public MyTablesController() {
allTables = new TableView[4];
allTables[0] = Table1;
allTables[1] = Table2;
allTables[2] = Table3;
allTables[3] = Table4;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
for(TableView<Pet> table : allTables) {
table.getColumns().add(createCol("ID", Pet::idProperty, 100));
table.getColumns().add(createCol("Name", Pet::nameProperty, 140));
table.getColumns().add(createCol("Owner", Pet::ownerProperty, 100));
table.getItems().addAll(
new Pet("1234", "spot", "joe"),
new Pet("5432", "snowball", "bill"),
new Pet("7612", "snoopy", "frank")
);
}
setupTableRowDragEvents();
}
private TableColumn<Pet, String> createCol(String title,
Function<Pet, ObservableValue<String>> mapper, double size) {
TableColumn<Pet, String> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> mapper.apply(cellData.getValue()));
col.setPrefWidth(size);
return col ;
}
private void setupTableRowDragEvents() {
for (TableView<Pet> table : allTables) {
table.setRowFactory(tv -> {
TableRow<Pet> row = new TableRow<>();
row.setOnMouseClicked(event -> {
System.out.println("I CLICKED ON " + row.getItem().getName()");
});
return row;
});
}
}
}
最后,这里是 Pet 对象:
Pet.java
public final class Pet {
public final StringProperty id = new SimpleStringProperty(this, "id");
public final StringProperty name = new SimpleStringProperty(this, "name");
public final StringProperty owner = new SimpleStringProperty(this, "owner");
public Pet() {}
public Pet(String id, String name, String owner) {
this.id.set(id);
this.name.set(name);
this.owner.set(owner);
}
public String getId() {
return id.get();
}
public void setId(String id) {
this.id.set(id);
}
public StringProperty idProperty() {
return id;
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty nameProperty() {
return name;
}
public String getOwner() {
return owner.get();
}
public void setOwner(String owner) {
this.owner.set(owner);
}
public StringProperty ownerProperty() {
return owner;
}
}
这是我的问题。
如果我将 MyTablesController.initialize 留空,则 4 个图表显示得很好。只有当我添加其余代码时(setCols 调用和 setupTableRowDragEvents() 调用)...
如果 initialize() 中的其中一个或两个存在,则不会显示图表。除了 window 完全为空且图表未显示之外,我没有收到任何错误消息或奇怪的行为。
我的代码基于 sort tableview with drag and drop (rows) 。与此相比,我无法弄清楚我在哪里搞砸了。这个答案是不是错了,没有人费心去检查它?
我做错了什么?
在填充数组时,table 视图引用都是 null
,因此您用空引用填充数组。那么在遍历数组的时候,第一次调用table.getColumns()
就会出现空指针异常。将代码从控制器构造函数移动到 initialize()
:
public class MyTablesController implements Initializable {
@FXML
private TableView<Pet> Table1;
@FXML
private TableView<Pet> Table2;
@FXML
private TableView<Pet> Table3;
@FXML
private TableView<Pet> Table4;
private TableView<Pet>[] allTables;
@Override
public void initialize(URL location, ResourceBundle resources) {
allTables = new TableView[4];
allTables[0] = Table1;
allTables[1] = Table2;
allTables[2] = Table3;
allTables[3] = Table4;
for(TableView<Pet> table : allTables) {
table.getColumns().add(createCol("ID", Pet::idProperty, 100));
table.getColumns().add(createCol("Name", Pet::nameProperty, 140));
table.getColumns().add(createCol("Owner", Pet::ownerProperty, 100));
table.getItems().addAll(
new Pet("1234", "spot", "joe"),
new Pet("5432", "snowball", "bill"),
new Pet("7612", "snoopy", "frank")
);
}
setupTableRowDragEvents();
}
// ...
}