How to calculate the subtotal while every time adding a new row in JTable
?
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
int i
There are probably a number of ways to do this and it will come down to your requirements about how you would finally achieve it, but to my mind, you want to minimize the number of iterations you need to perform over the table each time a new row is added...
There's no point iterating over the entire table if only one row was added, for example. It's inefficient.
Instead, you could use TableModelListener
and listen for updates to the table model and update a running total (adding the new row values to already running total).
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;
}
}
}
Take a look at How to use tables and in particular Listening for Data Changes