我有一个 Swing 屏幕,打开时有一个装满 itenms 的 JTable 和一个空的 JList。从按钮发送事件后,我将 itens 从 JTable 移动到 JList,使 JTable 为空,JList 充满我想要的项目。但是我有一个奇怪的问题,当帧最小化然后最大化时,JTable 会再次恢复到所有项目的原始状态。
当我从保留 JTable 值的数组中删除项目时,它不应该发生。我曾经sysout
在控制台上观察数组大小,因为正在删除项目,我确信最终它的大小已经归零。
另外,我将断点放在将数组值检索为 JTable 的getXXX
中,并且我自己放置了一个repaint()
方法来覆盖其原始方法,并且我没有中断点暂停任何一个。
所以。。。。我不知道它从哪里获得重置为原始状态的值!
最后,我刚刚注意到当单击表格的区域时会发生这种情况,因此将 JFrame 更改为没有最小化/最大化按钮的 JDialog 根本无法解决问题。
我不知道一些代码是否有帮助,但无论如何,我有一个init
的方法只是为了初始化 JTable。
private void initTable(Object rowData[][]) {
documents = rowData;
dataModel = new DataModel(rowData, COLUMNS);
scrollPane = new JScrollPane();
scrollPane.setBounds(13, 188, 300, 148);
contentPane.add(scrollPane);
table = new JTable(dataModel) {
@Override
public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
super.changeSelection(rowIndex, columnIndex, true, false);
}
};
scrollPane.setViewportView(table);
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(30);
table.getColumnModel().getColumn(1).setPreferredWidth(260);
table.setCellSelectionEnabled(true);
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(false);
ListSelectionModel cellSelectionModel = table.getSelectionModel();
cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow >= 0) {
if (selectedColumn == 0) {
Boolean valorCol= (Boolean) documents[selectedRow][0];
if (valorCol== true) {
documents[selectedRow][0] = false;
}
else {
documents[selectedRow][0] = true;
}
}
}
}
table.clearSelection();
}
});
}
_______编辑_______
我删除项目的方式是由列表而不是原始数组组成的。在从 JTable 中移动项目的过程之后,我调用上面的方法,但这次列表为空。这是"缺失的代码">
移动所有项目后...
Object[][] documentsMoved = buildTableDataFromList(myVO.getDocuments());
initTable(documentsMoved );
private Object[][] buildTableDataFromList(List<MyVO> list) {
Object[][] retorno = new Object[list.size()][COLUMNS.length];
for (int i = 0; i < list.size(); i++) {
MyVO vo = lista.get(i);
retorno[i][CHECK_COL] = Boolean.TRUE;
retorno[i][DOC_COL] = vo.getFileName();
}
return retorno;
}
您似乎正在直接更改DataModel
的dataVector
。这不是你应该做事的方式。您应该做的是通过DataModel
接口(使用模型索引(或通过JTable
接口(使用视图索引(更改单元格值。
所以我的建议是改变你的程序来做我刚刚告诉的。但是,如果您坚持按照自己的方式工作,则可以向DataModel
发出有关其底层dataVector
变化的信号,如果您的DataModel
扩展到DefaultTableModel
,我认为它确实或实现了AbstractTableModel
接口。在对整个模型进行更改后调用documents.fireTableDataChanged();
,或者在使用 documents.fireTableCellUpdated(rowModelId,colModelId);
更改单元格时调用更精细的 。
您犯的另一个错误是混淆了视图索引和模型索引。如果在表中对行进行排序和/或移动列,则这些内容可能会有所不同。在使用从视图返回的索引为模型编制索引之前,应使用 JTable.convertRowIndexToModel
和 JTable.convertColumnIndexToModel
转换这些视图索引。
将此应用于您的选择侦听器:
你应该做什么:
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow >= 0) {
if (table.convertColumnIndexToModel(selectedColumn) == 0) {
Boolean valorCol = (Boolean) table.getValueAt(selectedRow,selectedColumn);
if (valorCol == true) {
table.setValueAt(Boolean.FALSE,selectedRow,selectedColumn);
}
else {
table.setValueAt(Boolean.TRUE,selectedRow,selectedColumn);
}
}
}
}
table.clearSelection();
}
});
如果你坚持按照你的方式工作:
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow >= 0) {
int rowModelId = table.convertRowIndexToModel(selectedRow);
int colModelId = table.convertColumnIndexToModel(selectedColumn);
if (colModelId == 0) {
Boolean valorCol= (Boolean) documents[rowModelId][0];
if (valorCol== true) {
documents[rowModelId][0] = false;
}
else {
documents[rowModelId][0] = true;
}
dataModel.fireTableCellUpdated(rowModelId,0);
}
}
}
table.clearSelection();
}
});
唉,我认为随着您对 swing 和 JTable 的理解,您的代码中可能会有更多的问题。