JTable Cell Refresh

tuedel

Aktives Mitglied
Hallo =). Ich melde mich schonwieder ..

So richtig zufrieden bin ich zwar mit dem JWindow aus meinem vorherigen Thread noch nicht, aber mal zu was anderem = ).

Ich habe eine JTable, die ich mit comboboxen und Strings versehen habe und die auf MouseReleased Events Änderungen am TableModel vornimmt. Wenn ich dann aber in der überschriebenen setValueAt(..) methode ein fireTableCellUpdated(row, column) ausführe, wird nicht die entsprechende Zelle neu gezeichnet, sondern die gesamte Tabelle.

Wenn ich also nur vereinzelte Updates habe, oder Tabellenspalten ohnehin gleich bleiben, möchte ich ja nicht die gesamte Tabelle neu zeichnen. Vielleicht habe ich einen Fehler gemacht - daher hier der Quellcode für den Renderer, das Model und die JTable.

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package UI.Tables;

import AppletMain.DefaultResources;
import AppletMain.DefaultResources.DEFAULT_COLORSET;
import AppletMain.Enumarations.OPTIONS;
import MapDrawing.SailingPainter;
import UI.Utility.CustomCheckBox;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;


class JTableOptionsRenderer implements TableCellRenderer {

    private JLabel textLabel = new JLabel();
    private CustomCheckBox cBox = CustomCheckBox.createCustomCheckBox();
    private JSeparator sep = new JSeparator(JSeparator.HORIZONTAL);

    public JTableOptionsRenderer() {
        textLabel.setFont(DefaultResources.getFont(DefaultResources.FONT.META_DATA));
        textLabel.setForeground(DefaultResources.getDefaultColor(DefaultResources.DEFAULT_COLORSET.DATA_COLOR));
        textLabel.setBackground(DefaultResources.getDefaultColor(DefaultResources.DEFAULT_COLORSET.TOGGLE_COLOR_FIRST));
        textLabel.setOpaque(true);
        textLabel.setBorder(new EmptyBorder(3, 0, 0, 0));

        cBox.setBackground(DefaultResources.getDefaultColor(DefaultResources.DEFAULT_COLORSET.TOGGLE_COLOR_FIRST));
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
       
        if (value instanceof Boolean) {
            cBox.setSelected((Boolean) value);
            return cBox;
        } else if (value instanceof OPTIONS){
            textLabel.setText(((OPTIONS) value).toString());
            return textLabel;
        }
        else{
            return sep;
        }
    }
}


/**
 *
 * @author lueder.j
 */
class OptionsTableModel extends AbstractTableModel {

    private Object[][] rows = new Object[OPTIONS.values().length][2];
    private String[] columns = {"checkbox", "Definition"};

    public OptionsTableModel() {
        initRows();
    }

