[英]Initializing TableView with columns inside fx:root using FXML
I have a custom class inside a fxml file called TablePatientView
.我在名为
TablePatientView
。 I use it like <TablePatientView fx:id="tablePatientView" layoutX="20.0" layoutY="45.0" prefHeight="409.0" prefWidth="363.0" />
and it works almost fine.我像
<TablePatientView fx:id="tablePatientView" layoutX="20.0" layoutY="45.0" prefHeight="409.0" prefWidth="363.0" />
一样使用它,它几乎可以正常工作。 The fx:root
looks like the following: fx:root
如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<fx:root type="javafx.scene.control.TableView" xmlns:fx="http://javafx.com/fxml">
<TableView>
<columns>
<TableColumn fx:id="patId" prefWidth="101.0" text="Patient-ID" />
<TableColumn fx:id="patVorname" prefWidth="69.0" text="Vorname" />
<TableColumn fx:id="patNachname" prefWidth="98.0" text="Nachname" />
<TableColumn fx:id="patGebdat" prefWidth="96.0" text="Geburtsdatum" />
</columns>
</TableView>
</fx:root>
with the following class与以下 class
public class TablePatientView extends TableView<TablePatient> {
private Parent root;
@FXML
private TableColumn<TablePatient,String> patId;
@FXML
private TableColumn<TablePatient,String> patVorname;
@FXML
private TableColumn<TablePatient,String> patNachname;
@FXML
private TableColumn<TablePatient, LocalDate> patGebdat;
public TablePatientView() {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/fxml/TablePatientView.fxml"));
loader.setController(this);
loader.setRoot(this);
try {
root = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
setCellValueFactories();
// getColumns().addAll(patId, patVorname, patNachname, patGebdat); works, but not with plain fxml
}
private void setCellValueFactories() {
patId.setCellValueFactory(param -> param.getValue().idProperty().asString());
patVorname.setCellValueFactory(param -> param.getValue().vornameProperty());
patNachname.setCellValueFactory(param -> param.getValue().nachnameProperty());
patGebdat.setCellValueFactory(param -> param.getValue().gebDatProperty());
}
}
The columns are correctly initialized, but for some reason not added as columns to the TableView.列已正确初始化,但由于某种原因未作为列添加到 TableView。 I know I can do it via java code (see the commented line in the code above) but I would like to know why this doesn't work with just fxml.
我知道我可以通过 java 代码来做到这一点(参见上面代码中的注释行),但我想知道为什么这不适用于 fxml。 Using the <TableView> directly inside fxml without a custom class and root works just fine.
在没有自定义 class 和 root 的情况下直接在 fxml 中使用 <TableView> 就可以了。
The <fx:root type="TableView">
references a TableView
which is supplied via the call to loader.setRoot(this)
. <fx:root type="TableView">
引用通过调用loader.setRoot(this)
提供的TableView
。
You have defined another TableView
inside that TableView
1 .您已经在该
TableView
1中定义了另一个TableView
。 The columns are added to that TableView
, not the one referenced by <fx:root>
.这些列被添加到该
TableView
,而不是<fx:root>
引用的列。
The correct FXML is正确的 FXML 是
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<fx:root type="javafx.scene.control.TableView" xmlns:fx="http://javafx.com/fxml">
<columns>
<TableColumn fx:id="patId" prefWidth="101.0" text="Patient-ID" />
<TableColumn fx:id="patVorname" prefWidth="69.0" text="Vorname" />
<TableColumn fx:id="patNachname" prefWidth="98.0" text="Nachname" />
<TableColumn fx:id="patGebdat" prefWidth="96.0" text="Geburtsdatum" />
</columns>
</fx:root>
I'm not a big fan of subclassing control classes, such as TableView
.我不喜欢继承控件类,例如
TableView
。 The reason is that you're not really adding functionality to the TableView
, you're just essentially setting properties on it, and this is not a good use of inheritance.原因是您并没有真正向
TableView
添加功能,您只是在本质上设置属性,这不是 inheritance 的好用处。
Consider instead using a creational pattern.考虑改为使用创建模式。 A simple static factory method works well, and plays nicely with FXML via the
fx:factory
attribute.一个简单的 static 工厂方法运行良好,并通过
fx:factory
属性与 FXML 很好地配合使用。
TablePatientView.fxml: TablePatientView.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<TableView xmlns:fx="http://javafx.com/fxml" fx:controller="com.jamesd.examples.TablePatientController">
<columns>
<TableColumn fx:id="patId" prefWidth="101.0" text="Patient-ID" />
<TableColumn fx:id="patVorname" prefWidth="69.0" text="Vorname" />
<TableColumn fx:id="patNachname" prefWidth="98.0" text="Nachname" />
<TableColumn fx:id="patGebdat" prefWidth="96.0" text="Geburtsdatum" />
</columns>
</TableView>
TablePatientController.java: TablePatientController.java:
public class TablePatientContorller {
@FXML
private TableColumn<TablePatient,String> patId;
@FXML
private TableColumn<TablePatient,String> patVorname;
@FXML
private TableColumn<TablePatient,String> patNachname;
@FXML
private TableColumn<TablePatient, LocalDate> patGebdat;
@FXML
private void initialize() {
setCellValueFactories();
}
private void setCellValueFactories() {
patId.setCellValueFactory(param -> param.getValue().idProperty().asString());
patVorname.setCellValueFactory(param -> param.getValue().vornameProperty());
patNachname.setCellValueFactory(param -> param.getValue().nachnameProperty());
patGebdat.setCellValueFactory(param -> param.getValue().gebDatProperty());
}
}
Tables.java:表.java:
public class Tables {
public static TableView<TablePatient> tablePatientView() throws Exception {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/fxml/TablePatientView.fxml"));
return loader.load();
}
}
And then you can use this in FXML with然后你可以在 FXML 中使用它
<Tables fx:factory="tablePatientView" />
TableView
is added to the original TableView
's items
list, since the @DefaultProperty
of a TableView
is that list.TableView
被添加到原始TableView
的items
列表中,因为TableView
的@DefaultProperty
就是那个列表。 So eventually the table view would attempt to display that as a row in the table.ClassCastException
at some point, but possibly it gets silently squashed since FXML can't specify generic types.ClassCastException
,但由于 FXML 无法指定泛型类型,它可能会被静默地压扁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.