Pregunta

Background I have a JTable called table, and I have a column that is not part of the DefaultTableModel so its invisible:

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

I add the respective rows like this:

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++;
    }

Where curSong is the the current song object that it is adding, the SongObject contains all data about the song. The toString() returns the title of the song.

Problem: The problem is that when I try to access the column like this:

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

It throws a java.lang.ArrayIndexOutOfBoundsException: 4 >= 4 exception. Can anyone explain why and propose a solution? Thanks in advance :)

¿Fue útil?

Solución 2

Thanks to Aqua I overrode the following:

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);
        }
    });

Then I accessed the item in the fifth column (which is not part of the model!) like this:

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

Sorry for the messy code but it worked. Home I could help someone with a similar problem. The solution just misses the justifyRows() method found in DefaultTableModel

Otros consejos

DefaultTableModel.addRow() somewhere down the chain executes private justifyRows() method, which trims the unused columns from the row to the size equal to getColumnCount(). So the fifth column is never added to the model. As a result, you get ArrayIndexOutOfBoundsException when you're attempting to access this column.

If you need access to the actual SongObject then you can have a custom model that would return SongObject for a given row index. Make an extension of AbstractTableModel. See How to Use Tables tutorial for examples.

As an alternative, you can still use SongObject in a visible column. Just use a custom renderder that would renderer SongObject as a string for example. See Using Custom Renderers for details. You can reuse DefaultTableModel in this case.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top