I am trying to use a JTable with the first column predefined. The user enters data into the 2nd column only (Quantity). Then I calculate the final income by multiplying the Service and Quantity columns and display it in the third column, Income.
|Service | Quantity | Income |$40.00 | X | |$40.00 | 3 | 120
Here user inputs "3" because she did "3" of service X today at $40 each. The user can only update the Quantity column. The Income column will be calculated by the system.
What type of listener should I use? I was using a TableModelListener
but when I want to update Income to 120 by calling setValue = $120
it fires off a TableListenerEvent
and hence an infinite loop.
Shoul开发者_运维问答d I use an ActionEvent
, a ColumnListener
or something else?
Also, I want the "focus" to increment down the rows, always staying on the second column (the column the user edits).
for Listning changes into TableCell you have to implements TableModelListener for example
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableProcessing extends JFrame {
private static final long serialVersionUID = 1L;
private JTable table;
private String[] columnNames = {"Item", "Quantity", "Price", "Cost"};
private Object[][] data = {
{"Bread", new Integer(1), new Double(1.11), new Double(1.11)},
{"Milk", new Integer(1), new Double(2.22), new Double(2.22)},
{"Tea", new Integer(1), new Double(3.33), new Double(3.33)},
{"Cofee", new Integer(1), new Double(4.44), new Double(4.44)}};
private TableModelListener tableModelListener;
public TableProcessing() {
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override// Returning the Class of each column will allow different renderers
public Class getColumnClass(int column) { // to be used based on Class
return getValueAt(0, column).getClass();
}
@Override // The Cost is not editable
public boolean isCellEditable(int row, int column) {
int modelColumn = convertColumnIndexToModel(column);
return (modelColumn == 3) ? false : true;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
//http://stackoverflow.com/questions/7188179/jtable-focus-query/7193023#7193023
table.setCellSelectionEnabled(true);
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
InputMap map = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
map.put(tab, "selectNextRowCell");
//http://stackoverflow.com/questions/7188179/jtable-focus-query/7193023#7193023
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
setTableModelListener();
}
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 == 1 || column == 2) {
TableModel model = table.getModel();
int quantity = ((Integer) model.getValueAt(row, 1)).intValue();
double price = ((Double) model.getValueAt(row, 2)).doubleValue();
Double value = new Double(quantity * price);
model.setValueAt(value, row, 3);
}
}
}
};
table.getModel().addTableModelListener(tableModelListener);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TableProcessing frame = new TableProcessing();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
精彩评论