2009-11-13 4 views
7

Я подклассифицирую JTable и используя модель DefaultTableModel для моделирования данных моей таблицы. Следующий класс устанавливает JTable и добавляет одну строку к модели.java.lang.ArrayIndexOutOfBoundsException: 0> = 0 пытается заполнить JTable

import java.io.File; 
import java.util.Iterator; 
import java.util.Vector; 

import javax.swing.JTable; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumn; 

public class SelectedFileTable extends JTable { 
Vector<File> SelectedFiles = new Vector<File>(); 
DefaultTableModel Model = new DefaultTableModel(); 

TableColumn ColumnName  = new TableColumn(); 
TableColumn ColumnSize  = new TableColumn(); 
TableColumn ColumnRmIcon = new TableColumn(); 

ImageFilenameFilter Filter = new ImageFilenameFilter(); 

public SelectedFileTable() { 
    super(); 
    this.setModel(Model); 

    ColumnName.setHeaderValue(new String("Name")); 
     ColumnName.setMinWidth(200); 
    ColumnSize.setHeaderValue(new String("Size")); 
     ColumnSize.setMinWidth(50); 
     ColumnSize.setMaxWidth(100); 
    ColumnRmIcon.setHeaderValue(new String("Remove?")); 
     ColumnRmIcon.setMaxWidth(100); 
     ColumnRmIcon.setResizable(false); 

    this.addColumn(ColumnName); 
    this.addColumn(ColumnSize); 
    this.addColumn(ColumnRmIcon); 

    this.setShowVerticalLines(false); 
    this.setShowHorizontalLines(true); 
this.setAutoCreateColumnsFromModel(true); 

this.addFile(new File("C:/temp/cfk.jpg")); 
} 
public void addFile(File file) { 
    System.out.println("FileTable adding: " + file.getName()); 
    if (file.isDirectory()) { 
     for (File f : file.listFiles(Filter)) { 
      this.addFile(f); 
     } 
    } else { 
     if (Filter.accept(file)) { 
      System.out.println("Accepting file; " + file.getName()); 
      SelectedFiles.add(file); 
      { 
       String name = file.getName(); 
       Long size = new Long(file.length()); 
       String tempstr = new String("X"); 

       System.out.println("RowItems before: " + Integer.toString(Model.getRowCount())); 
       Model.addRow(new Object[] { name, size, tempstr }); 
       Model.fireTableDataChanged(); 
       System.out.println("RowItems start : " + Integer.toString(Model.getRowCount())); 
      } 
      System.out.println("Done Accepting file; " + file.getName()); 
     } 
    } 
} 
public Iterator<File> iterator() { 
    return SelectedFiles.iterator(); 
} 

} 

На дисплее времени/визуализации, следующее исключение:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0 
at java.util.Vector.elementAt(Vector.java:432) 
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:622) 
at javax.swing.JTable.getValueAt(JTable.java:1903) 
at javax.swing.JTable.prepareRenderer(JTable.java:3911) 
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2072) 
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1974) 
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1897) 
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142) 
at javax.swing.JComponent.paintComponent(JComponent.java:743) 
at javax.swing.JComponent.paint(JComponent.java:1006) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paint(JComponent.java:1015) 
at javax.swing.JViewport.paint(JViewport.java:728) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paint(JComponent.java:1015) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paint(JComponent.java:1015) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paint(JComponent.java:1015) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paint(JComponent.java:1015) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paint(JComponent.java:1015) 
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559) 
at javax.swing.JComponent.paintChildren(JComponent.java:843) 
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4979) 
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4925) 
at javax.swing.JComponent.paint(JComponent.java:996) 
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21) 
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60) 
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97) 
at java.awt.Container.paint(Container.java:1709) 
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248) 
at sun.awt.RepaintArea.paint(RepaintArea.java:224) 
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:254) 
at java.awt.Component.dispatchEventImpl(Component.java:4060) 
at java.awt.Container.dispatchEventImpl(Container.java:2024) 
at java.awt.Window.dispatchEventImpl(Window.java:1791) 
at java.awt.Component.dispatchEvent(Component.java:3819) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463) 
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110) 

Я разрывая мои волосы - я не смог найти причину этого очень простого использования дело.

+1

Я никогда не видел этого недоступного сообщение об исключении до сегодняшнего дня. Спасибо, что помогли мне отладить мое приложение! – Feanor

+0

, пожалуйста, изучите соглашения об именах java и придерживайтесь их – kleopatra

+0

@ Клеопатра - объясните? –

ответ

17

Думаю, вам нужно добавить столбцы в TableModel. Ваш код добавляет столбцы UI к столу, но не добавляет их к модели

+1

@Chris: более конкретно, вы должны добавить столбцы вместо TableModel ** вместо явно добавляя их в JTable. Также стоит отметить, что вы получите лучшую производительность из списка вместо Vector, так как вы не используете синхронизацию (и не должны платить за накладные расходы), которая поставляется с Vector. – rob

1

С JTable.setAutoCreateColumnsFromModel() API: «Этот метод вызывает createDefaultColumnsFromModel если autoCreateColumnsFromModel изменяется от ложного к истине»

Вектор бросает ArrayIndexOutOfBoundsException - если индекс находится вне диапазона (индекс < 0 || индекс> = размер())

Я думаю, модель таблицы отсутствует столбцы, как это было предложено Дмитрий

4

Дмитрий прав. Заменить

this.addColumn(ColumnName); 
this.addColumn(ColumnSize); 
this.addColumn(ColumnRmIcon); 

с

Model.addColumn(ColumnName); 
Model.addColumn(ColumnSize); 
Model.addColumn(ColumnRmIcon); 

и теперь модель знает о columsn и не будет сгенерировано исключение больше при попытке добавить строку в модель, которая думает, что она имеет 0 столбцов

1

Замените код следующего Здесь вам нужно удалить первую строку только, что должно быть итерированной для всех строк

private void refreshTable() { 

    int rowCount= model.getRowCount(); 

    // System.out.println(rowCount); 

    for(int i=0;i<rowCount;i++){ 
     model.removeRow(0); 
     //System.out.println(i); 
    } 

} 
19

Я тоже занимался этой проблемой (с помощью JList и DefaultListModel). Ответ Дмитрия прав.

Однако есть и другая вещь: Это исключение также может быть выброшено, если вы не измените модель в Swing's Dispatch Thread.

Выполнение следующих может помочь вам избежать этого исключения:

SwingUtilities.invokeLater(new Runnable(){public void run(){ 
    //Update the model here 
}}); 

http://www.javakb.com/Uwe/Forum.aspx/java-gui/3012/JList-JScrollPane-DefaultListModel-Updating

+1

+1 Несмотря на то, что принятый ответ верен в этом случае, это очень важно и вызывает у меня проблему – BeRecursive

+0

@ Séverin, на ваш ответ помог мне, спасибо, что поделились им. –

0

Другой вопрос может быть связано при использовании RowSorter. Когда вы редактируете модель RowSorterпытается пересортировать старую модель. Он должен автоматически воссоздаваться и повторно запускаться при каждом изменении модели таблицы.

Вы можете исправить это

tableModel = new DefaultTableModel(data, columnNames); 
jTableSentence.setModel(tableModel); 
jTableSentence.setRowSorter(new TableRowSorter(tableModel)); 
jTableSentence.setAutoCreateRowSorter(true); 

-Hayri

+0

не имеет смысла устанавливать свойство autoCreate _after_ setting модель и вручную установить новый rowSorter. Вместо этого установите для свойства значение true _before_, задав значение tableModel и сделайте. – kleopatra

+0

Нет. Из API мы знаем, что 'Этот метод вызывает createDefaultColumnsFromModel, если autoCreateColumnsFromModel изменяется с false на true'. Поэтому он может быть добавлен впоследствии. – FaithReaper

0

заменить

tabWindow.addTab(...); 

с

SwingUtilities.invokeLater(new Runnable() { 
    @Override public void run() { 
     tabWindow.addTab(...); 
    } 
}); 

Такая ситуация может hapen при изменении с закладками в действии слушателя ,

+0

, хотя может быть правдой в некоторых контекстах ... это совершенно не связано с вопросом – kleopatra

1

Я столкнулся с этой проблемой, потому что я добавлял столбцы и строки в JTable не к модели.

лучший способ - это.

Object[][]rows = new Object[ ][ ] { {"a","b"} , {"c","d"} }; 
Object[]columns = new Object[] {"column1","column2"}; 
JTable table = new JTable(); 
table.setModel(new DefaultTableModel(rows,columns)); 
0

Дмитрий прав, но вам просто нужно обновить свою модель. Чтобы сделать это, добавьте следующую строку в ваш код:

DefaultTableModel dtm = (DefaultTableModel) table.getModel(); 
for (int c = 0; c < table.getColumnCount(); c++) { 
dtm.addColumn(table.getColumnName(c)); 
} 
Смежные вопросы