可能有很多方法可以做到这一点,这将取决于您对最终如何实现它的要求,但在我看来,您希望尽量减少每次在表上执行新的迭代次数行已添加...
例如,如果只添加了一行,则迭代整个表是没有意义的。这是低效的。
相反,您可以使用TableModelListener
并监听表模型的更新并更新运行总计(将新行值添加到已经运行的总计中)。
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class SubTotalTable {
public static void main(String[] args) {
new SubTotalTable();
}
public SubTotalTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel subTotal;
private DefaultTableModel tableModel;
private double runningTally = 0;
public TestPane() {
setLayout(new BorderLayout());
tableModel = new DefaultTableModel(new Object[]{"Price"}, 0);
JTable table = new JTable(tableModel);
table.getColumnModel().getColumn(0).setCellRenderer(new CurrencyRenderer());
add(new JScrollPane(table));
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.weightx = 1;
JButton charge = new JButton("Charge");
charge.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
double subTally = 0;
double tally = runningTally;
int rows = (int) (Math.round(Math.random() * 9) + 1);
for (int row = 0; row < rows; row++) {
double amount = (Math.random() * 99999) + 1;
tableModel.addRow(new Object[]{amount});
tally += amount;
subTally += amount;
}
System.out.println("subTally = " + subTally);
System.out.println("tally = " + tally);
}
});
panel.add(charge, gbc);
gbc.gridx++;
gbc.weightx = 0;
subTotal = new JLabel(getRunningTallyDisplayValue());
panel.add(subTotal, gbc);
add(panel, BorderLayout.SOUTH);
tableModel.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
switch (e.getType()) {
case TableModelEvent.DELETE:
System.out.println("Delete");
break;
case TableModelEvent.INSERT:
System.out.println("Insert");
for (int row = e.getFirstRow(); row <= e.getLastRow(); row++) {
Object value = tableModel.getValueAt(row, 0);
if (value instanceof Double) {
runningTally += (double)value;
}
}
break;
case TableModelEvent.UPDATE:
System.out.println("Update");
break;
}
subTotal.setText(getRunningTallyDisplayValue());
}
});
}
protected String getRunningTallyDisplayValue() {
return NumberFormat.getCurrencyInstance().format(runningTally);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class CurrencyRenderer extends DefaultTableCellRenderer {
public CurrencyRenderer() {
setHorizontalAlignment(JLabel.RIGHT);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Double) {
value = NumberFormat.getCurrencyInstance().format(value);
}
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
return this;
}
}
}
看看如何使用表格,特别是监听数据变化