Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTable Cell Update doesn't work

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.

like image 211
nath Avatar asked Oct 31 '11 08:10

nath


1 Answers

That's expected behaviour: the edited value isn't committed to the backing model until an explicit user gesture, like f.i. pressing enter or tabbing out or clicking elsewhere in the table ...

One oddity (some call it bug :-) of JTable is that editing isn't by default terminated when transfering focus to the "outside" of the table. To force it doing so, you need to configure it like:

  table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

BTW (unrelated, just for sanity): always fire the most fine-grained event type, here that would be a cellUpdated instead of the dataChanged hammer.

like image 96
kleopatra Avatar answered Oct 06 '22 11:10

kleopatra