简体   繁体   English

JTable 单元格更新不起作用

[英]JTable Cell Update doesn't work

In my application I have use a java table which is similar to this example.在我的应用程序中,我使用了一个类似于示例的 java 表。 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.但是 'setValueAt' 方法在您单击不同的单元格之前不会调用。

That's expected behaviour: the edited value isn't committed to the backing model until an explicit user gesture, like fi pressing enter or tabbing out or clicking elsewhere in the table ...这是预期的行为:在明确的用户手势之前,编辑的值不会提交给支持模型,例如按 Enter 键或 Tab 键或单击表中的其他位置...

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. JTable 的一个奇怪之处(有人称之为错误 :-)是,在将焦点转移到表格的“外部”时,默认情况下不会终止编辑。 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.顺便说一句(无关,只是为了理智):总是触发最细粒度的事件类型,这里将是 cellUpdated 而不是 dataChanged 锤子。

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?你怎么知道?

[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, ...) [编辑]请注意,添加“保存”按钮会扰乱用户的编辑“流程”(单击表格单元格、编辑、抓取鼠标、瞄准、单击保存、单击下一个单元格、返回键盘、编辑……)

For my case对于我的情况

public void setValueAt(Object val, int row, int col) {
  data[row][col] = val;
  System.out.println(val);
  // Indicate the change has happened:
  fireTableDataChanged();
}

you need to call super function also.您还需要调用超级函数。

public void setValueAt(Object val, int row, int col) {
  data[row][col] = val;
  System.out.println(val);
  // Indicate the change has happened:
  fireTableDataChanged();
  super.setValueAt(val,row,col);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM