计算JTable中的运行总计 [英] Calculate running total in JTable

查看:93
本文介绍了计算JTable中的运行总计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要填充JTable中的一列来计算运行总计,如下所示。

  ID名称职位薪资总额
=== ====== ======== == ======= ======
1. Peter程序员40,000 40,000
2. Paul经理25,000 65,000
3. Mary Designer 25,000 90,000

我有4个类 - 每个员工一个实体类,一个表模型类,一个扩展JFrame以显示的主类输出,以及一个格式化最后两列中的数字。代码如下所示。我遇到的问题是运行总计没有正确计算。由于目前编写的代码,第一个总数是80,000太高,这让我觉得它是第三个员工,然后再转到第二个员工。正确添加每个后续总数,但当然最终总数减少了80,000。
以下是现在的输出结果:

  ID名称职位薪资总额
=== = ===== ========== ======= ======
1. Peter程序员40,000 120,000
2.保罗经理25,000 145,000
3. Mary Designer 25,000 170,000

请注意下面的代码表可以重新排序按列并包含一个侦听器以重新计算运行总计。这个函数需要在重新排序之前归零,现在还没有这样做。如果有人能告诉我为什么会这样,以及如何解决它,我将非常感激。

 公共类JTableRunningTotalExample扩展JFrame 
{
private static final long serialVersionUID = 1L;
私有JTable表;
private TableModel tableModel;
private NumberCellFormatter numberCellFormatter = new NumberCellFormatter();
private int salarySum = 0;
private List< Employee>类ListEmployees;
私人员工;

public JTableRunningTotalExample()
{
super(JTable Sorting Example);
createListEmployees();
tableModel = new EmployeeTableModel(listEmployees);
table = new JTable(tableModel);
for(int j = 3; j< 5; j ++)
{
table.getColumnModel()。getColumn(j).setCellRenderer(numberCellFormatter);
}

TableRowSorter< TableModel> sorter = new TableRowSorter<>(table.getModel());
table.setRowSorter(sorter);
List< RowSorter.SortKey> sortKeys = new ArrayList<>();

int columnIndexToSort = 0;
sortKeys.add(new RowSorter.SortKey(columnIndexToSort,SortOrder.ASCENDING));

sorter.setSortKeys(sortKeys);
sorter.sort();
sorter.addRowSorterListener(new RowSorterListener()
{
public void sorterChanged(RowSorterEvent evt)
{
int columnIndex = 0;
salarySum = 0;
for(int i = 0; i< table.getRowCount(); i ++)
{
table.setValueAt(i + 1,i,columnIndex);
}
}
});
add(new JScrollPane(table),BorderLayout.CENTER);

pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public void createListEmployees()
{
listEmployees = new ArrayList<>();
listEmployees.add(新员工(Peter,经理,40000));
listEmployees.add(新员工(Paul,程序员,25000));
listEmployees.add(新员工(Mary,Designer,25000));
listEmployees.add(新员工(Donald,Leader,30000));
listEmployees.add(新员工(Tom,Designer,28000));
listEmployees.add(新员工(Samantha,分析师,50000));
listEmployees.add(新员工(Jerome,程序员,32000));
listEmployees.add(新员工(Jonathon,开发人员,29000));
listEmployees.add(新员工(Kevin,程序员,23000));
listEmployees.add(新员工(Anthony,程序员,23000));
listEmployees.add(新员工(John,Designer,33000));
listEmployees.add(new Employee(David,Developer,28000));
listEmployees.add(新员工(Harry,Designer,31000));
listEmployees.add(新员工(Charles,程序员,26000));
listEmployees.add(新员工(Joseph,经理,40000));
}

public static void main(String [] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@覆盖
public void run()
{
JTableRunningTotalExample frame = new JTableRunningTotalExample();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
});
}
}

