如何在JavaFx中创建一个通用的TableView? [英] How do I create a generic TableView in JavaFx?

查看:243
本文介绍了如何在JavaFx中创建一个通用的TableView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的项目构建一个GUI,我需要显示来自各种数据结构的信息:ArrayList,HashMap,TreeSet在表中。



基本上,我需要显示来自我的查看包中我的模型包中查询方法的信息。



我的实现现在包括一个控制器,用于每个建立的表每次我声明一个TableView时都会指定对象类型。



我想知道是否有一种方法来创建一个类,它的构造函数会建立我需要的表(与这个对象需要的列数)。某种类型的通用表构建器可以读取一个对象,并找出需要表示的列数。例如:将具有4个字段/列的预留对象与具有6个字段/列的Member对象进行比较。根据数据结构将会得到。因此,我将能够创建一个这个类的实例,并实例化一个需要的表,并将其显示在屏幕上。



我还需要一种方法才能控制它从场景构建器,因为这是我图形化构建GUI的主要工具。



我在这里添加一个表格代码,希望有人可以帮助我这个繁琐的任务:)

 包视图; 

import java.util.ArrayList;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import model.Reservation;



public class QRYClientReservationsTableController {

private ObservableList< Reservation> ReservationsData = FXCollections.observableArrayList();


@FXML
private TableView< Reservation>客户预留;
@FXML
private TableColumn< Reservation,String> ReservationIdColumn;
@FXML
private TableColumn< Reservation,String> LocationIdColumn;
@FXML
private TableColumn< Reservation,String>地址栏
@FXML
private TableColumn< Reservation,String>描述柱
@FXML
private TableColumn< Reservation,String> StartTimeAndDateColumn;
@FXML
private TableColumn< Reservation,String> EndTimeAndDateColumn;
@FXML
private TextField memId;


/ **
*构造函数。
*在initialize()方法之前调用构造函数。
* /
public QRYClientReservationsTableController(){

}

/ **
*初始化控制器类。 fxml文件加载完成后,此方法自动调用
*。
* /
@FXML
private void initialize(){
//使用树列初始化Location表。
ReservationIdColumn.setCellValueFactory(cellData - > cellData.getValue()。ReservationIdProperty());
LocationIdColumn.setCellValueFactory(cellData - > cellData.getValue()。LocationIdProperty());
AddressColumn.setCellValueFactory(cellData - > cellData.getValue()。LocationAddressProperty());
DescriptionColumn.setCellValueFactory(cellData - > cellData.getValue()。LocationDescriptionProperty());
StartTimeAndDateColumn.setCellValueFactory(cellData - > cellData.getValue()。StartDateProperty());
EndTimeAndDateColumn.setCellValueFactory(cellData - > cellData.getValue()。EndDateProperty());
}
@FXML
按钮CloseBtn = new Button(); // AddLocation窗口内的关闭按钮
@FXML
public void handleCloseButtonAction(ActionEvent event){//对于所有关闭Button的这种方法称为
Stage stage =(Stage)CloseBtn.getScene()。getWindow();
stage.close();
}
/ **
*由主应用程序调用,以引用自身。
*
* @param Locaion
* /
public void setQRYClientReservationsTableController(String memId){
this.memId.setEditable(true);
this.memId.setText(memId);
this.memId.setEditable(false);
ArrayList< Reservation> reservationsAdd = new ArrayList< Reservation>();
reservationsAdd.addAll(ViewLogic.controlLogic.Q_getAllReservationsForMember(memId));
ReservationsData.addAll(reservationsAdd);
//将可见列表数据添加到表
ReservationforClient.setItems(ReservationsData);
ReservationIdColumn.sortableProperty()。setValue(false);
LocationIdColumn.sortableProperty()。setValue(false);
AddressColumn.sortableProperty()。setValue(false);
DescriptionColumn.sortableProperty()。setValue(false);
StartTimeAndDateColumn.sortableProperty()。setValue(false);
EndTimeAndDateColumn.sortableProperty()。setValue(false);
}
}

下一个代码在我的View视图中软件包,并且此代码传递加载小窗口以选择成员ID的FXML文件,通过此Id,我获得了在上面的代码上构建表的信息。
ViewLogic中此方法的代码如下:

  @FXML 
按钮ShowReservationsForClientBtn = new Button (); / *在查询* /
@FXML
之后按按钮的客户端按钮打开窗口的代码public void pressShowReservationsForClientBtn(ActionEvent event)throws Exception {
try {
FXMLLoader fxmlLoader = new FXMLLoader(ChooseAClientForReservationsQueryWindowController.class.getResource(/ view / ChooseAClientForReservationsQueryWindow.fxml));
AnchorPane chooseMemberIdForQuery =(AnchorPane)fxmlLoader.load();
ChooseAClientForReservationsQueryWindowController controller = fxmlLoader.getController();
controller.setAddTripToReservationClass();
Stage stage = new Stage();
stage.setTitle(请选择会员身份);
stage.setScene(new Scene(chooseMemberIdForQuery));
stage.show();
} catch(Exception e){
e.printStackTrace();
}
}

