2009-11-13 20 views
7

Estoy subclasando JTable y utilizando un DefaultTableModel para modelar los datos de mi tabla. La siguiente clase configura JTable y agrega una fila al modelo.java.lang.ArrayIndexOutOfBoundsException: 0> = 0 intentando llenar 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(); 
} 

} 

A la hora/visualización de pantalla, la excepción siguiente:

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) 

estoy rasgando mi pelo - No he podido encontrar la causa raíz de este inmensamente sencillo uso caso.

+1

Nunca había visto este mensaje de excepción fuera de límites hasta el día de hoy. ¡Gracias por ayudarme a depurar mi aplicación! – Feanor

+0

por favor aprenda las convenciones de nomenclatura de Java y adhiérase a ellas – kleopatra

+0

@Kleopatra - ¿explicar? –

Respuesta

17

Creo que debe agregar columnas a su TableModel. Su código añade columnas de interfaz de usuario a la mesa, pero no los agrega al modelo

+1

@Chris: más específicamente, debe agregar columnas al TableModel ** en su lugar ** para agregarlas explícitamente a JTable. También vale la pena señalar que obtendrá un mejor rendimiento de una lista en lugar de un vector, ya que no está utilizando la sincronización (y no debería tener que pagar la sobrecarga) que viene con un vector. – rob

1

Desde el JTable.setAutoCreateColumnsFromModel() de la API: "Este método llama createDefaultColumnsFromModel si autoCreateColumnsFromModel cambia de falso a verdadero"

vector lanza ArrayIndexOutOfBoundsException - si el índice está fuera de rango (índice < 0 || índice> = tamaño())

supongo que el modelo de tabla no se encuentra las columnas, como se sugiere por Dmitry

4

Dmitry tiene razón. Reemplazar

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

con

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

y ahora conoce el Modelo de la columsn y no lanzará una excepción ya cuando intenta agregar una fila a un modelo que piensa que tiene 0 columnas

1

Reemplazar el código con el siguiente Aquí es necesario para eliminar primera fila única que debía ser reiterado para todas las filas

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

También me encontré con este problema (con un JList y un DefaultListModel). La respuesta de Dmitry es correcta.

Sin embargo, hay otra cosa: esta excepción también puede ser lanzada si no modifica el modelo en el subproceso de envío de eventos de Swing.

haciendo lo siguiente puede ayudar a evitar esta excepción:

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 Aunque la respuesta aceptada es correcta en este caso, esto es muy importante y me estaba causando un problema – BeRecursive

+0

@ Séverin su respuesta me ayudó, gracias por compartirlo –

0

Otra cuestión podría estar relacionado cuando se utiliza RowSorter. Cuando edite el modelo RowSorter, pruebe para volver a ordenar el modelo anterior. Se debe volver a crear automáticamente y volver a ejecutar en cada cambio de modelo de tabla.

se puede arreglar por

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

-Hayri

+0

no tiene sentido establecer la propiedad autoCreate _after_ configuración el modelo y la instalación manual de un nuevo rowSorter. En su lugar, establezca la propiedad en true _antes de_ establecer el modelo de tabla y listo. – kleopatra

+0

No. De API sabemos que 'Este método llama a createDefaultColumnsFromModel si autoCreateColumnsFromModel cambia de falso a verdadero'. Entonces puede agregarse luego. – FaithReaper

0

reemplazar

tabWindow.addTab(...); 

con

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

Tal situación puede hapen cuando cambie panel con separadores en oyente de action .

+0

aunque podría ser cierto en algunos contextos ... no tiene relación con la pregunta – kleopatra

1

Me enfrentaba a este problema porque estaba agregando columnas y filas a JTable, no al modelo.

La mejor manera es esta.

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

Dmitry es correcto, pero usted simplemente tiene que actualizar su modelo. Para hacer esto, agregue lo siguiente a su código:

DefaultTableModel dtm = (DefaultTableModel) table.getModel(); 
for (int c = 0; c < table.getColumnCount(); c++) { 
dtm.addColumn(table.getColumnName(c)); 
}