可能有很多方法可以做到這一點,並且會根據您的要求來決定如何最終實現它,但在我看來,您希望最小化需要在表格上執行的迭代次數每次添加新行時...
例如,如果只添加一行,那麼遍歷整個表就沒有意義了。效率不高。
取而代之,您可以使用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;
}
}
}
看看How to use tables,特別Listening for Data Changes
1)爲了更好地幫助越早,張貼[SSCCE(http://sscce.org/)。 2)*「我怎樣才能做到這一點?」* [你有什麼嘗試?](http://www.whathaveyoutried.com/) –
你讓Swing類管理所有東西使事情變得過於複雜。爲什麼你使用'DefaultTableModel'而不是自定義模型來管理一個知道如何計算自己小計的支付列表?我假設'total'是一個'JLabel'。因此,讓標籤監聽「TableModelEvent」。 –
使用['TableModelListener'](http://docs.oracle.com/javase/7/docs/api/javax/swing/event/TableModelListener.html),它會告訴你什麼時候表模型被更改。然後,您可以使用該信息更新小計,而不需要遍歷整個表... – MadProgrammer