# NoSuchElementException



## stikio (8. Dez 2011)

Guten Tag,

meld mich mal wieder mit nem Problem. Bekomm die im Titel genannte Exception zufällig und recht selten.

Hab mal bisschen gegoogled und es soll wohl irgendwas mit meinem JTable zu tun haben. Kommt in der Fehlermeldung schliesslich was mit jScrollPane und Repaint vor ^^

mein Table bekommt in einem Thread n neues model zugewiesen. Das funktioniert trotz Fehlermeldung einwandfrei. Vielleicht kann mir hier jmd auf die Sprünge helfen wieso genau diese Fehlermeldung kommt 


```
Exception in thread "AWT-EventQueue-0" java.util.NoSuchElementException: Vector Enumeration
	at java.util.Vector$1.nextElement(Vector.java:348)
	at javax.swing.plaf.basic.BasicTableHeaderUI.getPreferredSize(BasicTableHeaderUI.java:793)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1660)
	at javax.swing.ViewportLayout.preferredLayoutSize(ViewportLayout.java:95)
	at java.awt.Container.preferredSize(Container.java:1788)
	at java.awt.Container.getPreferredSize(Container.java:1773)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1662)
	at javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:723)
	at java.awt.Container.layout(Container.java:1503)
	at java.awt.Container.doLayout(Container.java:1492)
	at java.awt.Container.validateTree(Container.java:1688)
	at java.awt.Container.validate(Container.java:1623)
	at javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:653)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1620)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
	at java.awt.EventQueue.access$000(EventQueue.java:101)
	at java.awt.EventQueue$3.run(EventQueue.java:666)
	at java.awt.EventQueue$3.run(EventQueue.java:664)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
```


----------



## VfL_Freak (8. Dez 2011)

Moin,



stikio hat gesagt.:


> Guten Tag,
> Hab mal bisschen gegoogled  .....



hab' auch mal ein bisschen gegoogled, aber Deinen Code nicht gefunden  

Gruß
Klaus


----------



## irgendjemand (8. Dez 2011)

was heißt hier "in einem Thread" ...

"AWT-EventQueue-0" ist nach meinems wissensstand aber der EDT ... also der thread in dem auf deinen button-klick reagiert und actionPerformed() gecallt wird ... also solltest du da erstmal nachsehen ...


*wobei sich das ganze nach nem type-missmatch dank TYPE-EREASURE anhört *gott ... danke dafür ... *ich könnte den jenigen der sich das hat einfallen lassen um abwärtskompatibel zu bleiben obwohl die class-version-number nich mal übereinstimmt ... immer noch töten ... echt ey**


@VFL
das is n guter insider : nach dem Code von TO googlen ... *muss ich mir merken ... ist fast so schön wie das mit der glaskugel =D*


----------



## ThreadPool (9. Dez 2011)

stikio hat gesagt.:


> Guten Tag,
> 
> meld mich mal wieder mit nem Problem. Bekomm die im Titel genannte Exception zufällig und recht selten.



Siehe javax.swing.plaf.basic: BasicTableHeaderUI.java. Zeile 791. Hier die Methode:


```
/**
  784        * Return the preferred size of the header. The preferred height is the
  785        * maximum of the preferred heights of all of the components provided
  786        * by the header renderers. The preferred width is the sum of the
  787        * preferred widths of each column (plus inter-cell spacing).
  788        */
  789       public Dimension getPreferredSize(JComponent c) {
  790           long width = 0;
  791           Enumeration enumeration = header.getColumnModel().getColumns();
  792           while (enumeration.hasMoreElements()) {
  793               TableColumn aColumn = (TableColumn)enumeration.nextElement();
  794               width = width + aColumn.getPreferredWidth();
  795           }
  796           return createHeaderSize(width);
  797       }
  798
```

Die Exception sagt dir primär das in dem Thread in welchem die GUI-Events verarbeitet werden eine Exception aufgetreten ist und zwar beim Durchlaufen der Tabellenspalten, sie Code. Die Bedingung der while-Schleife ist wahr, jedoch hat die enumeration danach "plötzlich" kein weiteres Element und läuft somit auf die NoSuchElementException. D.h. nach der Abfrage der Bedingung/oder während wurde die Datenstruktur von jmd anderem bearbeitet bevor nextElement() aufgerufen wird. 

Ich vermute es ist eine Verkettung ungünstiger Umstände, normalerweise sind fast alle Zugriffe auf einen Vector synchronisiert leider gehört die hasMoreElements-Methode nicht dazu. Würde der Iterator des Vectors verwendet werden, flöge unter Garantie eine ConcurrentModificationException. 

Gut, Swing erhebt auch keinen Anspruch Thread-Safe zu sein. Solche Exceptions fliegen oft wenn noch "gezeichnet" wird und man hintenrum irgendwas an der Datenstruktur ändert und das nicht über den EDT anstößt. Also schau mal bitte nach in welchem Thread du dein TableModel umsetzt, das sollte auch auf dem EDT-passieren.


----------



## ThreadPool (9. Dez 2011)

ThreadPool hat gesagt.:


> [...]
> 
> Ich vermute es ist eine Verkettung ungünstiger Umstände, normalerweise sind fast alle Zugriffe auf einen Vector synchronisiert leider gehört die hasMoreElements-Methode nicht dazu. Würde der Iterator des Vectors verwendet werden, flöge unter Garantie eine ConcurrentModificationException.



Das obere ist ein wenig missverständlich.  Selbst wenn die hasMoreElements-Methode synchronisiert wäre, könnte es zu so einem Fehlverhalten kommen. Es gibt immernoch ein Zeitfenster nach dem Prüfen der Bedingung und bevor die nächste Anweisung ausgeführt wird.


----------



## daha (4. Jul 2014)

Ich hatte eben auch das Problem. Ich hatte im gleichen Thread (gleiche Methode) ein TableChanged-Event abgefeuert mit fireTableCellUpdated(row, idx) bzw. fireTableRowsDeleted(row, row) und anschließend ein Event zur Änderung der Tabellenstruktur mit fireTableStructureChanged().

Da Swing nicht Thread-Safe ist, vermute ich, dass die Swing-Tabelle mit den Events durcheinander kommt (ohne Details der Java-Interna zu kennen). Abhilfe schaffte für mich die fireTableStructureChanged() in der Event-Queue hinten anzustellen mit folgendem Code:

```
SwingUtilities.invokeLater(new Runnable() {			
  @Override
  public void run() {
	fireTableStructureChanged();
  }
});
```


----------

