ERLEDIGT
JA
JA
ANTWORTEN
7
7
ZUGRIFFE
583
583
EMPFEHLEN
-
Hallo!
Ich verzweifle gerade ein wenig.
Ich hab eine JTable mit einem eigenen Model welches von AbstractTableModel ableitet.
Wenn in der Table etwas gelöscht wird, dann wird in der DB(MySql) ein Flag gesetzt,
anschließend alle Daten neu geholt, und im Model die Daten gesetzt:
Code java:1 2 3 4 5 6 7 8 9 10 11 12
/** * Setzt die Daten neu * * @param artikelList */ public void setData(List<Artikel> data) { this.data.clear(); this.data.addAll(data); this.fireTableDataChanged(); }
Nun tritt manchmal, aber nicht immer, folgender Fehler auf:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
java.lang.IndexOutOfBoundsException: Index: 1161, Size: 1161 at java.util.LinkedList.checkElementIndex(Unknown Source) at java.util.LinkedList.get(Unknown Source) at xxx.xxx.objects.jTableFilterHeader.ArtikelTableModel.getValueAt(ArtikelTableModel.java:157) at javax.swing.JTable.getValueAt(Unknown Source) at javax.swing.JTable.prepareRenderer(Unknown Source) at javax.swing.plaf.synth.SynthTableUI.paintCell(Unknown Source) at javax.swing.plaf.synth.SynthTableUI.paintCells(Unknown Source) at javax.swing.plaf.synth.SynthTableUI.paint(Unknown Source) at javax.swing.plaf.synth.SynthTableUI.update(Unknown Source) at javax.swing.JComponent.paintComponent(Unknown Source) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintToOffscreen(Unknown Source) at javax.swing.BufferStrategyPaintManager.paint(Unknown Source) at javax.swing.RepaintManager.paint(Unknown Source) at javax.swing.JComponent._paintImmediately(Unknown Source) at javax.swing.JComponent.paintImmediately(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.access$700(Unknown Source) at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$000(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)
Fällt jemanden etwas dazu ein?
-
17.01.12 07:43 #2
- Registriert seit
- Sep 2011
- Beiträge
- 6
Hallo Hesk,
ich habe es nicht ausprobiert, aber reicht es nicht einfach fireTableDataChanged() wegzulassen und die Tabelle zu repainten.
API:
Code :1 2
void fireTableDataChanged() Notifies all listeners that all cell values in the table's rows may have changed.
Ich glaube das er alle Zeilen durchgeht die auch vorher da waren (also eine zu viel). Probiere es man mit einem fireTableRowsDeleted(index, index).
AbstractTableModel
-
Hallo!
Soweit ich es verstanden habe:
fireTableDataChanged() alamiert alle Listener dass die Daten sich geändert haben.
Jetzt holen sich alle Listener die Daten neu.
Hierfür holen sie sich zuerst einmal die size:
Code java:1 2 3 4 5
@Override public int getRowCount() { return data.size(); }
Und irgendein Listener dürfte hier eines zu viel bekommen, und ich weiß nicht ganz warum.
Etwas zum Verständnis:
Alles was die GUI betrifft soll ja im EDT ausgeführt werden. Alles was länger dauert(Daten holen zb) in einem extra Thread.
Wenn in meinem Programm eine Zeile aus der Tabelle gelöscht wird, so wird ein Flag in MySql gesetzt und anschließend ein UpdateData ausgeführt:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
private class UpdateData extends Task<Void, Void> { /** * Konstruktor */ public UpdateData() { super(Application.getInstance()); } @Override protected Void doInBackground() throws Exception { List<Artikel> data = mySqlManager.getAllArtikel(); ((ArtikelTableModel)table.getModel()).setData(data); table.updateComboBoxes(); table.updateFilter(); return null; } @Override protected void finished() { super.finished(); System.out.println("update finished"); updateComponents(); } }
updateComponents macht nichts anderes als ein paar CheckBoxes anhand der neuen Daten zu setzen.
In doBackground hole ich mir zuerst alle Daten neu und setzte sie dann im Model.
Kann es nun sein dass wegen der oben genannten Logik fireTableDataChanged() erst im finished()-Teil ausgeführt werden soll? Da dadurch ja die GUI verändert wird, und die finished()-Methode im EDT läuft?
-
17.01.12 07:58 #4
Hi,
also rein aus Performancegründen würde ich auch eher die Methode fireTableRowsDeleted(int index, int index) aufrufen. So muss nicht die komplette (0-unendlich) neu geladen werden, sondern lediglich ein Listener/Row gelöscht werden. Das geht viel schneller.
Gruß
FabioBitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
-
Nach der Logik dass alles was die GUI betrifft im EDT ausgeführt werden soll, hab ich die updateData-Methode nun folgendermaßen geändert:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
private class UpdateData extends Task<Void, Void> { private List<Artikel> data; /** * Konstruktor */ public UpdateData() { super(Application.getInstance()); data = new ArrayList<Artikel>(); } @Override protected Void doInBackground() throws Exception { data = mySqlManager.getAllArtikel(); return null; } @Override protected void finished() { super.finished(); ((ArtikelTableModel)table.getModel()).setData(data); table.updateComboBoxes(); table.updateFilter(); System.out.println("update finished"); updateComponents(); } }
Der Fehler tritt nun nicht mehr auf.
Kann mir jemand vielleicht eine Erklärung liefern
?
-
-
Weil es in einem anderen Thread(http://www.tutorials.de/swing-java2d...rogressbar.htm) auch zu so einem Problem gekommen ist:
Weiß jemand wieso es zu Problemen(java.lang.ArrayIndexOutOfBoundsException) kommt wenn man das Model eine Table nicht im EDT ändert?
-
25.01.12 22:33 #8
- Registriert seit
- Jun 2009
- Beiträge
- 870
JTable ist eine Swing-Klasse, daher solltest du Daten darin auf gar keinen Fall von außerhalb des EDTs ändern, weil Swing-Klassen nicht threadsicher sind. Siehe dazu auch http://openbook.galileocomputing.de/...el_12_001.html
Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.Code java:1
System.out.println("Hallo");
___________
Ubuntu Bug #1: Microsoft has a majority market share
Casecon: Projekt leiser Käse
Ähnliche Themen
-
JTable: fireTableDataChanged
Von Brucks im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 0Letzter Beitrag: 26.02.07, 19:12 -
fireTableDataChanged()
Von bleifresser im Forum JavaAntworten: 4Letzter Beitrag: 17.08.05, 14:06





Zitieren
Login





