如何在 JavaFx TableView 中添加 TableView 页脚

Posted

技术标签:

【中文标题】如何在 JavaFx TableView 中添加 TableView 页脚【英文标题】:How to add TableView footer in JavaFx TableView 【发布时间】:2021-12-04 05:26:18 【问题描述】:

我被困在如何在 JavaFX TableView 中添加 table footercolumn footer。我希望添加一个TableView,它将在列中显示购买的商品数量和销售价格,并在TableView 页脚显示商品总数和总和。我查看了各种资源,但找不到与TableView 关联的页脚属性。知道怎么做吗?

模型类

    package javafxapplication8;
    
    public class TestModel 
    
        private String itemName = null;
    
        private int pricePerUnit = 0;
    
        private double quantity = 0.0;
    
        private double amount = 0.0;
    
        public TestModel() 
        
    
        public TestModel(String argitemName, int argpricePerUnit, double argquantity, double argamount) 
            itemName = argitemName;
            pricePerUnit = argpricePerUnit;
            quantity = argquantity;
            amount = argamount;
    
        
    
        public void setItemName(String argitemName) 
            itemName = argitemName;
        
    
        public void setPricePerUnit(int argpricePerUnit) 
            pricePerUnit = argpricePerUnit;
        
    
        public void setQuantity(double argquantity) 
            quantity = argquantity;
        
    
        public void setAmount(double argamount) 
            amount = argamount;
        
    
        public String getItemName() 
            return itemName;
        
    
        public int getPricePerUnit() 
            return pricePerUnit;
        
    
        public double getQuantity() 
            return quantity;
        
    
        public double getAmount() 
            return amount;
        
    
        @Override
        public String toString() 
            return this.itemName + "" + this.pricePerUnit + "" + this.quantity + "" + this.amount;
        
    
    

XML 代码

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

<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<AnchorPane id="AnchorPane" fx:id="anchor" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication8.TVCTestModel">
    <children>
        <VBox prefHeight="564.0" prefWidth="857.0">
            <children>
                <HBox alignment="BOTTOM_LEFT" prefHeight="100.0" prefWidth="1613.0" spacing="20.0" />            
                <BorderPane prefHeight="695.0" prefWidth="1618.0">
                    <center>
                        <VBox prefHeight="544.0" prefWidth="772.0">
                            <children>
                                <HBox prefHeight="65.0" prefWidth="1618.0" />
                                <HBox prefHeight="426.0" prefWidth="857.0">
                                    <children>
                                        <HBox alignment="CENTER" prefHeight="225.0" prefWidth="857.0">
                                            <children>                  
                                                <TableView fx:id="myTableView" prefHeight="419.0" prefWidth="816.0">
                                                    <columns>
                                                        <TableColumn fx:id="itemName" prefWidth="200.0" text="Item Name" />
                                                        <TableColumn fx:id="pricePerUnit" prefWidth="200.0" text="Price Per Unit" />
                                                        <TableColumn fx:id="quantity" prefWidth="200.0" text="Quantity" />
                                                        <TableColumn fx:id="amount" prefWidth="200.0" text="Amount" />
                                                    </columns>
                                                </TableView>
                                            </children>
                                        </HBox>
                                    </children>
                                </HBox>
                            </children>
                        </VBox>              
                    </center>
                    <bottom>

                    </bottom>
                </BorderPane>         
            </children>
        </VBox>
    </children>
</AnchorPane>

控制器类

package javafxapplication8;

import java.net.URL;

import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;

import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;

public class TVCTestModel implements Initializable 

    @FXML
    private TableColumn<TestModel, String> itemName;

    @FXML
    private TableColumn<TestModel, Integer> pricePerUnit;

    @FXML
    private TableColumn<TestModel, Double> quantity;

    @FXML
    private TableColumn<TestModel, Double> amount;
    @FXML
    private TableView<TestModel> myTableView;
    public ObservableList<TestModel> objList = FXCollections.observableArrayList();
    @FXML
    private AnchorPane anchor;
    private static TestModel curTestModel;

    @Override
    public void initialize(URL url, ResourceBundle rb) 
        this.itemName.setCellValueFactory(new PropertyValueFactory<>("itemName"));
        this.pricePerUnit.setCellValueFactory(new PropertyValueFactory<>("pricePerUnit"));
        this.quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
        this.amount.setCellValueFactory(new PropertyValueFactory<>("amount"));

        objList.add(new TestModel("Item 1", 10, 4, 400));
        objList.add(new TestModel("Item 2", 20, 5, 1000));
        objList.add(new TestModel("Item 3", 30, 6, 1800));
        objList.add(new TestModel("Item 4", 400, 7, 2800));
        System.out.println(objList.size());
        myTableView.setItems(objList);
    


MainMethod 类

   package javafxapplication8;
    
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class JavaFXApplication8 extends Application 
    
        @Override
        public void start(Stage primaryStage) 
    
            try 
                Parent root = FXMLLoader.load(getClass().getResource("TVCTestModel.fxml"));
                Scene scene = new Scene(root);
                primaryStage.setScene(scene);
                primaryStage.show();
    
             catch (IOException ex) 
                Logger.getLogger(JavaFXApplication8.class.getName()).log(Level.SEVERE, null, ex);
            
        
    
        public static void main(String[] args) 
            launch(args);
        
    
    

【问题讨论】:

这能回答你的问题吗? JavaFX .How to make a line of summation(total row) in the bottom of the table? 如果这不是重复的,请edit 您的问题包括一个minimal reproducible example,以显示您修改后的方法。 我看到你的编辑,但没有看到你的minimal reproducible example。 如您所述,fx tableView 不支持页眉/页脚 - 您的选择:a) 自己编写代码(这不是火箭科学,但需要对表格皮肤的实现细节有深入的了解)b)使用第三方实现(例如 GridView,或者 ControlsFX c 的 TableView2)与您的要求近似(例如引用的 QA,或者可能是表外的单个 tableRow) d)聘请顾问为您解决问题; ) 由于您的表格不可编辑,我采用了简单的近似值 (c) here;如果您编辑您的问题,请参考它;请注意,您应该考虑按照here 的建议迁移到模型类中的属性。 @kleopatra:谢谢,extractor 是关键成分。顺便说一句,OP 的更新引发了审查;历史记录在timeline。 【参考方案1】:

您更新的问题已重新打开,并且提供的图像表明,您需要两个汇总字段,而不是 footer。由于您的表格不可编辑,因此说明了一个简单的近似值here — 向视图添加两个标签,并在控制器中迭代表格的模型以建立本地化结果:

TVCTestModel.fxml:

…
<bottom>
    <HBox alignment="CENTER_RIGHT" style="-fx-spacing: 5px;">
        <children>
            <Label fx:id="labelQ"/>
            <Label fx:id="labelA"/>
        </children>
    </HBox>
</bottom>
…

TVCTestModel.java

@FXML private Label labelQ;
@FXML private Label labelA;

@Override
public void initialize(URL url, ResourceBundle rb) 
    …
    double sumQuantity = 0;
    double sumAmout = 0;
    for (TestModel o : objList) 
        sumQuantity += o.getQuantity();
        sumAmout += o.getAmount();
    
    labelQ.setText("Quantity: "
        + NumberFormat.getNumberInstance().format(sumQuantity));
    labelA.setText("Amount: "
       + NumberFormat.getCurrencyInstance().format(sumAmout));

如果您稍后决定让您的表格可编辑,如 here 所示,您应该考虑进行以下修改:

迁移到模型类中的可观察属性,如 here 所示。

使用extractor 创建您的ObservableList 模型,如here 和here 所示;您的 extractor 将包括数量和金额的属性;然后,您的控制器可以更新 ListChangeListener 中的汇总字段。

【讨论】:

以上是关于如何在 JavaFx TableView 中添加 TableView 页脚的主要内容,如果未能解决你的问题,请参考以下文章

如何将行和列添加到 JavaFX 8 TableView

如何填充在 JavaFx Scene Builder 中设计的 fxml 文件中定义的 TableView

向 Tableview Javafx 动态添加和删除 tablecolumn

如何将网格线保留在空的 TableView Javafx 中

JavaFX 表 - 如何添加组件?

javafx tableview 检测任何行的任何更改,包括添加新行