如何在JavaFx中创建通用的TableView?
我正在为我的项目构建一个GUI,我需要在表中显示来自各种类型的数据结构的信息:ArrayList、HashMap、TreeSet 基本上,我需要在我的视图包中显示我在模型包中得到的查询方法的信息 现在,我的实现为我使用每次声明TableView时指定的对象类型构建的每个表都包含一个控制器 我想知道是否有一种方法可以创建一个类,它的构造函数将为我构建所需的表(具有此对象所需的任意多个列)。某种类型的通用表生成器,可以读取对象并找出需要表示的列数。例如:与具有6个字段/列的成员对象相比,显示具有4个字段/列的保留对象。根据它将得到的数据结构。因此,我将能够创建这个类的一个实例,实例化一个我需要的表,并在屏幕上显示它 我还需要一种能够从场景生成器控制它的方法,因为这是我以图形方式构建GUI的主要工具 我在这里添加了一个表代码,希望有人能帮我完成这项繁琐的任务:) 然后,它调用该类,在该类中选择成员,然后启动上面的表代码,小窗口代码为:如何在JavaFx中创建通用的TableView?,java,user-interface,data-structures,javafx,Java,User Interface,Data Structures,Javafx,我正在为我的项目构建一个GUI,我需要在表中显示来自各种类型的数据结构的信息:ArrayList、HashMap、TreeSet 基本上,我需要在我的视图包中显示我在模型包中得到的查询方法的信息 现在,我的实现为我使用每次声明TableView时指定的对象类型构建的每个表都包含一个控制器 我想知道是否有一种方法可以创建一个类,它的构造函数将为我构建所需的表(具有此对象所需的任意多个列)。某种类型的通用表生成器,可以读取对象并找出需要表示的列数。例如:与具有6个字段/列的成员对象相比,显示具有4个
package view;
import java.util.ArrayList;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class ChooseAClientForReservationsQueryWindowController {
private String memIdChosen;
@FXML
private ComboBox<String> MemberIds;
public void initialize() {
}
@FXML
Button CloseBtn = new Button();//close button inside AddLocation window
@FXML
public void handleCloseButtonAction(ActionEvent event) {//for all close Button's this method is called
Stage stage = (Stage) CloseBtn.getScene().getWindow();
stage.close();
}
@FXML
Button EraseBtn = new Button();//erase Button
@FXML
public void handleEraseButtonAction(ActionEvent event) {//erase Button code
MemberIds.setValue(null);
}
@FXML
Button GoBtn = new Button();//Go button
@FXML
public void handleGoBtn(ActionEvent event) throws Exception {//for all close Button's this method is called
try{
if(MemberIds.getValue()==null)
throw new Exception();
FXMLLoader fxmlLoader = new FXMLLoader(QRYClientReservationsTableController.class.getResource("/view/QRYClientReservationsTableController.fxml"));
AnchorPane qryShowAllReservationsForMember = (AnchorPane) fxmlLoader.load();
QRYClientReservationsTableController controller = fxmlLoader.getController();
controller.setQRYClientReservationsTableController(memIdChosen);
Stage stage = new Stage();
stage.setTitle("Query - Show all reservations for member Id: "+memIdChosen+".");
stage.setScene(new Scene(qryShowAllReservationsForMember));
stage.show();
handleCloseButtonAction(event);
}
catch (Exception e){
Alert alert = new Alert(AlertType.WARNING,"One of the fields is empty", ButtonType.OK);
alert.setTitle("One of the fields is empty");
alert.setHeaderText("One of the fields is empty");
alert.setContentText("Please fill the empty fields");
alert.showAndWait();
}
}
/**
* The constructor.
* The constructor is called before the initialize() method.
*/
public ChooseAClientForReservationsQueryWindowController() {
}
public void setAddTripToReservationClass(){
ArrayList<String> memIds = new ArrayList<String>();
memIds.addAll(ViewLogic.controlLogic.getMembers().keySet());
MemberIds.getItems().setAll(memIds);
MemberIds.valueProperty().addListener(new ChangeListener<String>(){
@Override
public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
memIdChosen=arg2;
}
});
}
}
包视图;
导入java.util.ArrayList;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.event.ActionEvent;
导入javafx.fxml.fxml;
导入javafx.fxml.fxmloader;
导入javafx.scene.scene;
导入javafx.scene.control.Alert;
导入javafx.scene.control.Button;
导入javafx.scene.control.ButtonType;
导入javafx.scene.control.ComboBox;
导入javafx.scene.control.Alert.AlertType;
导入javafx.scene.layout.ancorpane;
导入javafx.stage.stage;
公共类ChooseClientForReservationSqueryWindowController{
私有字符串memidselected;
@FXML
私有组合框成员ID;
公共无效初始化(){
}
@FXML
Button CloseBtn=新建按钮();//关闭AddLocation窗口内的按钮
@FXML
public void handleCloseButtonAction(ActionEvent事件){//对于所有关闭按钮,调用此方法
Stage Stage=(Stage)CloseBtn.getScene().getWindow();
stage.close();
}
@FXML
按钮擦除Btn=新建按钮();//擦除按钮
@FXML
public void handleEraseButtonAction(ActionEvent事件){//擦除按钮代码
MemberIds.setValue(null);
}
@FXML
Button GoBtn=新建按钮();//转到按钮
@FXML
public void handleGoBtn(ActionEvent事件)为所有关闭按钮的
试一试{
if(memberId.getValue()==null)
抛出新异常();
FXMLLoader FXMLLoader=新的FXMLLoader(QRYClientReservationsTableController.class.getResource(“/view/QRYClientReservationsTableController.fxml”);
AnchorPane qryShowallReservationsformber=(AnchorPane)fxmlLoader.load();
QRYClientReservationsTableController控制器=fxmlLoader.getController();
controller.setQRYClientReservationsTableController(memidSelected);
阶段=新阶段();
stage.setTitle(“查询-显示成员Id的所有保留:“+memidselected+”);
stage.setScene(新场景(qryshowallreservationsformber));
stage.show();
handleCloseButtonAction(事件);
}
捕获(例外e){
Alert Alert=新警报(AlertType.WARNING,“其中一个字段为空”,ButtonType.OK);
alert.setTitle(“其中一个字段为空”);
alert.setHeaderText(“其中一个字段为空”);
alert.setContentText(“请填写空字段”);
alert.showAndWait();
}
}
/**
*构造器。
*在initialize()方法之前调用构造函数。
*/
public ChooseClientForReservationSqueryWindowController(){
}
public void setAddTripStoreServationClass(){
ArrayList memIds=新的ArrayList();
memIds.addAll(ViewLogic.controlLogic.getMembers().keySet());
MemberIds.getItems().setAll(memIds);
MemberId.valueProperty().addListener(新的ChangeListener()){
@凌驾
public void changed(ObservalEvalue您可以通过反射来执行此操作。这将为每个SimpleStringProperty
字段创建一个可编辑的字符串列。这样做意味着您无法在FXML中添加它们
for (Field f : TableInfo.class.getDeclaredFields()) {
if (f.getType().equals(SimpleStringProperty.class)){
TableColumn<TableInfo, String> tc = new TableColumn<>(f.getName());
tv.getColumns().add(tc);
tc.setCellValueFactory(new PropertyValueFactory<>(f.getName()));
tc.setCellFactory(TextFieldTableCell.forTableColumn());
}//else if more field types...
}
for(字段f:TableInfo.class.getDeclaredFields()){
if(f.getType().equals(SimpleStringProperty.class)){
TableColumn tc=新的TableColumn(f.getName());
tv.getColumns().add(tc);
setCellValueFactory(新的PropertyValueFactory(f.getName());
tc.setCellFactory(TextFieldTableCell.forTableColumn());
}//否则,如果有更多字段类型。。。
}
我偶然发现了类似的问题,并创建了一个简单的库来解决它
它使用您的模型类来构建表示给定类的字段的TableView
我有样品和说明书
如果您有任何建议,我希望听听您的意见。应该是这样做的。有一些教程,但我还没有尝试过。我在那里没有看到任何教程……我只是想找到一种方法,以一种通用的方式创建javafx表,就像您在swing中扩展AbstractTableModel时所做的那样……对实现有帮助吗如果能用外汇兑换,我将不胜感激。是的,但我需要这样做,这样我才能交易
package view;
import java.util.ArrayList;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class ChooseAClientForReservationsQueryWindowController {
private String memIdChosen;
@FXML
private ComboBox<String> MemberIds;
public void initialize() {
}
@FXML
Button CloseBtn = new Button();//close button inside AddLocation window
@FXML
public void handleCloseButtonAction(ActionEvent event) {//for all close Button's this method is called
Stage stage = (Stage) CloseBtn.getScene().getWindow();
stage.close();
}
@FXML
Button EraseBtn = new Button();//erase Button
@FXML
public void handleEraseButtonAction(ActionEvent event) {//erase Button code
MemberIds.setValue(null);
}
@FXML
Button GoBtn = new Button();//Go button
@FXML
public void handleGoBtn(ActionEvent event) throws Exception {//for all close Button's this method is called
try{
if(MemberIds.getValue()==null)
throw new Exception();
FXMLLoader fxmlLoader = new FXMLLoader(QRYClientReservationsTableController.class.getResource("/view/QRYClientReservationsTableController.fxml"));
AnchorPane qryShowAllReservationsForMember = (AnchorPane) fxmlLoader.load();
QRYClientReservationsTableController controller = fxmlLoader.getController();
controller.setQRYClientReservationsTableController(memIdChosen);
Stage stage = new Stage();
stage.setTitle("Query - Show all reservations for member Id: "+memIdChosen+".");
stage.setScene(new Scene(qryShowAllReservationsForMember));
stage.show();
handleCloseButtonAction(event);
}
catch (Exception e){
Alert alert = new Alert(AlertType.WARNING,"One of the fields is empty", ButtonType.OK);
alert.setTitle("One of the fields is empty");
alert.setHeaderText("One of the fields is empty");
alert.setContentText("Please fill the empty fields");
alert.showAndWait();
}
}
/**
* The constructor.
* The constructor is called before the initialize() method.
*/
public ChooseAClientForReservationsQueryWindowController() {
}
public void setAddTripToReservationClass(){
ArrayList<String> memIds = new ArrayList<String>();
memIds.addAll(ViewLogic.controlLogic.getMembers().keySet());
MemberIds.getItems().setAll(memIds);
MemberIds.valueProperty().addListener(new ChangeListener<String>(){
@Override
public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
memIdChosen=arg2;
}
});
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1450.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.QRYClientReservationsTableController">
<children>
<ButtonBar layoutX="44.0" layoutY="541.0" prefHeight="40.0" prefWidth="700.0" AnchorPane.bottomAnchor="19.0">
<buttons>
<Button fx:id="CloseBtn" mnemonicParsing="false" onAction="#handleCloseButtonAction" prefHeight="31.0" prefWidth="212.0" text="Close" />
</buttons>
</ButtonBar>
<TableView fx:id="ReservationforClient" layoutX="5.0" layoutY="55.0" prefHeight="486.0" prefWidth="893.0" AnchorPane.bottomAnchor="59.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="55.0">
<columns>
<TableColumn fx:id="ReservationIdColumn" prefWidth="121.0" text="Reservation Id" />
<TableColumn fx:id="LocationIdColumn" prefWidth="128.0" text="Location Id" />
<TableColumn fx:id="AddressColumn" prefWidth="276.0" text="Address" />
<TableColumn fx:id="DescriptionColumn" prefWidth="382.0" text="Description" />
<TableColumn fx:id="StartTimeAndDateColumn" prefWidth="282.0" text="Start Time and Date" />
<TableColumn fx:id="EndTimeAndDateColumn" prefWidth="252.0" text="EndTime and Date" />
</columns>
</TableView>
<Label layoutX="394.0" layoutY="8.0" prefHeight="40.0" prefWidth="350.0" text="Reservations for Client Id:" AnchorPane.leftAnchor="394.0" AnchorPane.rightAnchor="706.0" AnchorPane.topAnchor="8.0">
<font>
<Font name="System Bold" size="28.0" />
</font>
</Label>
<TextField fx:id="memId" editable="false" layoutX="738.0" layoutY="10.0" prefHeight="40.0" prefWidth="191.0" />
</children>
</AnchorPane>
for (Field f : TableInfo.class.getDeclaredFields()) {
if (f.getType().equals(SimpleStringProperty.class)){
TableColumn<TableInfo, String> tc = new TableColumn<>(f.getName());
tv.getColumns().add(tc);
tc.setCellValueFactory(new PropertyValueFactory<>(f.getName()));
tc.setCellFactory(TextFieldTableCell.forTableColumn());
}//else if more field types...
}