Aktualliesieren einer Tabelle Zurlaufzeit

Die Klasse DBox erzeugt eine Hashmap und füllt diese. Per Interface übertrage ich die Hashmap in die Klasse TimerDaten.

In der Klasse DBOX mach ich folgendes
Code:
DboxWatcherInterface obj = new TimerDaten();
obj.setHashmap(map);

Klasse TimerDaten speichert die übertragene Hashmap in ihrer eigene Hashmap und ruft anschliessend die Methode timerUpdate auf, wo die fireTableDataChanged() Methode drinnen steht.
Code:
     public void setHashmap(Hashmap map) {
          this.map = map;
          x.tableUpdate();
     }

Die Map wird an die Klasse TimerDaten wirklich übertragen. Nur die JTable übernimmt nicht die neuen Hashmap daten.

Hier der komplette Code der Klasse TimerDaten

Code:
package dboxwatcher2_0;

import java.awt.*;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.*;
import java.util.*;

public class TimerDaten extends JFrame implements DBoxWatcherInterface {
    BorderLayout borderLayout1 = new BorderLayout();
    HashMap map;
    JTable timerTable;
    MyTableModel x;
    TableSorter sorter;

    public TimerDaten() {
        try {
            jbInit();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    private void jbInit() throws Exception {
        x = new MyTableModel();
        sorter = new TableSorter(new MyTableModel()); 
        timerTable = new JTable(sorter);
        sorter.setTableHeader(timerTable.getTableHeader());
        sorter.setSortingStatus(0,1);
        timerTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
        JScrollPane scrollPane = new JScrollPane(timerTable);
        getContentPane().setLayout(borderLayout1);
        this.getContentPane().add(scrollPane);
    }

    public void getHashmap(HashMap map) {
        System.out.println("GetHashmap");
        this.map = map;
        x.tableUpdate();
    }

    class MyTableModel extends AbstractTableModel{
        private String[] spaltenNamen = {"Nr.", "Wdh.", "Start-Zeit","Stop-Zeit","Sender"};

        private Object[][] zeilen = new Object[map.size()][5];

        public MyTableModel(){
            Object[] zeilenKeys= map.keySet().toArray();
            for(int zeile=0; zeile<map.size(); zeile++){
                zeilen[zeile][0] = ((DboxTimerDaten)(map.get(zeilenKeys[zeile]))).getEventId();
                zeilen[zeile][1] = ((DboxTimerDaten)(map.get(zeilenKeys[zeile]))).getEventRepeat();
                zeilen[zeile][2] = ((DboxTimerDaten)(map.get(zeilenKeys[zeile]))).getAlarmTime();
                zeilen[zeile][3] = ((DboxTimerDaten)(map.get(zeilenKeys[zeile]))).getStopTime();
                zeilen[zeile][4] = ((DboxTimerDaten)(map.get(zeilenKeys[zeile]))).getData();
            }
        }

        public int getColumnCount() {
            //System.out.println("Spalten" + spaltenNamen.length);
            return spaltenNamen.length;
        }

        public void tableUpdate() {
            System.out.println("ICH BIN DA");
            fireTableDataChanged();
        }

        public int getRowCount() {
            //System.out.println("Zeilen" + zeilen.length);
            return zeilen.length;
        }

        public String getColumnName(int col) {
            //System.out.println(spaltenNamen[col]);
            return spaltenNamen[col];
        }

         public Object getValueAt(int row, int col) {
             //System.out.println(zeilen[row][col]);
             return zeilen[row][col];
         }
    }
}

Vielen Dank im voraus

Ich steh da voll auf der Leitung, so ein GUI Programmieren ist nicht so einfach *g*
 
Frankster hat gesagt.:
Code:
    public void getHashmap(HashMap map) {
        System.out.println("GetHashmap");
        this.map = map;
        x.tableUpdate();
    }

    class MyTableModel extends AbstractTableModel{
         public Object getValueAt(int row, int col) {
             //System.out.println(zeilen[row][col]);
             return zeilen[row][col];
         }
    }
}

Siehe oben. Was fällt Dir auf?
--> Du greifst in der getValueAt überhaupt nicht auf die map zu. D.h. Du setzt zwar die map, benutzt die Daten aber nicht. Hatte ich oben bereits drauf hingewiesen:
"Du musst lediglich die Daten im TableModel aktualisieren, auf die u.a. bei getValueAt() zugegriffen wird."
 
Ich weiss langsam nerve ich *g*

Aber stimmt das ;-)

Code:
        public Object getValueAt(int row, int col) {
            this.zeilen = new Object[map.size()][5];
            this.zeilenKeys = map.keySet().toArray();
            for (int zeile = 0; zeile < map.size(); zeile++) {
                zeilen[zeile][0] = ((DboxTimerDaten) (map.get(zeilenKeys[zeile]))).
                                   getEventId();
                zeilen[zeile][1] = ((DboxTimerDaten) (map.get(zeilenKeys[zeile]))).
                                   getEventRepeat();
                zeilen[zeile][2] = ((DboxTimerDaten) (map.get(zeilenKeys[zeile]))).
                                   getAlarmTime();
                zeilen[zeile][3] = ((DboxTimerDaten) (map.get(zeilenKeys[zeile]))).
                                   getStopTime();
                zeilen[zeile][4] = ((DboxTimerDaten) (map.get(zeilenKeys[zeile]))).
                                   getData();
            }
            return zeilen[row][col];
        }

Nur wann und wo setzt ich jetzt das fireTableDataChange() ein ?
Wenn ich dies direkt im getValue() mache, dann bekomm ich nur mehr Exceptions.

UND, wie schaff ich es dass die Daten sofort aktualisiert werden. Ich seh erst den neuen Inhalt wenn ich auf den TableHeader 2 mal klicke.
Irgendwo gehört irgendwas repainted ;)

Mfg
Frankster
 
>Aber stimmt das ;-)

Ja, der Code sieht jetzt OK aus.

>Nur wann und wo setzt ich jetzt das fireTableDataChange() ein ?

Üblicherweise nach der Stelle, wo die Datenbasis für das getValueAt verändert wird.

>Wenn ich dies direkt im getValue() mache, dann bekomm ich nur mehr Exceptions.

Besser in/nach dem setHashmap().

>UND, wie schaff ich es dass die Daten sofort aktualisiert werden. Ich seh erst den neuen Inhalt wenn ich auf den TableHeader 2 mal klicke.
>Irgendwo gehört irgendwas repainted ;)

Normalerweise reicht ein fireTableDataChanged. Es sei denn, es werden nicht nur die Daten geändert - dann probiere fireTableStructureChanged - oder Du arbeitest mit Threads - dann geht das irgendwie mit SwingUtilities.invokeLater(), aber damit bin ich nicht so bewandert.

>Mfg
>Frankster
 
Da muss man Tom fragen ;)

Er hat mir auch mal den Tipp gegeben mit SwingUtilities.invokeLater(). Ich habe SwingUtilities.invokeAndWait benutzt, weil bei invokeLater() puffert er es wohl und schreibt dann irgendwann und da hat er mir die ersten Strings immer mit dem zuletzt hinzugefügten überschrieben

Code:
SwingUtilities.invokeAndWait(new Runnable() {
                public void run()  { }
});
 
Hi!

Die Map wird nicht Threadmäßig gefüllt.

Die Anzahl der Zeilen verändert sich sicher, da entweder Zeilen hinzugefügt oder gelöscht werden.
 
Zurück