最小化/最大化后,JTable 重置为原始状态



我有一个 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;
}

您似乎正在直接更改DataModeldataVector。这不是你应该做事的方式。您应该做的是通过DataModel接口(使用模型索引(或通过JTable接口(使用视图索引(更改单元格值。

所以我的建议是改变你的程序来做我刚刚告诉的。但是,如果您坚持按照自己的方式工作,则可以向DataModel发出有关其底层dataVector变化的信号,如果您的DataModel扩展到DefaultTableModel,我认为它确实或实现了AbstractTableModel接口。在对整个模型进行更改后调用documents.fireTableDataChanged();,或者在使用 documents.fireTableCellUpdated(rowModelId,colModelId); 更改单元格时调用更精细的 。


您犯的另一个错误是混淆了视图索引和模型索引。如果在表中对行进行排序和/或移动列,则这些内容可能会有所不同。在使用从视图返回的索引为模型编制索引之前,应使用 JTable.convertRowIndexToModelJTable.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 的理解,您的代码中可能会有更多的问题。

最新更新