*****表模型类*** **

 公共类EmployeeTableModel扩展AbstractTableModel 
{
private static final long serialVersionUID = 1L;
private static final int COLUMN_NUM = 0;
private static final int COLUMN_NAME = 1;
private static final int COLUMN_JOB = 2;
private static final int COLUMN_SALARY = 3;
private static final int COLUMN_SUM = 4;

private String [] columnNames = {No#,Name,Job,Salary,Total Payroll};
private List< Employee>类ListEmployees;
private int salarySum = 0;
私人员工;

public EmployeeTableModel(List< Employee> listEmployees)
{
this.listEmployees = listEmployees;
int indexCount = 1;
for(员工雇员:listEmployees)
{
employee.setIndex(indexCount ++);
}
}

@Override
public int getColumnCount()
{
return columnNames.length;
}

@Override
public int getRowCount()
{
return listEmployees.size();
}

@Override
public String getColumnName(int columnIndex)
{
return columnNames [columnIndex];
}

@Override
public Class<?> getColumnClass(int columnIndex)
{
if(listEmployees.isEmpty())
{
return Object.class;
}
返回getValueAt(0,columnIndex).getClass();
}

@Override
public Object getValueAt(int rowIndex,int columnIndex)
{
employee = listEmployees.get(rowIndex);
Object returnValue = null;
switch(columnIndex)
{
case COLUMN_NUM:
returnValue = employee.getIndex();
休息;
case COLUMN_NAME:
returnValue = employee.getName();
休息;
case COLUMN_JOB:
returnValue = employee.getJob();
休息;
case COLUMN_SALARY:
returnValue = employee.getSalary();
休息;
case COLUMN_SUM:
salarySum = salarySum + employee.getSalary();
returnValue = salarySum;
休息;
默认值:
抛出新的IllegalArgumentException(无效的列索引);
}
返回returnValue;
}
}

***** Empoloyee实体类*** **

 公共类员工
{
private int index;
private String name;
private String job;
私人工资;

public Employee(String name,String job,int salary)
{
this.name = name;
this.job = job;
this.salary = salary;
}

public int getIndex()
{
return index;
}

public void setIndex(int index)
{
this.index = index;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public String getJob()
{
return job;
}

public void setJob(String job)
{
this.job = job;
}

public int getSalary()
{
返回工资;
}

public void setSalary(int age)
{
this.salary = age;
}
}

***** Cell Renderer class *** **

 公共类NumberCellFormatter extends DefaultTableCellRenderer 
{
private static final long serialVersionUID = 1L;
private NumberFormat numberFormat = new DecimalFormat(#,###,###);
private double formattedNumber;

public double setNumberFormat(String number)
{
formattedNumber = Double.parseDouble(numberFormat.format(number));
返回formattedNumber;
}
@Override
public Component getTableCellRendererComponent(JTable jTable,Object value,boolean isSelected,boolean hasFocus,int row,int column)
{
Component c = super .getTableCellRendererComponent(jTable,value,isSelected,hasFocus,row,column);
if(c instanceof JLabel&& value instanceof Number)
{
JLabel label =(JLabel)c;
label.setHorizo​​ntalAlignment(JLabel.RIGHT);
数字num =(数字)值;
String text = numberFormat.format(num);
label.setText(text);
label.setForeground(num.doubleValue()< 0?Color.RED:Color.BLACK);
}
返回c;
}
}


解决方案

As在



经测试:

  import java.awt.BorderLayout; 
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultRowSorter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;

/ ** @see https://stackoverflow.com/a/37892395/230513 * /
public class JTableRunningTotalExample extends JFrame {

private final NumberCellFormatter numberCellFormatter = new NumberCellFormatter();

public JTableRunningTotalExample(){
super(JTable Sorting Example);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = new JTable(){
@Override
public Dimension getPreferredScrollableViewportSize(){
return new Dimension(500,getRowCount()* getRowHeight());
}
};
列表<员工> listEmployees = createListEmployees();
TableModel model = new EmployeeTableModel(table,listEmployees);
table.setModel(model);
table.setAutoCreateRowSorter(true);
DefaultRowSorter sorter =(DefaultRowSorter)table.getRowSorter();
sorter.setSortable(4,false);
for(int j = 3; j< 5; j ++){
table.getColumnModel()。getColumn(j).setCellRenderer(numberCellFormatter);
}
add(new JScrollPane(table),BorderLayout.CENTER);
pack();
}

private List< Employee> createListEmployees(){
List< Employee> listEmployees = new ArrayList<>();
listEmployees.add(新员工(Peter,经理,40000));
listEmployees.add(新员工(Paul,程序员,25000));
listEmployees.add(新员工(Mary,Designer,25000));
listEmployees.add(新员工(Donald,Leader,30000));
listEmployees.add(新员工(Tom,Designer,28000));
listEmployees.add(新员工(Samantha,分析师,50000));
listEmployees.add(新员工(Jerome,程序员,32000));
listEmployees.add(新员工(Jonathon,开发人员,29000));
listEmployees.add(新员工(Kevin,程序员,23000));
listEmployees.add(新员工(Anthony,程序员,23000));
listEmployees.add(新员工(John,Designer,33000));
listEmployees.add(new Employee(David,Developer,28000));
listEmployees.add(新员工(Harry,Designer,31000));
listEmployees.add(新员工(Charles,程序员,26000));
listEmployees.add(新员工(Joseph,经理,40000));
return listEmployees;
}

public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run (){
JTableRunningTotalExample frame = new JTableRunningTotalExample();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

私有静态类EmployeeTableModel扩展AbstractTableModel {

private static final int COLUMN_NUM = 0;
private static final int COLUMN_NAME = 1;
private static final int COLUMN_JOB = 2;
private static final int COLUMN_SALARY = 3;
private static final int COLUMN_SUM = 4;

private String [] columnNames = {No,Name,Job,Salary,Total Payroll};
JTable表;
private List< Employee>类ListEmployees;

public EmployeeTableModel(JTable table,List< Employee> listEmployees){
this.table = table;
this.listEmployees = listEmployees;
int indexCount = 1;
for(员工雇员:listEmployees){
employee.setIndex(indexCount ++);
}
}

@Override
public int getColumnCount(){
return columnNames.length;
}

@Override
public int getRowCount(){
return listEmployees.size();
}

@Override
public String getColumnName(int columnIndex){
return columnNames [columnIndex];
}

@Override
public Class<?> getColumnClass(int columnIndex){
return getValueAt(0,columnIndex).getClass();
}

@Override
public Object getValueAt(int rowIndex,int columnIndex){
Employee employee = listEmployees.get(rowIndex);
switch(columnIndex){
case COLUMN_NUM:
return employee.getIndex();
case COLUMN_NAME:
return employee.getName();
case COLUMN_JOB:
return employee.getJob();
case COLUMN_SALARY:
return employee.getSalary();
case COLUMN_SUM:
return partialSum(rowIndex);
默认值:
抛出新的IllegalArgumentException(无效的列索引);
}
}

private int partialSum(int row){
int viewRow = table.convertRowIndexToView(row);
int viewCol = table.convertColumnIndexToView(COLUMN_SALARY);
int sum =(int)table.getValueAt(viewRow,viewCol);
for(int i = 0; i< viewRow; i ++){
sum + =(int)table.getValueAt(i,viewCol);
}
返还金额;
}
}

私有静态类雇员{

private int index;
private String name;
private String job;
私人工资;

public Employee(String name,String job,int salary){
this.name = name;
this.job = job;
this.salary = salary;
}

public int getIndex(){
return index;
}

public void setIndex(int index){
this.index = index;
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public String getJob(){
return job;
}

public void setJob(String job){
this.job = job;
}

public int getSalary(){
return salary;
}

public void setSalary(int age){
this.salary = age;
}
}

私有静态类NumberCellFormatter extends DefaultTableCellRenderer {

private static final long serialVersionUID = 1L;
private NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
private double formattedNumber;

public double setNumberFormat(String number){
formattedNumber = Double.parseDouble(numberFormat.format(number));
返回formattedNumber;
}

@Override
public Component getTableCellRendererComponent(JTable jTable,Object value,
boolean isSelected,boolean hasFocus,int row,int column){
组件c = super.getTableCellRendererComponent(jTable,value,
isSelected,hasFocus,row,column);
if(c instanceof JLabel&& value instanceof Number){
JLabel label =(JLabel)c;
label.setHorizo​​ntalAlignment(JLabel.RIGHT);
数字num =(数字)值;
String text = numberFormat.format(num);
label.setText(text);
label.setForeground(num.doubleValue()< 0?Color.RED:Color.BLACK);
}
返回c;
}
}
}


I need to populate a column in my JTable that computes a running total as is shown below.

ID   Name   Position   Salary    Total
===  ====== ========== =======   ======
1.   Peter  Programmer  40,000   40,000
2.   Paul   Manager     25,000   65,000
3.   Mary   Designer    25,000   90,000

I have 4 classes--one entity class for each employee, one table model class, one main class that extends JFrame to show the output, and one to format the numbers in the last two columns. Code is shown below. The problem I'm having is that the running total is not computed correctly. As the code is currently written, the first total is 80,000 too high, which makes me think it is adding the first employee three times before moving to the second. Each subsequent total is correctly added, but of course the final total is off by 80,000. Here is what the output looks like now:

ID   Name   Position   Salary   Total
===  ====== ========== =======   ======
1.   Peter  Programmer  40,000   120,000
2.   Paul   Manager     25,000   145,000
3.   Mary   Designer    25,000   170,000

Notice in the code below that the table can be re-sorted by column and a listener is included to re-calculate the running totals. This function needs to be zeroed out prior to re-sorting and it's not doing that now. If anyone can tell me why this is happening and how to fix it, I would be very grateful.

public class JTableRunningTotalExample extends JFrame
{
    private static final long serialVersionUID = 1L;
    private JTable table;
    private TableModel tableModel;
    private NumberCellFormatter numberCellFormatter = new NumberCellFormatter();
    private int salarySum = 0;
    private List<Employee> listEmployees;
    private Employee employee;

    public JTableRunningTotalExample()
    {
        super("JTable Sorting Example");
        createListEmployees();
        tableModel = new EmployeeTableModel(listEmployees);
        table = new JTable(tableModel);
        for (int j=3; j<5; j++)
        {
            table.getColumnModel().getColumn(j).setCellRenderer(numberCellFormatter);
        }

        TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
        table.setRowSorter(sorter);
        List<RowSorter.SortKey> sortKeys = new ArrayList<>();

        int columnIndexToSort = 0;
        sortKeys.add(new RowSorter.SortKey(columnIndexToSort, SortOrder.ASCENDING));

        sorter.setSortKeys(sortKeys);
        sorter.sort();
        sorter.addRowSorterListener(new RowSorterListener()
        {
            public void sorterChanged(RowSorterEvent evt)
            {
                int columnIndex = 0;
                salarySum = 0;
                for (int i = 0; i < table.getRowCount(); i++)
                {
                    table.setValueAt(i + 1, i, columnIndex);
                }
            }
        });
        add(new JScrollPane(table), BorderLayout.CENTER);

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void createListEmployees()
    {
        listEmployees = new ArrayList<>();
        listEmployees.add(new Employee("Peter", "Manager", 40000));
        listEmployees.add(new Employee("Paul", "Programmer", 25000));
        listEmployees.add(new Employee("Mary", "Designer", 25000));
        listEmployees.add(new Employee("Donald", "Leader", 30000));
        listEmployees.add(new Employee("Tom", "Designer", 28000));
        listEmployees.add(new Employee("Samantha", "Analyst", 50000));
        listEmployees.add(new Employee("Jerome", "Programmer", 32000));
        listEmployees.add(new Employee("Jonathon", "Developer", 29000));
        listEmployees.add(new Employee("Kevin", "Programmer", 23000));
        listEmployees.add(new Employee("Anthony", "Programmer", 23000));
        listEmployees.add(new Employee("John", "Designer", 33000));
        listEmployees.add(new Employee("David", "Developer", 28000));
        listEmployees.add(new Employee("Harry", "Designer", 31000));
        listEmployees.add(new Employee("Charles", "Programmer", 26000));
        listEmployees.add(new Employee("Joseph", "Manager", 40000));
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JTableRunningTotalExample frame = new JTableRunningTotalExample();
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);
            }
        });
    }
}

*****Table Model class*****

public class EmployeeTableModel extends AbstractTableModel
{
    private static final long serialVersionUID = 1L;
    private static final int COLUMN_NUM = 0;
    private static final int COLUMN_NAME = 1;
    private static final int COLUMN_JOB = 2;
    private static final int COLUMN_SALARY = 3;
    private static final int COLUMN_SUM = 4;

    private String[] columnNames = { "No #", "Name", "Job", "Salary", "Total Payroll" };
    private List<Employee> listEmployees;
    private int salarySum = 0;
    private Employee employee;

    public EmployeeTableModel(List<Employee> listEmployees)
    {
        this.listEmployees = listEmployees;
        int indexCount = 1;
        for (Employee employee : listEmployees)
        {
            employee.setIndex(indexCount++);
        }
    }

    @Override
    public int getColumnCount()
    {
        return columnNames.length;
    }

    @Override
    public int getRowCount()
    {
        return listEmployees.size();
    }

    @Override
    public String getColumnName(int columnIndex)
    {
        return columnNames[columnIndex];
    }

    @Override
    public Class<?> getColumnClass(int columnIndex)
    {
        if (listEmployees.isEmpty())
        {
            return Object.class;
        }
        return getValueAt(0, columnIndex).getClass();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex)
    {
        employee = listEmployees.get(rowIndex);
        Object returnValue = null;
        switch (columnIndex)
        {
            case COLUMN_NUM:
                returnValue = employee.getIndex();
                break;
            case COLUMN_NAME:
                returnValue = employee.getName();
                break;
            case COLUMN_JOB:
                returnValue = employee.getJob();
                break;
            case COLUMN_SALARY:
                returnValue = employee.getSalary();
                break;
            case COLUMN_SUM:
                salarySum = salarySum + employee.getSalary();
                returnValue = salarySum ;
                break;
            default:
                throw new IllegalArgumentException("Invalid column index");
        }
        return returnValue;
    }
}

*****Empoloyee entity class*****

public class Employee
{
    private int index;
    private String name;
    private String job;
    private int salary;

    public Employee(String name, String job, int salary) 
    {
        this.name = name;
        this.job = job;
        this.salary = salary;
    }

    public int getIndex()
    {
        return index;
    }

    public void setIndex(int index)
    {
        this.index = index;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getJob()
    {
        return job;
    }

    public void setJob(String job)
    {
        this.job = job;
    }

    public int getSalary()
    {
        return salary;
    }

    public void setSalary(int age)
    {
        this.salary = age;
    }
}

*****Cell Renderer class*****

public class NumberCellFormatter extends DefaultTableCellRenderer
{
    private static final long serialVersionUID = 1L;
    private NumberFormat numberFormat = new DecimalFormat("#,###,###");
    private double formattedNumber;

    public double setNumberFormat(String number)
    {
        formattedNumber = Double.parseDouble(numberFormat.format(number));
        return formattedNumber;
    }
    @Override
    public Component getTableCellRendererComponent(JTable jTable, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        Component c = super.getTableCellRendererComponent(jTable, value, isSelected, hasFocus, row, column);
        if (c instanceof JLabel && value instanceof Number)
        {
            JLabel label = (JLabel) c;
            label.setHorizontalAlignment(JLabel.RIGHT);
            Number num = (Number) value;
            String text = numberFormat.format(num);
            label.setText(text);
            label.setForeground(num.doubleValue() < 0 ? Color.RED : Color.BLACK);
        }
        return c;
    }
}

解决方案

As discussed in How to Use Tables: Sorting and Filtering, "When using a sorter, always remember to translate cell coordinates." Because JTable sorting occurs in the view, use view coordinates when calculating the partial sum for COLUMN_SUM in your implementation of getValueAt(), and disable sorting for that column as shown here.

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Employee employee = listEmployees.get(rowIndex);
    switch (columnIndex) {
        …
        case COLUMN_SUM:
            return partialSum(rowIndex);
        …
    }
}

private int partialSum(int row) {
    int viewRow = table.convertRowIndexToView(row);
    int viewCol = table.convertColumnIndexToView(COLUMN_SALARY);
    int sum = (int) table.getValueAt(viewRow, viewCol);
    for (int i = 0; i < viewRow; i++) {
        sum += (int) table.getValueAt(i, viewCol);
    }
    return sum;
}

As tested:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultRowSorter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;

/** @see https://stackoverflow.com/a/37892395/230513 */
public class JTableRunningTotalExample extends JFrame {

    private final NumberCellFormatter numberCellFormatter = new NumberCellFormatter();

    public JTableRunningTotalExample() {
        super("JTable Sorting Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTable table = new JTable() {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(500, getRowCount() * getRowHeight());
            }
        };
        List<Employee> listEmployees = createListEmployees();
        TableModel model = new EmployeeTableModel(table, listEmployees);
        table.setModel(model);
        table.setAutoCreateRowSorter(true);
        DefaultRowSorter sorter = (DefaultRowSorter) table.getRowSorter();
        sorter.setSortable(4, false);
        for (int j = 3; j < 5; j++) {
            table.getColumnModel().getColumn(j).setCellRenderer(numberCellFormatter);
        }
        add(new JScrollPane(table), BorderLayout.CENTER);
        pack();
    }

    private List<Employee> createListEmployees() {
        List<Employee> listEmployees = new ArrayList<>();
        listEmployees.add(new Employee("Peter", "Manager", 40000));
        listEmployees.add(new Employee("Paul", "Programmer", 25000));
        listEmployees.add(new Employee("Mary", "Designer", 25000));
        listEmployees.add(new Employee("Donald", "Leader", 30000));
        listEmployees.add(new Employee("Tom", "Designer", 28000));
        listEmployees.add(new Employee("Samantha", "Analyst", 50000));
        listEmployees.add(new Employee("Jerome", "Programmer", 32000));
        listEmployees.add(new Employee("Jonathon", "Developer", 29000));
        listEmployees.add(new Employee("Kevin", "Programmer", 23000));
        listEmployees.add(new Employee("Anthony", "Programmer", 23000));
        listEmployees.add(new Employee("John", "Designer", 33000));
        listEmployees.add(new Employee("David", "Developer", 28000));
        listEmployees.add(new Employee("Harry", "Designer", 31000));
        listEmployees.add(new Employee("Charles", "Programmer", 26000));
        listEmployees.add(new Employee("Joseph", "Manager", 40000));
        return listEmployees;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JTableRunningTotalExample frame = new JTableRunningTotalExample();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static class EmployeeTableModel extends AbstractTableModel {

        private static final int COLUMN_NUM = 0;
        private static final int COLUMN_NAME = 1;
        private static final int COLUMN_JOB = 2;
        private static final int COLUMN_SALARY = 3;
        private static final int COLUMN_SUM = 4;

        private String[] columnNames = {"No", "Name", "Job", "Salary", "Total Payroll"};
        JTable table;
        private List<Employee> listEmployees;

        public EmployeeTableModel(JTable table, List<Employee> listEmployees) {
            this.table = table;
            this.listEmployees = listEmployees;
            int indexCount = 1;
            for (Employee employee : listEmployees) {
                employee.setIndex(indexCount++);
            }
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public int getRowCount() {
            return listEmployees.size();
        }

        @Override
        public String getColumnName(int columnIndex) {
            return columnNames[columnIndex];
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return getValueAt(0, columnIndex).getClass();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Employee employee = listEmployees.get(rowIndex);
            switch (columnIndex) {
                case COLUMN_NUM:
                    return employee.getIndex();
                case COLUMN_NAME:
                    return employee.getName();
                case COLUMN_JOB:
                    return employee.getJob();
                case COLUMN_SALARY:
                    return employee.getSalary();
                case COLUMN_SUM:
                    return partialSum(rowIndex);
                default:
                    throw new IllegalArgumentException("Invalid column index");
            }
        }

        private int partialSum(int row) {
            int viewRow = table.convertRowIndexToView(row);
            int viewCol = table.convertColumnIndexToView(COLUMN_SALARY);
            int sum = (int) table.getValueAt(viewRow, viewCol);
            for (int i = 0; i < viewRow; i++) {
                sum += (int) table.getValueAt(i, viewCol);
            }
            return sum;
        }
    }

    private static class Employee {

        private int index;
        private String name;
        private String job;
        private int salary;

        public Employee(String name, String job, int salary) {
            this.name = name;
            this.job = job;
            this.salary = salary;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getJob() {
            return job;
        }

        public void setJob(String job) {
            this.job = job;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int age) {
            this.salary = age;
        }
    }

    private static class NumberCellFormatter extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;
        private NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
        private double formattedNumber;

        public double setNumberFormat(String number) {
            formattedNumber = Double.parseDouble(numberFormat.format(number));
            return formattedNumber;
        }

        @Override
        public Component getTableCellRendererComponent(JTable jTable, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = super.getTableCellRendererComponent(jTable, value,
                isSelected, hasFocus, row, column);
            if (c instanceof JLabel && value instanceof Number) {
                JLabel label = (JLabel) c;
                label.setHorizontalAlignment(JLabel.RIGHT);
                Number num = (Number) value;
                String text = numberFormat.format(num);
                label.setText(text);
                label.setForeground(num.doubleValue() < 0 ? Color.RED : Color.BLACK);
            }
            return c;
        }
    }
}

这篇关于计算JTable中的运行总计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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