Eigenes TableModel abgeleitet von AbstractTableModel (neue rows nicht sichtbar)

Status
Nicht offen für weitere Antworten.

Patric

Mitglied
Die Lösung des Problems befindet sich im dritten Post!

Hallo zusammen,

ich sitze jetzt schon seit ein paar Stunden daran, mein TableModel dazu zu bewegen mir die Reihen, die ich zur Laufzeit hinzugefügt habe auch an zu zeigen. Bisher leider ohne Erfolg.

Die Daten als solches werden zwar in die Tabelle eingetragen, allerdings kann ich diese nicht sehen. Wenn ich jetzt z.B. zwei Reihen im Konstruktor meines Hauptprogramms zu der JTable hinzufüge, dann sehe ich diese nach dem start auch wunderbar. Sobald ich es allerdings zur Laufzeit versuche klappt es nicht mehr, sie werden dann nicht angezeigt. Das die Reihen, die ich zur Laufzeit hinzugefügt habe da sind habe ich überprüft, indem ich auf meine JTable geklickt habe und dann mit der Pfeil-nach-unten-Taste nach unten gegangen bin und die Selektion dann unter meiner JTable im Nichts verschwunden ist. Wenn ich das mache, ohne zur Laufzeit eine Reihe hinzugefügt zu haben, dann bleibt meine Selektion bei der zweiten Reihe stehen und ich sehe sie noch.

Ich habe mir hier in dem Forum schon mehrere Beiträge, sowie das Tutorial zum Thema JTable durchgelesen, konnte aber auch da nichts finden, was mir weiterhilft.

Mein TableModel leite ich von vom AbstractTableModel ab welches sich (laut Informationen die ich hier gefunden habe) selber darum kümmert, dass die JTable aktualisiert wird, sobald sich dort was getan hat. Da dies allerdings nicht der Fall zu sein scheint, habe ich auch mal die passenden fire-Methoden aufgerufen, nachdem ich etwas an der JTable gemacht habe, allerdings blieb auch das ohne Erfolg.

Hier jetzt mal der Code, ich bin sicher ihr könnt mir damit weiterhelfen:

Mein TableModel

[HIGHLIGHT="Java"]class DownloadTableModel extends AbstractTableModel
{

private static final long serialVersionUID = 1L;
String[] headers = {"ContentId", "Filename", "Size", "Progress"};
@SuppressWarnings("unchecked")
Class[] columnClasses = {String.class, String.class, String.class, JProgressBar.class};
Vector<RowEntry> data = new Vector<RowEntry> ();

@Override
public int getColumnCount()
{
return headers.length;
}

@Override
public int getRowCount()
{
return data.size();
}

@SuppressWarnings("unchecked")
public Class getColumnClass(int c)
{
return columnClasses[c];
}

public String getColumnName(int c)
{
return headers[c];
}

public boolean isCellEditable(int r, int c)
{
return false;
}

@Override
public Object getValueAt(int r, int c)
{
RowEntry e = data.get(r);
switch (c)
{
case 0: return e.getContentId();
case 1: return e.getFilename();
case 2: return e.getSize();
case 3: return e.getProgressBar().getValue();
default: return null;
}
}

public void setValueAt(Object value, int r, int c)
{
}

public void addRow(String filename, String size)
{
int ID = getRowCount();

data.add(new RowEntry(String.valueOf(ID), filename, size, createProgressBar()));
fireTableRowsInserted(ID, ID); // Hier sage ich nochmal explizit, was ich hinzugefügt habe
}

public void removeRowAt(int r)
{
}

private JProgressBar createProgressBar()
{
JProgressBar pb = new JProgressBar(0, 100);
pb.setValue(0);
pb.setStringPainted(true);
return pb;
}
}[/HIGHLIGHT]



Mein TableCellRenderer:

[HIGHLIGHT="Java"]class DownloadTableRenderer extends JProgressBar implements TableCellRenderer
{

private static final long serialVersionUID = 1L;

public DownloadTableRenderer()
{
super(SwingConstants.HORIZONTAL);
this.setSize(115, 15);
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
if (value == null)
return this;
if (value instanceof JProgressBar)
setValue(((JProgressBar)value).getValue());
else
setValue(0);
return this;
}
}[/HIGHLIGHT]


Mfg. Patric
 
Zuletzt bearbeitet:
S

SlaterB

Gast
> Das die Reihen, die ich zur Laufzeit hinzugefügt habe da sind habe ich überprüft, indem ich auf meine JTable geklickt habe und dann mit der Pfeil-nach-unten-Taste nach unten gegangen bin und die Selektion dann unter meiner JTable im Nichts verschwunden ist.

klingt nach einem Layoutproblem der JTable an sich, dazu hast du ja gar nix gepostet,
füge die JTable vielleicht in ein JScrollPane ein, dann bekommst du ScrollBalken?
 

Patric

Mitglied
> Das die Reihen, die ich zur Laufzeit hinzugefügt habe da sind habe ich überprüft, indem ich auf meine JTable geklickt habe und dann mit der Pfeil-nach-unten-Taste nach unten gegangen bin und die Selektion dann unter meiner JTable im Nichts verschwunden ist.

klingt nach einem Layoutproblem der JTable an sich, dazu hast du ja gar nix gepostet,
füge die JTable vielleicht in ein JScrollPane ein, dann bekommst du ScrollBalken?

Die JTable befindet sich bereits in einem JScrollPane. Mein Hauptframe hat folgende Größe:

[HIGHLIGHT=Java]private final Dimension SIZE = new Dimension(650, 450);[/HIGHLIGHT]

und hat ein 1x1 großes Grid Layout.

[HIGHLIGHT=Java]
this.setLayout(new GridLayout(1, 1));
dlGrid = new DownloadGrid();
this.add(new JScrollPane(dlGrid));
[/HIGHLIGHT]

Ich füge im Konstruktor auch nur 2 Reihen ein, es ist also noch genügend Platz für weitere Reihen.

Hier mal ein Screenshot:

Frame.png


Nachtrag:

Ich habe jetzt mal die Methode removeRowAt vervollständigt:

[HIGHLIGHT=Java]
public void removeRowAt(int r)
{
data.removeElementAt(r);
fireTableRowsDeleted(r, r);
}
[/HIGHLIGHT]

Wenn ich jetzt zur Laufzeit ein Element entferne, dann sieht das wie folgt aus:

Frame_Deleted.png


Hier sieht es so aus, als würde das neu zeichnen da nicht so ganz funktionieren.

addRow geändert

Ich habe meine addRow-Methode mal so umgeschrieben, dass ich die Listener alle manuell benachrichtige, allerdings wieder ohne Erfolg

[HIGHLIGHT=Java]
public void addRow(String filename, String size)
{
int ID = getRowCount();

data.add(new RowEntry(String.valueOf(ID), filename, size, createProgressBar()));
// fireTableRowsInserted(ID, ID);
TableModelListener[] tmls = (TableModelListener[])(this.getListeners(TableModelListener.class));
for (TableModelListener l : tmls)
{
TableModelEvent e = new TableModelEvent(this, ID, ID, TableModelEvent.ALL_COLUMNS,
TableModelEvent.INSERT);

l.tableChanged(e);
}
}
[/HIGHLIGHT]

Okay, ich habe das Problem gelöst. Eigentlich war es klar, dass man da zuerst mal gucken sollte. Ich habe in meine Hauptklasse das TableModelInterface implementiert. Die tableChanged-Methode habe ich allerdings leer gelassen (aus welchen Grund auch immer^^). Jetzt habe ich sie wie folgt geändert und es funktioniert. Jetzt kann ich auch zur Laufzeit Daten hinzufügen.

[HIGHLIGHT=Java]
public void tableChanged(TableModelEvent e)
{
super.tableChanged(e);
}
[/HIGHLIGHT]

Allerdings habe ich jetzt ein neues Problem. Ich habe auf einmal doppelt so viele Spalten, wie ich eigentlich habe (Jede 2 mal).
Dabei spielt es keine Rolle, wann ich die Daten hinzufüge.

Wenn ich jetzt die Zeile
[HIGHLIGHT=Java]super.tableChanged(e);[/HIGHLIGHT]
auskommentiere, dann hab ich nur die 4 Spalten, die ich auch tatsächlich habe.

Kann damit jemand was anfangen?

Mfg. Patric
 
Zuletzt bearbeitet:
S

SlaterB

Gast
was für ein ewiges Mysterium, unvollständigen Code zu posten, und auch schön in kleine Teile zerstückelt,
alles darf man sich zusammenkopieren,
zusätzliche Klassen wie DownloadGrid oder RowEntry oder gar überhaupt ein JFrame/ eine Main-Methode selbst ausdenken

ich habe mir deine Teile so weit es geht zusammenkopiert und nichts deutet auf ein Problem hin,
wollte erst Buttons zum Hinzufügen/ Entfernen verwenden, aber bei GridLayout(1,1) passt ja nun überhaupt nix weiter rein,
also einfach ein Skript: nach einer Sekunde werden zwei Zeilen hinzugefügt, später drei entfernt, alles klappt


so geht ein Programm: alles kopieren, einfügen, vielleicht noch imports ergänzen, auf Ausführen klicken, läuft
Code:
public class Test {

    private static final Dimension SIZE = new Dimension(650, 450);

    public static void main(String argv[]) throws Exception {

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(SIZE);
        f.setLayout(new GridLayout(1, 1));

        DownloadGrid dlGrid = new DownloadGrid();
        f.add(new JScrollPane(dlGrid));
        f.setVisible(true);

        Thread.sleep(1000);
        DownloadGrid.m.addRow("d", "e");
        DownloadGrid.m.addRow("d", "e");
        Thread.sleep(1000);
        DownloadGrid.m.removeRowAt(0);
        DownloadGrid.m.removeRowAt(0);
        DownloadGrid.m.removeRowAt(0);

        // JButton plus = new JButton("+");
        // plus.addActionListener(new ActionListener() {
        // public void actionPerformed(ActionEvent e) {
        // DownloadGrid.m.addRow("d", "e");
        // }
        //
        // });
        // JButton minus = new JButton("+");
        // minus.addActionListener(new ActionListener() {
        // public void actionPerformed(ActionEvent e) {
        // DownloadGrid.m.removeRowAt(0);
        // }
        //
        // });
        // JPanel buttons = new JPanel();
        // buttons.add(plus);
        // buttons.add(minus);

    }
}

class DownloadGrid extends JTable {

    public static final DownloadTableModel m = new DownloadTableModel();

    public DownloadGrid() {
        m.addRow("a", "b");
        m.addRow("c", "d");
        setModel(m);
    }
}

class RowEntry {

    private JProgressBar p;

    private String x;

    private String y;

    public RowEntry(String string, String filename, String size,
            JProgressBar bar) {
        p = bar;
        x = filename;
        y = size;
    }

    public Object getContentId() {
        return x;
    }

    public Object getFilename() {
        return y;
    }

    public Object getSize() {
        return null;
    }

    public JProgressBar getProgressBar() {
        return p;
    }

}

class DownloadTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 1L;

    String[] headers = { "ContentId", "Filename", "Size", "Progress" };

    @SuppressWarnings("unchecked")
    Class[] columnClasses = { String.class, String.class, String.class,
            JProgressBar.class };

    Vector<RowEntry> data = new Vector<RowEntry>();

    @Override
    public int getColumnCount() {
        return headers.length;
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @SuppressWarnings("unchecked")
    public Class getColumnClass(int c) {
        return columnClasses[c];
    }

    public String getColumnName(int c) {
        return headers[c];
    }

    public boolean isCellEditable(int r, int c) {
        return false;
    }

    @Override
    public Object getValueAt(int r, int c) {
        RowEntry e = data.get(r);
        switch (c) {
        case 0:
            return e.getContentId();
        case 1:
            return e.getFilename();
        case 2:
            return e.getSize();
        case 3:
            return e.getProgressBar().getValue();
        default:
            return null;
        }
    }

    public void setValueAt(Object value, int r, int c) {
    }

    public void addRow(String filename, String size) {
        int ID = getRowCount();

        data.add(new RowEntry(String.valueOf(ID), filename, size,
                createProgressBar()));
        fireTableRowsInserted(ID, ID); // Hier sage ich nochmal explizit, was
        // ich hinzugefügt habe
    }

    public void removeRowAt(int r) {
        data.removeElementAt(r);
        fireTableRowsDeleted(r, r);
    }

    private JProgressBar createProgressBar() {
        JProgressBar pb = new JProgressBar(0, 100);
        pb.setValue(0);
        pb.setStringPainted(true);
        return pb;
    }
}

class DownloadTableRenderer extends JProgressBar implements TableCellRenderer {

    private static final long serialVersionUID = 1L;

    public DownloadTableRenderer() {
        super(SwingConstants.HORIZONTAL);
        this.setSize(115, 15);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (value == null)
            return this;
        if (value instanceof JProgressBar)
            setValue(((JProgressBar) value).getValue());
        else
            setValue(0);
        return this;
    }
}

edit:
setDefaultRenderer(JProgressBar.class, new DownloadTableRenderer());

für den Renderer ändert auch nichts am Hinzufügen oder Entfernen von Zeilen
 
Zuletzt bearbeitet von einem Moderator:

Patric

Mitglied
Danke erstmal für deinen Einsatz =)

