我需要填充JTable中的一列来计算运行总计,如下所示.
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
我有4个类 – 每个员工一个实体类,一个表模型类,一个扩展JFrame以显示输出的主类,以及一个用于格式化最后两列中的数字的类.代码如下所示.我遇到的问题是运行总量未正确计算.由于目前编写的代码,第一个总数是80,000太高,这让我觉得它是第三个员工,然后再转到第二个员工.每个后续总数都被正确添加,但当然最终总数减少了80,000.
以下是输出现在的样子:
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
请注意,在下面的代码中,可以按列对表进行重新排序,并包含一个侦听器来重新计算运行总计.在重新排序之前,需要将此函数清零,而现在不执行此操作.如果有人能告诉我为什么会这样,以及如何解决它,我将非常感激.
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 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 sorter = new TableRowSorter<>(table.getModel());
table.setRowSorter(sorter);
List 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);
}
});
}
}
*****表模型类*****
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 listEmployees;
private int salarySum = 0;
private Employee employee;
public EmployeeTableModel(List 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实体类*****
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;
}
}