In my application I have use a java table which is similar to this example. My problem is when I change a value of a cell (even in above example) the data model doesn't get updated until I click on a different cell. Even I click on the gray area below the table after changing the cell value the model won't change. I think the reason is cell stay on focused until I click on a different cell. How can I avoid this and update the model without clicking on the table cell. Thanks in advance
I have edit the above sample code to reflect the problem
public class JTableDemo extends JApplet {
private JTextArea txt = new JTextArea(4, 20);
// The TableModel controls all the data:
class DataModel extends AbstractTableModel {
Object[][] data = { { "one", "two", "three", "four" },
{ "five", "six", "seven", "eight" },
{ "nine", "ten", "eleven", "twelve" }, };
// Prints data when table changes:
class TML implements TableModelListener {
public void tableChanged(TableModelEvent e) {
txt.setText(""); // Clear it
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[0].length; j++)
txt.append(data[i][j] + " ");
txt.append("\n");
}
}
}
public DataModel() {
addTableModelListener(new TML());
fireTableDataChanged();
}
public int getColumnCount() {
return data[0].length;
}
public int getRowCount() {
return data.length;
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public void setValueAt(Object val, int row, int col) {
data[row][col] = val;
System.out.println(val);
// Indicate the change has happened:
fireTableDataChanged();
}
public boolean isCellEditable(int row, int col) {
return true;
}
}
public void init() {
Container cp = getContentPane();
JTable table = new JTable(new DataModel());
cp.add(new JScrollPane(table));
cp.add(BorderLayout.SOUTH, txt);
}
public static void main(String[] args) {
run(new JTableDemo(), 350, 200);
}
public static void run(JApplet applet, int width, int height) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(applet);
frame.setSize(width, height);
applet.init();
applet.start();
frame.setVisible(true);
}
}
When you run the example you can see the table content in the text area below the table. After you update a cell it should appear in the text box below. But 'setValueAt' method wont call until you click on a different cell.
The default update mechanism only changes the model when the cell editor loses the focus. Either tabbing out of the cell or clicking in a different cell will cause the vital "focus lost" event which triggers the model change.
Clicking in the gray area has no effect because there are no active elements there which could process the event - the table ignores the click.
If you want to change this, you need to find an event which tells the computer that the user is "done with editing". How do you know that?
ActionListener
(see http://download.oracle.com/javase/tutorial/uiswing/components/textfield.html). It will get triggered when you press RETURN. In the handler, call fireEditingStopped()
to trigger the "copy to model" code (see http://download.oracle.com/javase/tutorial/uiswing/components/table.html#editor).You could add a "Save" button below the table and call this code in it's ActionListner
:
if(null != jTable.getCellEditor()) {
// there is an edit in progress
jTable.getCellEditor().stopCellEditing()
}
[EDIT] Note that adding a "Save" button can disrupt the edit "flow" of users (click table cell, edit, grab mouse, aim, click save, click next cell, go back to keyboard, edit, ...)