tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
7
ZUGRIFFE
583
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    hesk hesk ist offline Mitglied Gold
    Registriert seit
    Oct 2007
    Beiträge
    192
    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?
     

  2. #2
    schlagi123 schlagi123 ist offline Rookie
    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
     

  3. #3
    hesk hesk ist offline Mitglied Gold
    Registriert seit
    Oct 2007
    Beiträge
    192
    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?
     

  4. #4
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist offline Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    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ß

    Fabio
     
    Bitte 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.

  5. #5
    hesk hesk ist offline Mitglied Gold
    Registriert seit
    Oct 2007
    Beiträge
    192
    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?
     

  6. #6
    hesk hesk ist offline Mitglied Gold
    Registriert seit
    Oct 2007
    Beiträge
    192
    Zitat Zitat von Fabio Hellmann Beitrag anzeigen
    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ß

    Fabio

    Das mag wohl stimmen. Aber da das Programm von mehreren Personen benutzt wird(mehrere PC's), schadet hier kein neuholen der gesamten Daten, weil dadurch auch gleich Änderungen von anderen geholt werden.
    Geändert von hesk (17.01.12 um 11:57 Uhr)
     

  7. #7
    hesk hesk ist offline Mitglied Gold
    Registriert seit
    Oct 2007
    Beiträge
    192
    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?
     

  8. #8
    genodeftest genodeftest ist offline Mitglied Brillant
    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)
    Code java:
    1
    
    System.out.println("Hallo");
    hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.
    ___________
    Ubuntu Bug #1: Microsoft has a majority market share
    Casecon: Projekt leiser Käse

Ähnliche Themen

  1. JTable: fireTableDataChanged
    Von Brucks im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 0
    Letzter Beitrag: 26.02.07, 19:12
  2. fireTableDataChanged()
    Von bleifresser im Forum Java
    Antworten: 4
    Letzter Beitrag: 17.08.05, 14:06