Habe nun auch das Problem mit den doppelten Spalten gelöst. War ein Dummer Fehler, ich habe die Spalten aus Versehen 2 mal hinzugefügt.

Zu dem Mysterium: Okay sehe ich ein, ab jetzt gibt es von mir nur noch KSKBś, mein Wort drauf ;)

Kurze Frage: Früher konnte man die Themen als gelöst markieren, geht das hier immernoch? Finde grad keine Button dazu.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Eigenes TableModel für ArrayList<String[]> AWT, Swing, JavaFX & SWT 5
D eigenes Tablemodel, Zeile löschen ArrayindexOOB excp AWT, Swing, JavaFX & SWT 4
A JTable, eigenes TableModel und dessen Objekte AWT, Swing, JavaFX & SWT 4
H LayoutManager RPG Programmieren, eigenes Spielfeld grafisch generieren aus Tileset AWT, Swing, JavaFX & SWT 18
O Swing "Eigenes" JPanel wird dem JScrollPane nicht hinzugefügt AWT, Swing, JavaFX & SWT 5
M Swing JComboBox eigenes Design AWT, Swing, JavaFX & SWT 3
L LookAndFeel Eigenes Design für die Applikation AWT, Swing, JavaFX & SWT 4
L JavaFX als eigenes Objekt AWT, Swing, JavaFX & SWT 3
M Plugin oder eigenes Tool mit zB SWING AWT, Swing, JavaFX & SWT 2
N LookAndFeel Wie kann ich mein eigenes LookAndFeel machen? AWT, Swing, JavaFX & SWT 6
1 Eigenes Layout schreiben AWT, Swing, JavaFX & SWT 4
J Eigenes Gui/ Look and Feel AWT, Swing, JavaFX & SWT 14
D Eigenes Textfeld AWT, Swing, JavaFX & SWT 8
A Minimalestopuhr: JLabel.setText() durch eigenes Event ändern AWT, Swing, JavaFX & SWT 6
C Eigenes Hintergrundbild einfügen AWT, Swing, JavaFX & SWT 6
M Eigenes Panel aus Component? AWT, Swing, JavaFX & SWT 5
3 Eigenes Frame/Window programmieren AWT, Swing, JavaFX & SWT 2
F LayoutManager Eigenes Layout die Lösung?! AWT, Swing, JavaFX & SWT 4
P Eigenes Textverarbeitungsprogramm AWT, Swing, JavaFX & SWT 4
R [JTree/DefaultTreeCellRenderer] eigenes Renderer-Panel, so breit wie der JTree AWT, Swing, JavaFX & SWT 2
Developer_X LookAndFeel Eigenes Look And Feel erstellen AWT, Swing, JavaFX & SWT 33
B SWT Eigenes Icon für CheckboxTreeViewer AWT, Swing, JavaFX & SWT 3
KrokoDiehl Swing Design-Frage: eigenes Line-Wrapping AWT, Swing, JavaFX & SWT 5
M Swing eigenes StyledDocument AWT, Swing, JavaFX & SWT 2
S JTree mit Daten aus Model füllen, eigenes TreeModel (gute Dokumentation des Problems) AWT, Swing, JavaFX & SWT 2
M Eigenes ActionEvent / Eigener Listener AWT, Swing, JavaFX & SWT 2
G JToolbar gleich als eigenes Fenster öffnen AWT, Swing, JavaFX & SWT 2
G Eigenes ComboBoxModel AWT, Swing, JavaFX & SWT 2
M eigenes DialogFenster AWT, Swing, JavaFX & SWT 4
L Button ändert eigenes Bild und Progressbar-Value nicht AWT, Swing, JavaFX & SWT 6
J eigenes JOptionPane ? AWT, Swing, JavaFX & SWT 2
D Eigenes Tooltip AWT, Swing, JavaFX & SWT 5
G eigenes option pane AWT, Swing, JavaFX & SWT 5
C Eigenes Event AWT, Swing, JavaFX & SWT 8
S Eigenes Package für die GUI? AWT, Swing, JavaFX & SWT 6
P Eigenes Look&Feel schreiben (Tutorials?) AWT, Swing, JavaFX & SWT 6
B Eigenes Events AWT, Swing, JavaFX & SWT 3
G für showInputDialog kein eigenes Icon auswählen AWT, Swing, JavaFX & SWT 6
M JDialog und eigenes Icon AWT, Swing, JavaFX & SWT 10
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
C TableModel zugehörige Table ermitteln AWT, Swing, JavaFX & SWT 3
W Neues TableModel und JTable wird nicht refreshed AWT, Swing, JavaFX & SWT 3
D Swing JTable TableModel + RowCount AWT, Swing, JavaFX & SWT 18
JAVAnnik Problem mit TableModel AWT, Swing, JavaFX & SWT 3
S Swing Setzen von TableModel liefert NullPointer AWT, Swing, JavaFX & SWT 6
S TableModel Header wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
K verständnissproblem mit TableModel AWT, Swing, JavaFX & SWT 2
K zwei TableModel AWT, Swing, JavaFX & SWT 9
N Swing Eintrag in JTable an dessen TableModel weiterreichen AWT, Swing, JavaFX & SWT 3
hdi Swing Komisches Problem mit TableModel & setAutoCreateRowSorter AWT, Swing, JavaFX & SWT 2
E Swing TableModel fireTableDataChanged führt zu IndexOutOfBoundsException AWT, Swing, JavaFX & SWT 9
F Tablemodel zu mehreren Tabellen AWT, Swing, JavaFX & SWT 6
K JTable +TableModel --> Anpassung der Tabellengröße (Zeilenanzahl) AWT, Swing, JavaFX & SWT 3
K TableModel mit Daten aus Datenbank füllen AWT, Swing, JavaFX & SWT 7
K TableModel Daten übergeben AWT, Swing, JavaFX & SWT 9
L Klick auf JTable -> EditorPane manipulieren, Fragen zu TableModel AWT, Swing, JavaFX & SWT 9
X Swing Daten aus Vector ins TableModel ?? AWT, Swing, JavaFX & SWT 12
E JTable und tablemodel Verständnisproblem AWT, Swing, JavaFX & SWT 3
C Kann Konstruktor von eigenem TableModel nicht nutzen AWT, Swing, JavaFX & SWT 2
S Table oder TableModel so ueberschreiben, dass Columns minimale Breite haben? AWT, Swing, JavaFX & SWT 2
R JTable - TableModel AWT, Swing, JavaFX & SWT 6
D JTable - TableColumnModel - TableModel AWT, Swing, JavaFX & SWT 3
S JTable nimmt TableModel nicht an AWT, Swing, JavaFX & SWT 4
D Mehrere CheckBoxen im TableModel wechselseitig ausschließen AWT, Swing, JavaFX & SWT 5
R TableModel und Columnmodel - Zusammenspiel? AWT, Swing, JavaFX & SWT 2
G TableModel mit anderen Spalten AWT, Swing, JavaFX & SWT 4
G JTable - TableModel aus ArrayList AWT, Swing, JavaFX & SWT 8
D TableModel + Daten bearbeiten + Daten zurückschreiben AWT, Swing, JavaFX & SWT 9
G Frage zu JTable und TableModel AWT, Swing, JavaFX & SWT 4
O TableModel AWT, Swing, JavaFX & SWT 12
V Vector->TableModel->RowSorter:Bei Markierung Index im AWT, Swing, JavaFX & SWT 2
S Daten aus editierbaren TableModel lesen AWT, Swing, JavaFX & SWT 7
F TableModel Spaltenkoepfe benamen, wie? AWT, Swing, JavaFX & SWT 2
F Wie MouseListener bei TableModel anmelden? AWT, Swing, JavaFX & SWT 3
G JTable, TableModel und CellRenderer AWT, Swing, JavaFX & SWT 3
R DataVector bei TableModel - Class Cast Exception AWT, Swing, JavaFX & SWT 9
N TableModel mit CheckBox? AWT, Swing, JavaFX & SWT 5
J Tablemodel AWT, Swing, JavaFX & SWT 2
G jTable + ScrollPane (+ TableModel) AWT, Swing, JavaFX & SWT 7
D invokeLate bei änderung im TableModel? AWT, Swing, JavaFX & SWT 4
G TableModel von JTable wieder entfernen AWT, Swing, JavaFX & SWT 10
G TableModel auswerten und in Datei schreiben AWT, Swing, JavaFX & SWT 3
P JTable TableModel JFreeReport AWT, Swing, JavaFX & SWT 4
T anlegen einer jTable mit TableModel AWT, Swing, JavaFX & SWT 3
B Zugriff auf JFrame obwohl die Klasse abgeleitet ist AWT, Swing, JavaFX & SWT 3
A TreeNode abgeleitet -> Wie komme ich an meine Methoden? AWT, Swing, JavaFX & SWT 2
ChaosNo1 Problem mit Komponente auf JPanel adden (beides abgeleitet) AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben