Swing - 访问时不可见的列抛出异常

时间:2014-01-06 21:50:48

标签: java swing jtable indexoutofboundsexception defaulttablemodel

背景 我有一个名为table的JTable,我有一个不属于DefaultTableModel的列,因此它不可见:

final JTable table = new JTable(new DefaultTableModel(new Object[]{"Title", "Artist",
"Album", "Time"}, 0)

我添加了相应的行:

int upTo = songList.size();
    int idx = 0;
    while (idx < upTo) {
        SongObject curSong = songList.get(idx);
        model.addRow(new Object[]{
curSong.toString(), 
curSong.getArtist(), 
"-", 
curSong.getDuration(), 
curSong});
        idx++;
    }

如果curSong是它正在添加的当前歌曲对象,则SongObject包含有关该歌曲的所有数据。 toString()返回歌曲的标题。

问题: 问题是当我尝试像这样访问列时:

SongObject songToPlay = (SongObject) table.getModel().getValueAt(table.getSelectedRow(), 4);

抛出java.lang.ArrayIndexOutOfBoundsException: 4 >= 4个异常。 谁能解释原因并提出解决方案? 在此先感谢:)

2 个答案:

答案 0 :(得分:1)

链中某处的

DefaultTableModel.addRow()执行私有justifyRows()方法,该方法将行中未使用的列修剪为等于getColumnCount()的大小。因此,第五列永远不会添加到模型中。因此,当您尝试访问此列时,会收到ArrayIndexOutOfBoundsException

如果您需要访问实际的SongObject,那么您可以拥有一个自定义模型,该模型将为给定的行索引返回SongObject。扩展AbstractTableModel。有关示例,请参阅How to Use Tables教程。

作为替代方案,您仍然可以在可见列中使用SongObject。例如,只需使用将SongObject渲染为字符串的自定义渲染器。有关详细信息,请参阅Using Custom Renderers。在这种情况下,您可以重复使用DefaultTableModel

答案 1 :(得分:0)

感谢Aqua我覆盖了以下内容:

final JTable table = new JTable(new DefaultTableModel(new Object[]{"Title", "Artist", "Album", "Time"}, 0) {

        @Override
        public void addRow(Object[] rowData) {
            Vector blah = DefaultTableModel.convertToVector(rowData);
            insertRow(super.getRowCount(), blah);
        }

        @Override
        public void insertRow(int row, Vector data) {
            super.dataVector.insertElementAt(data, row);
            super.fireTableRowsInserted(row, row);
        }
    });

然后我访问了第五列中的项目(不是模型的一部分!),如下所示:

SongObject songToPlay = (SongObject) table.getModel().getValueAt(table.convertRowIndexToModel(
                                table.getSelectedRow()), 4); //get the value at the VIEW location NOT THE MODEL collection

对于凌乱的代码感到抱歉,但它有效。家我可以帮助有类似问题的人。解决方案只是错过了justifyRows()

中的DefaultTableModel方法