然后调用此类,您选择您的会员,那么上面的代码表就被启动,迷你窗口代码是:

 包视图; 

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>会员
public void initialize(){
}
@FXML
按钮CloseBtn = new Button(); // AddLocation窗口内的关闭按钮
@FXML
public void handleCloseButtonAction(ActionEvent event){//所有关闭Button的这个方法叫
Stage stage =(Stage)CloseBtn.getScene()。getWindow();
stage.close();
}
@FXML
按钮EraseBtn = new Button(); //擦除按钮
@FXML
public void handleEraseButtonAction(ActionEvent event){//擦除按钮代码
MemberIds.setValue(null);
}
@FXML
按钮GoBtn = new Button(); // Go按钮
@FXML
public void handleGoBtn(ActionEvent event)throws Exception {// for所有关闭Button的这个方法叫做
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(查询 - 显示成员ID的所有保留+ memIdChosen +。);
stage.setScene(new Scene(qryShowAllReservationsForMember));
stage.show();
handleCloseButtonAction(event);
}
catch(Exception e){
Alert alert = new Alert(AlertType.WARNING,其中一个字段为空,ButtonType.OK);
alert.setTitle(其中一个字段为空);
alert.setHeaderText(其中一个字段为空);
alert.setContentText(请填空字段);
alert.showAndWait();
}
}
/ **
*构造函数。
*在initialize()方法之前调用构造函数。
* /
public SelectAClientForReservationsQueryWindowController(){

}

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;

}
});
}
}

这是上面表格代码的相关FXML文件,它有助于:

 <?xml version =1.0encoding =UTF-8?> 

<?import javafx.scene.text。*?>
<?import javafx.scene.control。*?>
<?import java.lang。*?>
<?import javafx.scene.layout。*?>
<?import javafx.scene.layout.AnchorPane?>

< AnchorPane maxHeight = - InfinitymaxWidth = - InfinityminHeight = - InfinityminWidth = - InfinityprefHeight =600.0prefWidth =1450.0xmlns =http: //javafx.com/javafx/8.0.40xmlns:fx =http://javafx.com/fxml/1fx:controller =view.QRYClientReservationsTableController>
< children>
< ButtonBar layoutX =44.0layoutY =541.0prefHeight =40.0prefWidth =700.0AnchorPane.bottomAnchor =19.0>
< buttons>
< Button fx:id =CloseBtnmnemonicParsing =falseonAction =#handleCloseButtonActionprefHeight =31.0prefWidth =212.0text =Close/>
< / buttons>
< / ButtonBar>
< TableView fx:id =ReservationforClientlayoutX =5.0layoutY =55.0prefHeight =486.0prefWidth =893.0AnchorPane.bottomAnchor =59.0AnchorPane.leftAnchor =5.0AnchorPane。 rightAnchor =2.0AnchorPane.topAnchor =55.0>
< columns>
< TableColumn fx:id =ReservationIdColumnprefWidth =121.0text =预约ID/>
< TableColumn fx:id =LocationIdColumnprefWidth =128.0text =Location Id/>
< TableColumn fx:id =AddressColumnprefWidth =276.0text =Address/>
< TableColumn fx:id =DescriptionColumnprefWidth =382.0text =Description/>
< TableColumn fx:id =StartTimeAndDateColumnprefWidth =282.0text =开始时间和日期/>
< TableColumn fx:id =EndTimeAndDateColumnprefWidth =252.0text =EndTime and Date/>
< / columns>
< / TableView>
< Label layoutX =394.0layoutY =8.0prefHeight =40.0prefWidth =350.0text =客户端ID的预约AnchorPane.leftAnchor =394.0AnchorPane.rightAnchor =706.0 AnchorPane.topAnchor =8.0>
< font>
< Font name =System Boldsize =28.0/>
< / font>
< / Label>
< TextField fx:id =memIdeditable =falselayoutX =738.0layoutY =10.0prefHeight =40.0prefWidth =191.0/>
< / children>
< / AnchorPane>

谢谢



Tom

解决方案

我偶然遇到类似的问题,并创建了一个解决这个问题的简单库。



它使用您的模型类来构建表示给定类的字段的TableView。



我有在GitHub上发布,并附有示例和说明。



如果您有任何建议,我想听听你的意见。


I am building a GUI for my project and I need to show information that is coming from various types of data structures: ArrayList,HashMap,TreeSet in a table.

Basically I need to show information from query methods I got in my model package in my view package.

My implementation right now includes a controller for each and every table I build with the object type specified every time I declare a TableView.

I wonder if there is a way to create a class that its constructor will build me the table I need(with as many columns this object require). some sort of a generic table builder that can read an object and find out how many columns it needs to be represented. for example: to present Reservation Object that has 4 fields/columns compare to Member object that has 6 fields/columns. according to the data-structure it will get. therefore I will be able to create an instance of this class and instantiate a table of my need and show it on the screen.

I also need a way to be able to control it from the scene builder as this is my main tool for building the GUI graphically.

I am adding one of my table codes here and I hope someone can help me with this tedious task :)

    package view;

import java.util.ArrayList;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import model.Reservation;



public class QRYClientReservationsTableController {

    private ObservableList<Reservation> ReservationsData = FXCollections.observableArrayList();


    @FXML
    private TableView<Reservation> ReservationforClient;
    @FXML
    private TableColumn<Reservation, String> ReservationIdColumn;
    @FXML
    private TableColumn<Reservation, String> LocationIdColumn;
    @FXML
    private TableColumn<Reservation, String> AddressColumn;
    @FXML
    private TableColumn<Reservation, String> DescriptionColumn;
    @FXML
    private TableColumn<Reservation, String> StartTimeAndDateColumn;
    @FXML
    private TableColumn<Reservation, String> EndTimeAndDateColumn;
    @FXML
    private TextField memId;


    /**
     * The constructor.
     * The constructor is called before the initialize() method.
     */
    public QRYClientReservationsTableController() {

    }

    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
        // Initialize the Location table with the tree columns.
        ReservationIdColumn.setCellValueFactory(cellData -> cellData.getValue().ReservationIdProperty());
        LocationIdColumn.setCellValueFactory(cellData -> cellData.getValue().LocationIdProperty());
        AddressColumn.setCellValueFactory(cellData -> cellData.getValue().LocationAddressProperty());
        DescriptionColumn.setCellValueFactory(cellData -> cellData.getValue().LocationDescriptionProperty());
        StartTimeAndDateColumn.setCellValueFactory(cellData -> cellData.getValue().StartDateProperty());
        EndTimeAndDateColumn.setCellValueFactory(cellData -> cellData.getValue().EndDateProperty());
    }
    @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();
    }
    /**
     * Is called by the main application to give a reference back to itself.
     *
     * @param Locaion
     */
    public void setQRYClientReservationsTableController(String memId) {
        this.memId.setEditable(true);
        this.memId.setText(memId);
        this.memId.setEditable(false);
        ArrayList<Reservation> reservationsAdd = new ArrayList<Reservation>();
        reservationsAdd.addAll(ViewLogic.controlLogic.Q_getAllReservationsForMember(memId));
        ReservationsData.addAll(reservationsAdd);
        // Add observable list data to the table
        ReservationforClient.setItems(ReservationsData);
        ReservationIdColumn.sortableProperty().setValue(false);
        LocationIdColumn.sortableProperty().setValue(false);
        AddressColumn.sortableProperty().setValue(false);
        DescriptionColumn.sortableProperty().setValue(false);
        StartTimeAndDateColumn.sortableProperty().setValue(false);
        EndTimeAndDateColumn.sortableProperty().setValue(false);
    }
}

The next code is in my ViewLogic Class inside my View package and this code summons the FXML file that loads up a small window to choose a member Id, by this Id I am getting the info to build the table on the code above. the code for this method in ViewLogic is as follows:

@FXML
Button ShowReservationsForClientBtn= new Button();/*Code for pressing the get reservations for client button to open window after pressing the button in Queries*/
@FXML
public void pressShowReservationsForClientBtn(ActionEvent event) throws Exception {
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(ChooseAClientForReservationsQueryWindowController.class.getResource("/view/ChooseAClientForReservationsQueryWindow.fxml"));
        AnchorPane chooseMemberIdForQuery = (AnchorPane) fxmlLoader.load();
        ChooseAClientForReservationsQueryWindowController controller = fxmlLoader.getController();
        controller.setAddTripToReservationClass();
        Stage stage = new Stage();
        stage.setTitle("Please Choose a Member Id");
        stage.setScene(new Scene(chooseMemberIdForQuery));
        stage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

It then calls this class where you choose your member and then the table code above is initiated, the mini window code is:

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;

                }
            });
        }
    }

That's the relevant FXML file for the table code above if it helps:

<?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>

Thank you

Tom

解决方案

I stumbled across the similar problem and have created a simple library that solves it.

It uses your model class to build a TableView that represents the fields of the given class.

I've published it on GitHub with a sample and instruction.

If you have any suggestions, I would like to hear from you.

这篇关于如何在JavaFx中创建一个通用的TableView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