    private void initRows() {
        for (int i = 0; i < OPTIONS.values().length; i++) {

            if (OPTIONS.values()[i] == OPTIONS.NONE) {
                rows[i][0] = "";
                rows[i][1] = "";
            } else {
                if (i == 0) {
                    rows[i][0] = true;
                } else {
                    rows[i][0] = false;
                }
                rows[i][1] = OPTIONS.values()[i];
            }
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return rows[rowIndex][columnIndex];
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        rows[rowIndex][columnIndex] = aValue; 
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    @Override
    public int getRowCount() {
        return rows.length;
    }

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

    @Override
    public Class getColumnClass(int column) {
        return getValueAt(0, column).getClass();
    }
}

public class OptionsTable extends JTable {

    private OPTIONS activeMainOption = OPTIONS.SHOW_SAILNUMBERS;
    private int rowActive = 0;

    public OptionsTable() {
        setModel(new OptionsTableModel());
        setDoubleBuffered(true);
        setVisible(true);
        setDefaultRenderer(Boolean.class, new JTableOptionsRenderer());
        setDefaultRenderer(OPTIONS.class, new JTableOptionsRenderer());
        setDefaultRenderer(String.class, new JTableOptionsRenderer());                

        setTableHeader(null);
        setGridColor(DefaultResources.getDefaultColor(DEFAULT_COLORSET.BORDER_COLOR));
        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        setShowHorizontalLines(true);
        setIntercellSpacing(new Dimension(0, 1));

        getColumnModel().getColumn(0).setPreferredWidth(20);
        getColumnModel().getColumn(1).setPreferredWidth(120);

        setRowHeight(MenuContainer.lineHeight + MenuContainer.lineBorderThickness * 2);
        setRowHeight(6, 2); // Set the height for the empty Row, which is used for the seperator and does match with the NONE value of the OPTIONS Enumration

        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
                int row = rowAtPoint(e.getPoint());
                int column = columnAtPoint(e.getPoint());
                OPTIONS command = (OPTIONS) getModel().getValueAt(row, 1);

                if (getModel().getColumnClass(column) == Boolean.class) {
                    if (((Boolean) getModel().getValueAt(row, column)) == false) {

                        getModel().setValueAt(true, row, column);

                        if (command == OPTIONS.SHOW_PATH) {
                            SailingPainter.showPath = true;
                        } else if (command == OPTIONS.SHOW_TAIL) {
                            SailingPainter.showTails = true;
                        } else {
                            if (command != activeMainOption) {
                                getModel().setValueAt(false, rowActive, 0);
                            }
                            SailingPainter.option = command;
                            activeMainOption = command;
                            rowActive = row;
                        }

                    } else {

                        if (command == OPTIONS.SHOW_PATH) {
                            SailingPainter.showPath = false;
                        } else if (command == OPTIONS.SHOW_TAIL) {
                            SailingPainter.showTails = false;
                        } else {
                            SailingPainter.option = OPTIONS.NONE;
                        }

                        getModel().setValueAt(false, row, 0);
                    }
                    
                }                
            }
        });
    }
}
 

tuedel

Aktives Mitglied
Keiner eine Idee? An sich wäre es mir möglich aus der Instanz der JTable heraus einen repaint auszuführen, dessen koordinaten mit der jeweiligen Cell matchen. Das ist aber irgendwie nicht Sinn der Sache. Das Ding ist, dass die fireTableCellUpdated(row, column) auch nur ein tableChanged ruft, dass wiederum die Listener des Models durchläuft und diesen die Veränderung mitteilt.

Müsste ich eventuell die Listener anpassen und überschreiben?!
 
S

SlaterB

Gast
wenn du von einem Thread oder Button aus setValueAt() aufrufst wird nur eine Zelle neu gemalt,
umgekehrt werden Zeilen beim Rumklicken in der Tabelle auch dann komplett neu gemalt wenn du dort gar nicht setValueAt() aufrufst,
einfach nur die Tabelle für sich sorgt für schöne Ansicht, weil sie z.B. mit Hervorhebung einer selektierten Zeile rechnet,
(edit: ok, so ganz passt das nicht, aber irgendwas in der Richtung)

wie sich das ausschalten läßt kann ich pauschal nicht sagen, ist das wirklich wichtig?
lass die Tabelle doch malen wie sie will, cache in deinem Model Daten falls dort ein Problem herrscht,

ach ja, es werden wirklich nur 1-2 Zeilen gemalt, nicht die ganze Tabelle oder wie kommst du dazu?
ein vollständiges Testprogramm zu posten wäre günstig, so ist dein Code unausführbar -> unnachprüfbar

hier eine abgespeckte lauffähige Variante

Java:
public class TestGUI
    extends JFrame
{
    public TestGUI()
        throws Exception
    {
        OptionsTable t = new OptionsTable();
        add(t);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);
        setVisible(true);

        OptionsTableModel m = (OptionsTableModel)t.getModel();
        for (int i = 0; i < 10; i++)
        {
            Thread.sleep(1000);
            m.setValueAt("k: " + i, 3, 0);
        }
    }


    public static void main(String[] args)
        throws Exception
    {
        new TestGUI();
    }

}


class JTableOptionsRenderer
    implements TableCellRenderer
{

    private JLabel textLabel = new JLabel();
    private JSeparator sep = new JSeparator(JSeparator.HORIZONTAL);

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
                                                   int column)
    {
        System.out.println("paint: " + row + ", " + column + ", " + value);
        // new Error("paint: " + row + ", " + column + ", " + value).printStackTrace();
        textLabel.setText(value.toString());
        return textLabel;
    }
}

class OptionsTableModel
    extends AbstractTableModel
{

    private String[][] rows = new String[5][2];
    private String[] columns =
        {"checkbox", "Definition"};

    public OptionsTableModel()
    {
        initRows();
    }

    private void initRows()
    {
        for (int i = 0; i < rows.length; i++)
        {
            rows[i][0] = "";
            rows[i][1] = "";
        }
    }

    public Object getValueAt(int rowIndex, int columnIndex)
    {
        return rows[rowIndex][columnIndex];
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex)
    {
        rows[rowIndex][columnIndex] = (String)aValue;
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    public int getRowCount()
    {
        return rows.length;
    }

    public int getColumnCount()
    {
        return columns.length;
    }

    public Class getColumnClass(int column)
    {
        return getValueAt(0, column).getClass();
    }
}


class OptionsTable
    extends JTable
{
    private int rowActive = 0;

    public OptionsTable()
    {
        setModel(new OptionsTableModel());
        setDoubleBuffered(true);
        setDefaultRenderer(String.class, new JTableOptionsRenderer());

        setTableHeader(null);

        addMouseListener(new MouseAdapter()
            {

                int c = 0;

                public void mouseReleased(MouseEvent e)
                {
                    int row = rowAtPoint(e.getPoint());
                    int column = columnAtPoint(e.getPoint());

                    // getModel().setValueAt("" + c++, row, column);

                }
            });
    }
}
 
Zuletzt bearbeitet von einem Moderator:

tuedel

Aktives Mitglied
Morgen !!

Ich habe dein Beispiel auch mal ausgeführt. Bei der Verwendung des Mouselisteners werden dabei nur die angrenzenden Zellen oder die jeweils ausgewählte neu gezeichnet. Aus einem mir bisher noch nicht bekannten Grund, wird bei mir aber jede Zelle neu gezeichnet.

Der Renderer durchläuft halt alle Zeilen und Spalten indezes. An sich wäre mir das für eine so einfache Tabelle egal, ob er jetzt alle oder nur eine Zelle zeichnet. Da ich aber eine weitaus umfangreichere Tabelle erst noch schreiben will, war das für mich bei einem einfachereren Beispiel jetzt halt der Aufhänger..
 

tuedel

Aktives Mitglied
Kurze Rückmeldung -

wie es aussieht hat die Anweisung

setRowHeight(6, 2);

Quasi wollte ich ja in eine Zeile einen separator tricksen, der aber leider diesen Nebeneffekt verursacht.

LG
 

tuedel

Aktives Mitglied
Ok ich habs hinbekommen - falls es jemanden interessiert. Habe jetzt den Separator aus dem TableModel entfernt und stattdessen die paintComponent der Table überschrieben.

Java:
@Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        paintSeparator(g);
    }
    private static final Stroke separator = new BasicStroke(3, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_BEVEL);
    
    public void paintSeparator(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        Rectangle rectOfSeparator = getCellRect(6, 0, true);
        
        int firstNonExistentRowY = rectOfSeparator.y; //the top Y-coordinate of the first empty tablerow

        int x = 0;
        for (int i = 0; i < getColumnCount(); i++) {
            TableColumn column = getColumnModel().getColumn(i);
            x += column.getWidth(); //add the column width to the x-coordinate                
        }
        g2d.setColor(Color.lightGray);
        g2d.setStroke(separator);
        g2d.drawLine(0, firstNonExistentRowY - 1, x, firstNonExistentRowY - 1);
        
        g2d.dispose();        
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
M JTable Cell Renderer- Terminplaner AWT, Swing, JavaFX & SWT 2
A JTable Cell Eingabe AWT, Swing, JavaFX & SWT 6
J Swing JTable cell-ausrichtung für zahlen mit alternierenden zeilenfarben AWT, Swing, JavaFX & SWT 2
B LookAndFeel Cell Renderer für JTable bei Nimbus Look and Feel AWT, Swing, JavaFX & SWT 2
M Swing JTable cell leeren bei Eingabe AWT, Swing, JavaFX & SWT 6
C Swing JTable: edit Cell -> versteckten Wert ändern AWT, Swing, JavaFX & SWT 12
A Focus in JTable Cell AWT, Swing, JavaFX & SWT 3
O JTable Edit cell edit end erzwingen... AWT, Swing, JavaFX & SWT 7
O JCombobox in EINER JTable Cell AWT, Swing, JavaFX & SWT 5
J Cell Farbe in JTable AWT, Swing, JavaFX & SWT 31
S JTable - farbe einer cell/row ändern, Hilfe please AWT, Swing, JavaFX & SWT 2
clemson Cursor in JTable-Cell setzen AWT, Swing, JavaFX & SWT 6
D JTable - Hintergrundbild in Cell AWT, Swing, JavaFX & SWT 6
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
S HPRO und UPRO gemeinsame JTABLE gemeinsamer RENDERER ? AWT, Swing, JavaFX & SWT 1
F Swing JTable - MultiHeader inkl. Eingabemöglichkeit AWT, Swing, JavaFX & SWT 1
S JTable - Feldinhalte anzeigen AWT, Swing, JavaFX & SWT 15
D Swing JTable Spaltenbreite AWT, Swing, JavaFX & SWT 1
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
G jTable - getSelectedRow() AWT, Swing, JavaFX & SWT 3
I JTable mit einem Button zu einer Detail Seite springen AWT, Swing, JavaFX & SWT 4
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
D Tastaturabfragen CTRL+t, CTRL+E bei eine JTable, bestehend aus JTextAteas AWT, Swing, JavaFX & SWT 4
P Checkboxes in JTable nicht editable AWT, Swing, JavaFX & SWT 9
F Best-Practise: JTable Text in Zelle zu groß AWT, Swing, JavaFX & SWT 2
izoards JTable in CSV File schreiben... AWT, Swing, JavaFX & SWT 23
Kohl Jedes Objekt einer JTable um ein Zeichen verkürzen AWT, Swing, JavaFX & SWT 7
I JTable, DefaultTableModel, zwei Zahlen multiplizieren. AWT, Swing, JavaFX & SWT 26
M JTABLE / wie oft wurde gewürfelt. AWT, Swing, JavaFX & SWT 1
F JTable vergrößern AWT, Swing, JavaFX & SWT 2
H JTable: Diverse NullPointer-Exceptions zur Laufzeit AWT, Swing, JavaFX & SWT 3
J Swing Werte des JTable werden nicht angezeigt AWT, Swing, JavaFX & SWT 9
T Swing JTable cellRenderer mit jpg Hintergrundfarbe lässt sich nicht ändern. AWT, Swing, JavaFX & SWT 1
HoT Einzelne Zelle in JTable Rahmen unten setzen AWT, Swing, JavaFX & SWT 24
B JTable Zellen zusammenfügen AWT, Swing, JavaFX & SWT 3
H JTable im JSplitPane darstellen AWT, Swing, JavaFX & SWT 2
MadMax2506 Swing JTable lädt sehr lange AWT, Swing, JavaFX & SWT 1
D Zeilenumbruch in einer JTable AWT, Swing, JavaFX & SWT 9
R Swing JTable und Spaltenausrichtung AWT, Swing, JavaFX & SWT 8
G JTable füllen AWT, Swing, JavaFX & SWT 1
H JTable TableCellEditor-Problem AWT, Swing, JavaFX & SWT 0
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
J Datensatz in jTable ausgeben AWT, Swing, JavaFX & SWT 3
M Swing Automatischer Editorstart in JTable-Zelle AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing JTable aktualisieren AWT, Swing, JavaFX & SWT 5
adiko01 JTable: Nur markierte Zeilen aus der Tabelle in CSV exportiern AWT, Swing, JavaFX & SWT 9
M JTable.setDefaultRenderer(...) greift nicht AWT, Swing, JavaFX & SWT 0
J JTable: Eingabe in Tabellenzelle korrigieren AWT, Swing, JavaFX & SWT 4
T Problem mit JTable Sortierung AWT, Swing, JavaFX & SWT 2
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
D MySQL Daten in JTable anzeigen AWT, Swing, JavaFX & SWT 2
H Swing Jtable extra spalte AWT, Swing, JavaFX & SWT 6
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
S Swing Mal wieder JTable Ansicht aktualisieren AWT, Swing, JavaFX & SWT 10
A JTable mit Daten füllen AWT, Swing, JavaFX & SWT 1
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
N AWT jTable CellRenderer AWT, Swing, JavaFX & SWT 6
T Swing JTable valueChanged datensatz löschen AWT, Swing, JavaFX & SWT 1
0 Swing JTable aus anderer Klasse updaten AWT, Swing, JavaFX & SWT 5
S Jtable defaultRenderer wohin damit ? AWT, Swing, JavaFX & SWT 23
T Swing JTable / FocusListener AWT, Swing, JavaFX & SWT 0
it_is_all Warum wird die JTable im JDialog nicht angezeigt? AWT, Swing, JavaFX & SWT 1
L Swing JTable im Panel darstellen AWT, Swing, JavaFX & SWT 8
T Swing Double Click bei Buttons in JTable AWT, Swing, JavaFX & SWT 9
J addRow bei JTable AWT, Swing, JavaFX & SWT 6
M Jtable gibt -1 wert bei selectedRow und Column AWT, Swing, JavaFX & SWT 3
Meeresgott Swing JTable AWT, Swing, JavaFX & SWT 4
J JTable Selection Listener funktioniert nicht AWT, Swing, JavaFX & SWT 4
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
Thallius JTable dynamisch Spaltenanzahl verändern AWT, Swing, JavaFX & SWT 2
Thallius JTable dynamisch laden? AWT, Swing, JavaFX & SWT 2
B Swing JTable sortieren AWT, Swing, JavaFX & SWT 2
T Swing JTable auslesen und befüllen AWT, Swing, JavaFX & SWT 8
B JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 1
J JTable und Suchlogik AWT, Swing, JavaFX & SWT 4
Viktim Swing JTable mit Tab verlassen AWT, Swing, JavaFX & SWT 1
F Swing Spaltenbreite einer Column eines JTable auslesen AWT, Swing, JavaFX & SWT 5
Viktim Swing JTable Mit Tab druch Zeilen Wechseln AWT, Swing, JavaFX & SWT 5
Thallius Warum refrehsed mein JTable nicht? AWT, Swing, JavaFX & SWT 5
Ghostman1711 Hinzufügen ausgewählter Dateinen des Filechoosers zu einem JTable AWT, Swing, JavaFX & SWT 9
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
M Wert einer Zelle aus JTable ziehen AWT, Swing, JavaFX & SWT 4
K JTable getValueAt() klappt nicht immer AWT, Swing, JavaFX & SWT 1
K JTable in extra Klasse, Zugriff in einer anderen klasse nicht möglich AWT, Swing, JavaFX & SWT 26
B Swing Tabelle(JTable) filtern swing GUI AWT, Swing, JavaFX & SWT 3
P JTable - bei Eingabe Selektion AWT, Swing, JavaFX & SWT 0
P Fokus auf Zelle in JTable AWT, Swing, JavaFX & SWT 1
S Swing Deselektion in JTable verhindern AWT, Swing, JavaFX & SWT 0
D Problem mit JTable AWT, Swing, JavaFX & SWT 1
N Swing Print JTable mit AbstractTableModel AWT, Swing, JavaFX & SWT 1
Ananaskirsche Swing jTable Reihen zuviel eingefügt AWT, Swing, JavaFX & SWT 12
P im JTable die Schriftfarbe ändern AWT, Swing, JavaFX & SWT 19
T Swing JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Dreiecke in bestimmte Zellen einer JTable AWT, Swing, JavaFX & SWT 9
LexeB4F Zelle in JTable gezielt einfärben AWT, Swing, JavaFX & SWT 4
LexeB4F JTable mehrere Zelle selektieren und inhalte Löschen.. Ideen gesucht AWT, Swing, JavaFX & SWT 1
D Swing JTable Renderer Grafikfehler AWT, Swing, JavaFX & SWT 0
K Swing JTable mit ImageIcon und Text in einer Zelle AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben