我正在尝试根据是添加还是删除项目来更新GUI中的JTable。 JTextField中的总价格应根据删除或添加的项目递增或递减。我知道我应该使用TableModelListener动态更新它。我还需要在整个JTextField中设置它,但我不确定如何正确处理它。这是我的代码。
package classes;
import java.awt.*;
import java.awt.GridLayout;
import java.awt.event.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.event.*;
public class CoffeeTill_GUI extends JFrame {
private JPanel contentPane;
JLabel orderDescription = new JLabel("Order Description:");
private JTextField totalTF;
private double total = 0.0;
private double tendered = 0.0;
private double change = 0.0;
private TableModelListener tableModelListener;
// Editing An Order
//TableModelListener to listen for changes in the tableModel
private void setTableModelListener() {
tableModelListener = new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
if (e.getType() == TableModelEvent.UPDATE) {
System.out.println("Cell " + e.getFirstRow() + ", "
+ e.getColumn() + " changed. The new value: "
+ table.getModel().getValueAt(e.getFirstRow(),
e.getColumn()));
int row = e.getFirstRow();
int column = e.getColumn();
if (column == 0 || column == 1)
{
TableModel model = table.getModel();
int quantity = ((Integer) model.getValueAt(row, 0)).intValue();
double price = ((Double) model.getValueAt(row, 1)).doubleValue();
Double value = new Double(quantity * price);
model.setValueAt(value, row, 1);
}
}
}
};
table.getModel().addTableModelListener(tableModelListener);
}
// JDBC Driver name and database URL
final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
final String DB_URL = "jdbc:mysql://localhost:3306/team_project?useSSL=false";
final String USER_NAME = "root";
final String PASSWORD = "password";
// sql variables
Statement statement = null;
ResultSet resultSet = null;
// Update JTable when JButton is clicked
public void updateTable(int prodIn) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = (Connection) DriverManager.getConnection(DB_URL, USER_NAME, PASSWORD);
Statement stmt = conn.createStatement();
String sqlString = "select ProductID, ProductName, Price from product where ProductID = " + prodIn;
stmt.executeQuery(sqlString);
} catch (Exception e) {
e.printStackTrace();
}
}
// creating new stock item
Stock productPrice = new Stock();
Stock productName = new Stock();
JTable table = new JTable();
JButton delButton = new JButton("DEL");
JButton minusButton = new JButton("-");
JButton plusButton = new JButton("+");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CoffeeTill_GUI frame = new CoffeeTill_GUI();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
// Connection Object
Connection connection = null;
private JTextField tenderedTF;
private JTextField changeTF;
/**
* Create the frame.
*/
public CoffeeTill_GUI() {
try {
connection = (Connection) DriverManager.getConnection(DB_URL, USER_NAME, PASSWORD);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1200, 686);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
// COFFEE PANEL - START -----------------------------------------
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.setBounds(20, 74, 796, 563);
contentPane.add(tabbedPane);
JPanel panel = new JPanel();
tabbedPane.addTab("Coffee", null, panel, null);
panel.setLayout(null);
JLabel lblCoffee = new JLabel("Americano");
lblCoffee.setHorizontalAlignment(SwingConstants.CENTER);
lblCoffee.setFont(new Font("Tahoma", Font.PLAIN, 30));
lblCoffee.setBounds(10, 45, 154, 45);
panel.add(lblCoffee);
JLabel label = new JLabel("Cappucino");
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setFont(new Font("Tahoma", Font.PLAIN, 30));
label.setBounds(10, 117, 154, 45);
panel.add(label);
JLabel label_1 = new JLabel("Espresso");
label_1.setHorizontalAlignment(SwingConstants.CENTER);
label_1.setFont(new Font("Tahoma", Font.PLAIN, 30));
label_1.setBounds(10, 191, 154, 45);
panel.add(label_1);
JLabel label_2 = new JLabel("Latte");
label_2.setHorizontalAlignment(SwingConstants.CENTER);
label_2.setFont(new Font("Tahoma", Font.PLAIN, 30));
label_2.setBounds(10, 274, 154, 45);
panel.add(label_2);
JLabel label_3 = new JLabel("Mocha");
label_3.setHorizontalAlignment(SwingConstants.CENTER);
label_3.setFont(new Font("Tahoma", Font.PLAIN, 30));
label_3.setBounds(10, 355, 154, 45);
panel.add(label_3);
JLabel label_4 = new JLabel("Macchiato");
label_4.setHorizontalAlignment(SwingConstants.CENTER);
label_4.setFont(new Font("Tahoma", Font.PLAIN, 30));
label_4.setBounds(10, 440, 154, 45);
panel.add(label_4);
JButton americanoSmall = new JButton("SMALL");
americanoSmall.setBounds(191, 45, 164, 45);
panel.add(americanoSmall);
JButton americanoMedium = new JButton("MEDIUM");
americanoMedium.setBounds(365, 45, 164, 45);
panel.add(americanoMedium);
JButton americanoLarge = new JButton("LARGE");
americanoLarge.setBounds(539, 45, 164, 45);
panel.add(americanoLarge);
JButton cappuchinoSmall = new JButton("SMALL");
cappuchinoSmall.setBounds(191, 117, 164, 45);
panel.add(cappuchinoSmall);
JButton cappuchinoMedium = new JButton("MEDIUM");
cappuchinoMedium.setBounds(365, 117, 164, 45);
panel.add(cappuchinoMedium);
JButton cappuchinoLarge = new JButton("LARGE");
cappuchinoLarge.setBounds(539, 117, 164, 45);
panel.add(cappuchinoLarge);
JButton espressoSmall = new JButton("SMALL");
espressoSmall.setBounds(191, 191, 164, 45);
panel.add(espressoSmall);
JButton espressoMedium = new JButton("MEDIUM");
espressoMedium.setBounds(365, 191, 164, 45);
panel.add(espressoMedium);
JButton espressoLarge = new JButton("LARGE");
espressoLarge.setBounds(539, 191, 164, 45);
panel.add(espressoLarge);
JButton latteSmall = new JButton("SMALL");
latteSmall.setBounds(191, 274, 164, 45);
panel.add(latteSmall);
JButton latteMedium = new JButton("MEDIUM");
latteMedium.setBounds(365, 274, 164, 45);
panel.add(latteMedium);
JButton latteLarge = new JButton("LARGE");
latteLarge.setBounds(539, 274, 164, 45);
panel.add(latteLarge);
JButton mochaSmall = new JButton("SMALL");
mochaSmall.setBounds(191, 355, 164, 45);
panel.add(mochaSmall);
JButton mochaMedium = new JButton("MEDIUM");
mochaMedium.setBounds(365, 355, 164, 45);
panel.add(mochaMedium);
JButton mochaLarge = new JButton("LARGE");
mochaLarge.setBounds(539, 355, 164, 45);
panel.add(mochaLarge);
JButton macchiatoSmall = new JButton("SMALL");
macchiatoSmall.setBounds(191, 440, 164, 45);
panel.add(macchiatoSmall);
JButton macchiatoMedium = new JButton("MEDIUM");
macchiatoMedium.setBounds(365, 440, 164, 45);
panel.add(macchiatoMedium);
JButton macchiatoLarge = new JButton("LARGE");
macchiatoLarge.setBounds(539, 440, 164, 45);
panel.add(macchiatoLarge);
// COFFEE PANEL - END -----------------------------------------
// COLD DRINKS PANELS - START -----------------------------------------
JPanel panel_1 = new JPanel();
tabbedPane.addTab("Cold Drinks", null, panel_1, null);
panel_1.setLayout(new GridLayout(2, 2));
ImageIcon waterIcon, cokeIcon, spriteIcon, fantaIcon;
JButton waterButton, cokeButton, spriteButton, fantaButton;
panel_1.add(waterButton = new JButton(waterIcon = new ImageIcon("image/water.jpg")));
panel_1.add(cokeButton = new JButton(cokeIcon = new ImageIcon("image/coke.jpg")));
panel_1.add(spriteButton = new JButton(spriteIcon = new ImageIcon("image/sprite.jpg")));
panel_1.add(fantaButton = new JButton(fantaIcon = new ImageIcon("image/fanta.jpg")));
// COLD DRINKS PANEL - END -----------------------------------------
// SANDWICHES - START -----------------------------------------
JButton hamAndCheese, bltButton, tunaAndSweetcorn, chickenAndHam, hamAndCheesePanini;
JPanel panel_2 = new JPanel();
tabbedPane.addTab("Sandwiches", null, panel_2, null);
panel_2.setLayout(new GridLayout(5, 1));
panel_2.add(hamAndCheese = new JButton("Ham & Cheese"));
panel_2.add(bltButton = new JButton("BLT"));
panel_2.add(tunaAndSweetcorn = new JButton("Tuna & Sweetcorn"));
panel_2.add(chickenAndHam = new JButton("Chicken & Ham"));
panel_2.add(hamAndCheesePanini = new JButton("Ham & Cheese Panini"));
// SANDWICHES - END -----------------------------------------
// PASTRIES - START -----------------------------------------
JButton danishPastryJbt, muffinJbt, cinnamonRoleJbt, profiteroleJbt, eclairJbt, croissantJbt;
JPanel panel_3 = new JPanel();
panel_3.setLayout(new GridLayout(6, 1));
tabbedPane.addTab("Pastries", null, panel_3, null);
panel_3.add(danishPastryJbt = new JButton("Danish Pastry"));
panel_3.add(muffinJbt = new JButton("Muffin"));
panel_3.add(cinnamonRoleJbt = new JButton("Cinnamon Role"));
panel_3.add(profiteroleJbt = new JButton("Profiterole"));
panel_3.add(eclairJbt = new JButton("Eclair"));
panel_3.add(croissantJbt = new JButton("Croissant"));
orderDescription.setFont(new Font("Tahoma", Font.PLAIN, 20));
orderDescription.setBounds(845, 55, 214, 33);
contentPane.add(orderDescription);
// ORDER - END -----------------------------------------
// HEADING - START -----------------------------------------
JLabel lblUserEmployee = new JLabel("User: Employee1");
lblUserEmployee.setFont(new Font("Tahoma", Font.PLAIN, 20));
lblUserEmployee.setBounds(20, 11, 204, 33);
contentPane.add(lblUserEmployee);
JLabel lblJavaHouseCoffee = new JLabel("Java House Coffee");
lblJavaHouseCoffee.setHorizontalAlignment(SwingConstants.CENTER);
lblJavaHouseCoffee.setFont(new Font("Tahoma", Font.PLAIN, 40));
lblJavaHouseCoffee.setBounds(333, 11, 480, 60);
contentPane.add(lblJavaHouseCoffee);
// Setting the Time on the GUI
JLabel lblTime = new JLabel("");
String timeStamp = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss").format(Calendar.getInstance().getTime());
lblTime.setFont(new Font("Tahoma", Font.PLAIN, 18));
lblTime.setBounds(650, 0, 120, 30);
lblTime.setText(timeStamp + "");
lblTime.setVisible(true);
int delay = 1000; // milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String date = new java.text.SimpleDateFormat("HH:mm:ss")
.format(new java.util.Date(System.currentTimeMillis()));
lblTime.setText("" + Calendar.getInstance().getTime());
}
};
new Timer(delay, taskPerformer).start();
lblTime.setHorizontalAlignment(SwingConstants.CENTER);
lblTime.setFont(new Font("Tahoma", Font.PLAIN, 20));
lblTime.setBounds(914, 11, 244, 45);
contentPane.add(lblTime);
// add header of the table
String columns[] = new String[] { "Product Name", "Price" };
DefaultTableModel dtm = new DefaultTableModel(columns, 0);
dtm.setColumnIdentifiers(columns);
table.setModel(dtm);
// round the prices values pulled from DB to 2 Decimal Places
table.getColumnModel().getColumn(1).setCellRenderer(new DecimalFormatRenderer());
getContentPane().add(new JScrollPane(table));
table.setFont(new Font("Serif", Font.PLAIN, 18));
// add header of the table
JScrollPane scrollPaneTable = new JScrollPane(table);
scrollPaneTable.setBounds(845, 94, 329, 241);
contentPane.add(scrollPaneTable);
JPanel panel_5 = new JPanel();
scrollPaneTable.setColumnHeaderView(panel_5);
panel_5.setLayout(new BorderLayout());
JLabel totalJLabel = new JLabel("Total €");
totalJLabel.setFont(new Font("Tahoma", Font.PLAIN, 20));
totalJLabel.setBounds(899, 400, 63, 45);
contentPane.add(totalJLabel);
totalTF = new JTextField();
totalTF.setFont(new Font("Tahoma", Font.PLAIN, 20));
totalTF.setBounds(970, 400, 204, 45);
contentPane.add(totalTF);
totalTF.setColumns(10);
totalTF.setEditable(false);
delButton.setBounds(845, 346, 96, 45);
contentPane.add(delButton);
delButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
minusButton.setBounds(963, 346, 96, 45);
contentPane.add(minusButton);
minusButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
plusButton.setBounds(1083, 346, 87, 45);
contentPane.add(plusButton);
plusButton.setFont(new Font("Tahoma", Font.PLAIN, 15));
JLabel tenderedJLabel = new JLabel("Tendered €");
tenderedJLabel.setFont(new Font("Tahoma", Font.PLAIN, 20));
tenderedJLabel.setBounds(858, 456, 102, 45);
contentPane.add(tenderedJLabel);
tenderedTF = new JTextField();
tenderedTF.setFont(new Font("Tahoma", Font.PLAIN, 20));
tenderedTF.setBounds(972, 456, 202, 45);
contentPane.add(tenderedTF);
tenderedTF.setColumns(10);
JLabel changeJlabel = new JLabel("Change €");
changeJlabel.setFont(new Font("Tahoma", Font.PLAIN, 20));
changeJlabel.setBounds(878, 521, 84, 37);
contentPane.add(changeJlabel);
changeTF = new JTextField();
changeTF.setFont(new Font("Tahoma", Font.PLAIN, 20));
changeTF.setEditable(false);
changeTF.setBounds(972, 512, 202, 46);
contentPane.add(changeTF);
changeTF.setColumns(10);
// Delete row from JTable when clicked by user
delButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int viewIndex = table.getSelectedRow();
if (viewIndex != -1) {
// converts the row index in the view to the appropriate
// index in the model
int modelIndex = table.convertRowIndexToModel(viewIndex);
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.removeRow(modelIndex);
}
}
});
table.getTableHeader().setReorderingAllowed(false);
// HEADING - END -----------------------------------------
// Small Americano ActionListener
americanoSmall.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String query = "select ProductName, Price from product where ProductID = 24";
java.sql.PreparedStatement pst = connection.prepareStatement(query);
ResultSet rs = pst.executeQuery();
// Loop through the ResultSet and transfer in the Model
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i = 0; i < colNo; i++) {
objects[i] = rs.getObject(i + 1);
}
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(objects);
Stock s = new Stock();
// deduct stock from db from
// s1.deductStock(24);
total = total + s.getItemPrice(24);
totalTF.setText(String.valueOf(total));
totalTF.setText(String.format("%.2f", total));
}
TableModel model = (DefaultTableModel) table.getModel();
table.setModel(model);
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
americanoMedium.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String query = "select ProductName, Price from product where ProductID = 25";
java.sql.PreparedStatement pst = connection.prepareStatement(query);
ResultSet rs = pst.executeQuery();
// Loop through the ResultSet and transfer in the Model
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i = 0; i < colNo; i++) {
objects[i] = rs.getObject(i + 1);
}
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(objects);
Stock s = new Stock();
// deduct stock from db from
// s1.deductStock(24);
total = total + s.getItemPrice(25);
totalTF.setText(String.valueOf(total));
totalTF.setText(String.format("%.2f", total));
}
TableModel model = (DefaultTableModel) table.getModel();
table.setModel(model);
} catch (Exception e2) {
e2.printStackTrace();
}
}
});
americanoLarge.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String query = "select ProductName, Price from product where ProductID = 26";
java.sql.PreparedStatement pst = connection.prepareStatement(query);
ResultSet rs = pst.executeQuery();
// Loop through the ResultSet and transfer in the Model
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i = 0; i < colNo; i++) {
objects[i] = rs.getObject(i + 1);
}
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(objects);
Stock s = new Stock();
// deduct stock from db from
// s1.deductStock(24);
total = total + s.getItemPrice(26);
totalTF.setText(String.valueOf(total));
totalTF.setText(String.format("%.2f", total));
}
TableModel model = (DefaultTableModel) table.getModel();
table.setModel(model);
} catch (Exception e2) {
e2.printStackTrace();
}
}
});
cappuchinoSmall.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String query = "select ProductName, Price from product where ProductID = 30";
java.sql.PreparedStatement pst = connection.prepareStatement(query);
ResultSet rs = pst.executeQuery();
// Loop through the ResultSet and transfer in the Model
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i = 0; i < colNo; i++) {
objects[i] = rs.getObject(i + 1);
}
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(objects);
Stock s = new Stock();
// deduct stock from db from
// s1.deductStock(24);
total = total + s.getItemPrice(30);
totalTF.setText(String.valueOf(total));
totalTF.setText(String.format("%.2f", total));
}
TableModel model = (DefaultTableModel) table.getModel();
table.setModel(model);
} catch (Exception e2) {
e2.printStackTrace();
}
}
});
cappuchinoMedium.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String query = "select ProductName, Price from product where ProductID = 31";
java.sql.PreparedStatement pst = connection.prepareStatement(query);
ResultSet rs = pst.executeQuery();
// Loop through the ResultSet and transfer in the Model
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i = 0; i < colNo; i++) {
objects[i] = rs.getObject(i + 1);
}
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(objects);
Stock s = new Stock();
// deduct stock from db from
// s1.deductStock(24);
total = total + s.getItemPrice(31);
totalTF.setText(String.valueOf(total));
totalTF.setText(String.format("%.2f", total));
}
TableModel model = (DefaultTableModel) table.getModel();
table.setModel(model);
} catch (Exception e2) {
e2.printStackTrace();
}
}
});
cappuchinoLarge.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String query = "select ProductName, Price from product where ProductID = 32";
java.sql.PreparedStatement pst = connection.prepareStatement(query);
ResultSet rs = pst.executeQuery();
// Loop through the ResultSet and transfer in the Model
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int colNo = rsmd.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i = 0; i < colNo; i++) {
objects[i] = rs.getObject(i + 1);
}
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(objects);
Stock s = new Stock();
// deduct stock from db from
// s1.deductStock(24);
total = total + s.getItemPrice(32);
totalTF.setText(String.valueOf(total));
totalTF.setText(String.format("%.2f", total));
}
TableModel model = (DefaultTableModel) table.getModel();
table.setModel(model);
} catch (Exception e2) {
e2.printStackTrace();
}
}
});
JButton payButton = new JButton("Pay");
payButton.setBounds(970, 569, 209, 51);
contentPane.add(payButton);;
}// end class
答案 0 :(得分:1)
所以这是概念的基本证据。
这样做,它维护了添加/删除/更新的值的内部“代理”/“缓存”。通过这种方式,它能够使用事件信息简单地更新计数而无需重新迭代模型,这可能非常耗时。
当你创建一个新模型时,你应该将监听器附加到它上面,在填充它之前,这将使监听器有机会收到新行的通知并更新其内部状态。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private DefaultTableModel model;
private JTextField tallyField;
private double tally;
public TestPane() {
setLayout(new BorderLayout());
tallyField = new JTextField(10);
// When loading data, update this value to represent the total
// of the data that was loaded
tally = 0;
model = new DefaultTableModel(new Object[]{"Quanity", "Amount"}, 0);
model.addTableModelListener(new TableModelListener() {
private Map<Integer, Double> proxy = new HashMap<Integer, Double>();
private NumberFormat nf = NumberFormat.getCurrencyInstance();
@Override
public void tableChanged(TableModelEvent e) {
int firstRow = e.getFirstRow();
int lastRow = e.getLastRow();
double sum = 0;
for (int row = Math.min(firstRow, lastRow); row <= Math.max(firstRow, lastRow); row++) {
switch (e.getType()) {
case TableModelEvent.DELETE:
sum -= delete(row);
break;
case TableModelEvent.INSERT:
sum += add(row);
break;
case TableModelEvent.UPDATE:
sum -= delete(row);
sum += add(row);
break;
default:
break;
}
}
tally += sum;
tallyField.setText(nf.format(tally));
}
protected double delete(int row) {
double sum = 0;
if (proxy.containsKey(row)) {
sum = proxy.get(row);
}
proxy.remove(row);
return sum;
}
protected double add(int row) {
int qty = 0;
// I hope your model is better setup then mine
if (model.getValueAt(row, 0) instanceof String) {
qty = Integer.parseInt((String) model.getValueAt(row, 0));
} else if (model.getValueAt(row, 0) instanceof Integer) {
qty = (Integer) model.getValueAt(row, 0);
}
double amount = (Double) model.getValueAt(row, 1);
double rowTotal = qty * amount;
proxy.put(row, rowTotal);
return rowTotal;
}
});
JTable table = new JTable(model);
add(new JScrollPane(table));
JButton add = new JButton("Add");
JButton delete = new JButton("Delete");
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
double amount = 1.0; //Math.random() * 1000.0;
model.addRow(new Object[]{1, amount});
}
});
delete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] rows = table.getSelectedRows();
List<Integer> selection = new ArrayList<>(rows.length);
for (int row : rows) {
selection.add(row);
}
Collections.sort(selection);
Collections.reverse(selection);
for (int row : selection) {
model.removeRow(row);
}
}
});
JPanel footer = new JPanel(new BorderLayout());
JPanel buttons = new JPanel();
buttons.add(add);
buttons.add(delete);
footer.add(tallyField);
footer.add(buttons, BorderLayout.SOUTH);
add(footer, BorderLayout.SOUTH);
}
}
}
为什么我们需要缓存?因为删除行时,您无法再确定它的值。
如果我在一个真实的应用程序中这样做,我会创建一个实现TableModelListener
的简单类,但它提供了一个getter来检索tally
(因此tally
被封装到()类并使用观察者模式在tally
发生变化时生成通知。
这意味着当您加载数据时,您可以单独更新模型和“计数监视器”。当您需要时,更新屏幕上的必填字段。
这可能变得非常复杂,非常快。我做了类似的事情来生成一个自动计数系统,用于独立于模型计算行和列,因此系统没有耦合到模型结构,除了已知哪个行/列负责计数