Mehrere Tabellen Zellen gleichzeitig färben

skrobi

Mitglied
Hallo,
ich habe nachfolgende Tabelle in der ich beim Anklicken einer Tabellen-Zelle diese CYAN-farbig färbe.
Dies funktioniert einwandfrei.

Wie muss ich den Code ändern bzw. ergänzen, damit nicht nur die angeklickte Zelle Cyan gefärbt wird, sondern noch
zusätzlich Weitere andersfarbig
z.B.: rc(row+x1, column+y1).setBackground(Color.RED); ?
oder: rc(row-x2, column-y4).setBackground(Color.YELLOW); ?

Vielen Dank für Eure Unterstützung
skrobi


Java:
JTable WORKTAB_table = new JTable(WORKTAB_model)
  {
  :
  public boolean isCellEditable( int rowIndex , int columnInd ex)
  {
  :
   class  CustomRenderer extends DefaultTableCellRenderer {
   :
  public CustomRenderer(int rows, int cols) {
          }  //  END  public CustomRenderer(int rows, int cols) {

          public CustomRenderer(String[][] WORKTAB_DATA, String[] WORKTAB_UEBER) {
              // TODO Auto-generated constructor stub
            }

            @Override
          public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus,
          int row, int column) {
    
          Component rc = super.getTableCellRendererComponent
                         (table, value, isSelected, hasFocus, row, column);
    
        if      (row    == A.SafeIx1_Row &&
                column == A.SafeIx1_Col) {
                 rc.setBackground(Color.CYAN);
//               ====>>>>   hier so oder so ähnlich ergänzen
// z.B.:       rc(row+x1, column+y1).setBackground(Color.RED);   ? 
// oder:     rc(row-x2, column-y4).setBackground(Color.YELLOW);?
               };
 
Ändere das Tabellenmodell und rufe fireTableCellUpdated(row, column) für die entsprechenden Zellen auf. Das Value-Object im TableModel sollte eine Eigenschaft enthalten, aus welcher die Farbe abgeleitet werden kann. Das TableModel kann z.B. über einen SelectionListener beeinflusst werden.
 
Leider geht aus deiner Beschreibung nicht hervor, wovon abhängt, welche Farbe gesetzt werden soll.

Eine Möglichkeit ist, das so zu machen wie @Oneixee5 vorgeschlagen hat.

Deine Idee, das anhand der Indizes zu prüfen, ist genauso gut, Java macht das ja selbst so bei gewissen Look&Feels, wo jede zweite Zeile anders gefärbt ist. Nun musst du halt noch irgendwo hinterlegen, für welche Indizes welche Farbe gilt.
 
Deine Idee, das anhand der Indizes zu prüfen, ist genauso gut, Java macht das ja selbst so bei gewissen Look&Feels, wo jede zweite Zeile anders gefärbt ist. Nun musst du halt noch irgendwo hinterlegen, für welche Indizes welche Farbe gilt.
Ja, das funktioniert sehr gut, wenn man z. B. jede zweite Zeile andersfarbig darstellen möchte. Im konkreten Fall sehe ich allerdings das Problem, dass man im Renderer dafür sorgen müsste, dass die anderen Zellen/Zeilen ebenfalls neu gezeichnet werden -> hervorragende Fehlerquelle. Da ist der Ansatz von @Oneixee5 m.E. wesentlich sauberer: die Auswahl führt zur Änderung im Model und die wird dann einfach dargestellt.
 
Bei Farbänderung neu zeichnen zu lassen, ist in jedem Fall eine gute Idee. Aber ob sie Teil der Daten sein sollte, hängt wirklich vom Design ab.
Eine markierte Zeile hat ja standardmäßig eine andere Farbe - ohne dass dies Teil der Daten ist.

Geht es um die Position in der sichtbaren Tabelle? Dann ist das Speichern der Farbe als Wert sinnlos. Hängt die Farbe der gesamten Zeile vom Wert des Feldes einer bestimmten Spalte ab (ob nun die Farbe direkt gespeichert wird oder ein Wert, der entsprechend gemappt wird, lass ich mal außen vor)? Dann sollte die Zeile auch neu gezeichnet werden, wenn sich der Wert des Feldes in dieser Spalte ändert.

Ich hab's bei einer Liste selbst auch schon in den Daten hinterlegt, um jeweils Gruppen von Zeilen gleich zu färben. Ist eine funktionierende Quick& Dirty Lösung. Es hängt wirklich vom jeweiligen Fall ab.

Es gibt einfach zu wenig Informationen darüber, was der OP eigentlich vorhat, um das beurteilen zu können.
 
Moment, wir reden gerade aneinander vorbei. Ich habe nicht gesagt, dass man die Farben in den Daten speichern soll, es spricht jedoch überhaupt nichts dagegen, den Zugriff auf die Farben in ein Model für die JTable (bzw. deren Renderer) aufzunehmen. Wenn man will, kann man das komplett vom TableModel entkoppeln und ein Model für Renderer anbieten.

Mal kurz was überlegen:
Java:
record CellColor(Color background, Color foreground) {}

@FunctionalInterface
interface TableCellColorModel {
    CellColor getColor(int row, int col, boolean isSelected, boolean hasFocus);
}

// hier mal als Decorator
public class ColorRenderer implements TableCellRenderer {
    private final TableCellRenderer renderer;
    private final TableCellColorModel model;

    public ColorRenderer(TableCellRenderer renderer, TableCellColorModel model) {
        this.renderer = renderer;
        this.model = model;
    }

    @override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        CellColor cellColor = model.getColor(row, col, isSelected, hasFocus);
        if (cellColor != null) {
            comp.setForeground(cellColor.foreground());
            comp.setBackground(cellColor.background());
        }
        return comp;
    }

    public static void decorateColumns(JTable table, TableCellColorModel colors) {
        table.getColumnModel().getColumns().asIterator().forEachRemaining(col -> decorateColumn(col, colors));
    }

    private static void decorateColumn(TableColumn column, TableCellColorModel colors) {
        TableCellRenderer renderer = column.getTableCellRenderer();
         if (renderer instanceof ColorRenderer) {
             return;
         }
         column.setTableCellRenderer(new ColorRenderer(renderer, colors));
    }
}
Ist natürlich nur eine ungetestete Skizze, aber damit sollte sich z. B. folgendes realisieren lassen:
Java:
final CellColor secondRowColor = new CellColor(Color.LIGHT_GRAY, Color.BLACK);
final TableCellColorModel colors = (r,c,s,f) -> !s && !f && r % 2 == 1 ? secondRowColor : null;
ColorRenderer.decorateColumns(table, colors);
Es muss also nichts gespeichert werden. Das Model lässt sich jetzt natürlich beliebig implementieren, z. B. mit Zugriff auf das TableModel, wenn man es braucht, oder mit einem expliziten Setzen von Farben für Spalten/Zeilen usw. Natürlich kann ich mir auch die JTable angeben lassen und mir das SelectionModel besorgen, um entsprechende Events auszuülösen...
 

Zurück
Oben