JTable 单元格更新不起作用
在我的应用程序中,我使用了一个类似于 this 示例的 java 表。我的问题是,当我更改单元格的值(即使在上面的示例中)时,数据模型不会更新,直到我单击不同的单元格。即使我在更改单元格值后单击表格下方的灰色区域,模型也不会更改。我认为原因是单元格保持聚焦,直到我点击另一个单元格。如何避免这种情况并在不单击表格单元格的情况下更新模型。预先感谢
我已经编辑了上面的示例代码来反映问题
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);
}
}
当您运行示例时,您可以在表格下方的文本区域中看到表格内容。更新单元格后,它应该出现在下面的文本框中。但是“setValueAt”方法不会调用,直到您单击不同的单元格。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是预期的行为:编辑后的值不会提交到支持模型,直到出现明确的用户手势,例如 fi 按 Enter 或 Tab 键跳出或单击表中的其他位置...
JTable 的一个奇怪之处(有些人称之为 bug :-) 是当将焦点转移到表格的“外部”时,默认情况下不会终止编辑。要强制它这样做,您需要像这样配置它:
顺便说一句(无关,只是为了理智):始终触发最细粒度的事件类型,这里将是 cellUpdated 而不是 dataChanged 锤子。
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:
BTW (unrelated, just for sanity): always fire the most fine-grained event type, here that would be a cellUpdated instead of the dataChanged hammer.
默认更新机制仅在单元格编辑器失去焦点时更改模型。使用 Tab 键退出单元格或单击不同的单元格将导致重要的“焦点丢失”事件,从而触发模型更改。
单击灰色区域没有任何效果,因为那里没有可以处理事件的活动元素 - 表会忽略单击。
如果您想更改此设置,则需要找到一个事件来告诉计算机用户“已完成编辑”。你怎么知道的?
ActionListener
(请参阅 http: //download.oracle.com/javase/tutorial/uiswing/components/textfield.html)。当您按 RETURN 时,它将被触发。在处理程序中,调用fireEditingStopped()
来触发“复制到模型”代码(请参阅 http://download.oracle.com/javase/tutorial/uiswing/components/table.html#editor)。您可以在表格下方添加一个“保存”按钮,并在其
ActionListner
中调用此代码:[编辑]请注意,添加“保存”按钮可能会扰乱用户的编辑“流程”(单击表格单元格、编辑、抓住鼠标、瞄准、单击保存、单击下一个单元格、返回键盘, 编辑, ...)
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, callfireEditingStopped()
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
:[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
you need to call super function also.