Tabellenzeilen einfärben

B

bbth6afi

Mitglied
Hallo,

ich habe Probleme bei der Darstellung einer Tabelle.
In einer seperaten Tabelle sind Daten hinterlegt die auch Länder beinhalten.
Über eine Suchfunktion kann ich Länder auswählen und die Einträge zu dem
jeweiligen Land werden in der Tabelle angezeigt, dabei wird zuerst das Land
und dann die Daten eingetragen.
Nun möchte ich dass die komplette Zeile wo das Land drinsteht eingefärbt wird,
dies soll über einen DefaultTableCellRenderer gemacht werden.
Mit einer for-Schleife in einer anderen Klasse werden die zu ermittelnden Einträge gesucht,
ist das zu suchende Land gefunden, wird der Index in einer Variablen gespeichert.

Als Beispiel habe ich 4 Länder ausgewählt (Bild01).
Bild01.jpg

In dem Renderer soll dann die Zahl in der Variablen mit der Zeile Tabelle verglichen werden,
stimmen die beiden Werte, dann soll die Zeile mit dem Land gefärbt werden, der Index für das
Land wird in der Konsole ausgegeben.

Renderer Code:

Java:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.io.*;
import java.util.*;

public class SuchenTableCellRenderer extends DefaultTableCellRenderer {
  private Color lightBlue = new Color(210,210,240);
  private Color normalBlue = new Color(140,140,215);
 
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
    //Einrücken
    Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    Border defaultBorder = ((JComponent)comp).getBorder();

    defaultBorder =  BorderFactory.createEmptyBorder(0,3,0,0);

    this.setBorder(defaultBorder);
    //setFont(new Font("Arial", Font.BOLD, 14));
   
    if(row%2 == 0) {
      this.setBackground(Color.white);
    } else {
      this.setBackground(lightBlue);
    }
    //----------------------------------------------------------------------------------------
    if(SuchenEintrag.tree_wert.equals("Land") & row == 0) {
      this.setBackground(Color.yellow);
    } else if(SuchenEintrag.tree_wert.equals("Land") & row > 1) {
      if(row == Suchen.index_land) {
        this.setBackground(Color.yellow);
      }
     
      /*if(row == 11) {
        this.setBackground(Color.yellow);
      }
     
      if(row == 44) {
        this.setBackground(Color.yellow);
      }
     
      if(row == 62) {
        this.setBackground(Color.yellow);
      } */
    }   
    //----------------------------------------------------------------------------------------
    if(isSelected) {
      //63,53,255
      this.setBackground(new Color(0,120,215));
      this.setForeground(Color.white);
    } else {
      this.setForeground(Color.black); 
    }
   
    setValue(value.toString());
    return this;
  }
}
Im unterstrichelten Bereich habe ich schon mal was probiert und das geht auch,
allerdings nur wenn ich in der if-Anweisung den Index direkt angebe (Bilder 02-05).
Bild02.jpg Bild03.jpg Bild04.jpg Bild05.jpg

Wird die Zeile der Tabelle mit dem Index-Wert aus der Variablen veglichen, dann
klappt es nicht und es wird nur die Zeile gefärbt mit dem letzten Index-Wert (Bilder 06-09).
Bild06.jpg Bild07.jpg Bild08.jpg Bild09.jpg

Ich hoffe mir kann jemand weiterhelfen.
 
Zuletzt bearbeitet von einem Moderator:
mihe7

mihe7

Top Contributor
Normalerweise würde ich hier nur kurz antworten, da es aber ein größeres Projekt zu sein scheint, mal etwas mehr Code, der einen etwas allgemeineren Ansatz zeigt (als Denkanstoß). Dabei wird zwischen den Aufgaben klar getrennt: der Renderer kümmert sich als Dekorator einzig um das Färben der Zellen, während die Frage der Farbe von einem Modell beantwortet wird.

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.Enumeration;

import javax.swing.*;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

@FunctionalInterface
interface TableColorModel {
    Color getColor(JTable table, int row, int col);
}

class ColoringTableCellRenderer implements TableCellRenderer {
    private final TableCellRenderer delegate;
    private final TableColorModel colors;

    public ColoringTableCellRenderer(TableColorModel backgroundColors, 
            TableCellRenderer delegate) {
        this.colors = backgroundColors;
        this.delegate = delegate;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        Component component = delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        if (!hasFocus && !isSelected) {
            Color color = colors.getColor(table, row, column);
            if (color != null) {
                component.setBackground(color);
            }
        }
        return component;
    }
}      

public class Test {

    Object[][] data = new Object[100][2];
    private String query = "";
    private TableColorModel colors;
    
    public Test() {
        colors = (t, r, c) -> rowMatchesQuery(r) ? Color.LIGHT_GRAY : Color.WHITE;

        for (int i = 0; i < data.length; i++) {
            data[i][0] = "Wert " + (2*i+1);
            data[i][1] = "Wert " + (2*i+2);
        }
    }

    private boolean rowMatchesQuery(int row) {
        if (!query.isEmpty()) {
            for (Object value : data[row]) {
                if (value != null && value.toString().contains(query)) {
                    return true;
                }
            }
        }
        return false;
    }

    public void run() {
        JTextField searchField = new JTextField();
        JTable table = new JTable(data, new Object[]{"Spalte A", "Spalte B"});
        installRenderers(table);
        searchField.addActionListener(e -> {
            query = searchField.getText().trim();
            table.repaint();
        });

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(searchField, BorderLayout.NORTH);
        frame.add(new JScrollPane(table));
        frame.setSize(800, 600);
        frame.setVisible(true);
    }

    private void installRenderers(JTable table) {
        TableColumnModel columns = table.getColumnModel();
        for (Enumeration<TableColumn> e = columns.getColumns(); e.hasMoreElements(); ) {
            TableColumn column = e.nextElement();
            TableCellRenderer delegate = column.getCellRenderer();
            if (delegate == null) {
                delegate = new DefaultTableCellRenderer();
            }
            column.setCellRenderer(new ColoringTableCellRenderer(colors, delegate));
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
 
B

bbth6afi

Mitglied
Danke für deine Antwort, da ich kein Profi bin, versuche ich mal den Code zu enträtseln.
 
mihe7

mihe7

Top Contributor
versuche ich mal den Code zu enträtseln.
Das sollte hoffentlich nicht zu schwer sein - bis auf die paar Lambda-Ausdrücke, die nur dazu dienen, die entsprechenden Schnittstellen platzsparend zu implementieren, ist das "guter, alter" Java-Code :) Die Test-Klasse dient auch nur Demonstrationszwecken.

Der wesentliche Punkt besteht aus dem TableColorModel und dem ColoringTableCellRenderer. Letzterer unterscheidet sich von Deinem Renderer nur unwesentlich:
  1. Die Komponente hole ich mir nicht von super, sondern von einem zuvor übergebenen Renderer. Der ColoringTableCellRenderer hat nur eine einzige Aufgabe: Hintergrundfarbe setzen. Er muss selbst keine Komponente zur Verfügung stellen, daher überlasse ich das anderen (eben dem übergebenen Renderer).
  2. Aus dem gleichen Grund bestimmt die Farbe nicht der Renderer sondern das zuvor übergebene TableColorModel.
Mit diesen kleinen Änderungen hat man nun ein wiederverwendbares, recht universell einsetzbares "Tool". Wenn Du z. B. jede zweite Zeile einfärben willst, ist das nun lediglich eine kleine Änderung:
Java:
colors = (t, r, c) -> row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE;
Wenn Du ein komplexes "Farbmodell" haben willst, wo der Programmierer einzelne Zellen farblich hervorheben kann, ist das nicht schwerer:
Java:
Map<Point,Color> cellColors = new HashMap<>();
...
colors = (t, r, c) -> cellColors.getOrDefault(new Point(r,c), Color.WHITE);
Jetzt kann jede einzelne Zelle (deren "Koordinate" hier mit einem java.awt.Point angegeben wird) einzeln eingefärbt werden.

Man kann den Spaß beliebig ausbauen, z. B. um Ereignisse, die bei Änderung des Modells ausgelöst werden, so dass die Tabelle automatisch neu gezeichnet wird. Wie schon gesagt, das soll jetzt erst einmal ein Denksanstoß sein. Einfach, um einmal ein wenig von den üblichen Beispielimplementierungen der CellRenderer, die auf einen konkreten Fall zugeschnitten sind, wegzukommen.
 
B

bbth6afi

Mitglied
ich habs geschafft, es geht jetzt.
In der Klasse wo der Index für das jeweilige Land ermittelt wird habe ich eine ArrayList erstellt,
dort werden die Index-Werte gespeichert.
Dann habe ich in der Renderer-Klasse den Bereich zwischen den gestrichelten Linien entfernt
und durch dieses ersetzt:

if(SuchenEintrag.tree_wert.equals("Land")) {
for(int i=0;i<Suchen.liste_laender.size();i++) {
if(row == Integer.parseInt(""+Suchen.liste_laender.get(i))) {
this.setBackground(Color.yellow);
}
}
}

Und es hat geklappt, jetzt muss ich nur noch die Zeilen mit den Ländern zu einer Zelle machen,
dann bin ich glücklich.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Swing Gleichmäßige Verteilung der Tabellenzeilen über den gesammten Tabellenbereich AWT, Swing, JavaFX & SWT 5
Landei Swing JTree mit "Tabellenzeilen"? AWT, Swing, JavaFX & SWT 5
kilopack15 JPanel im laufenden Zustand einfärben AWT, Swing, JavaFX & SWT 2
S Swing GANZE Row auf einen Schlag einfärben AWT, Swing, JavaFX & SWT 2
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
LexeB4F Zelle in JTable gezielt einfärben AWT, Swing, JavaFX & SWT 4
B Einfärben von Tabellenzellen AWT, Swing, JavaFX & SWT 6
J Zellen in JavaFx einfärben funktioniert nicht AWT, Swing, JavaFX & SWT 1
D Swing Bestimmte Berechnung von Spalten durchführen und dann die Zeilen nach bestimmten Kriterien einfärben AWT, Swing, JavaFX & SWT 5
P DefaultStyledDocument eingegebenen String durchsuchen und bestimmte Sachen einfärben AWT, Swing, JavaFX & SWT 1
T Table-Zeilen mit Thread einfärben AWT, Swing, JavaFX & SWT 15
M JTable Zeilen und Zellen einfärben AWT, Swing, JavaFX & SWT 11
C Java2D Transparenz geht bei einfärben verloren AWT, Swing, JavaFX & SWT 7
M JTable Zeilen einfärben AWT, Swing, JavaFX & SWT 13
R Zeile in JTable anhand von Wert einfärben AWT, Swing, JavaFX & SWT 2
S Swing JTable - Zeilentext unabhänig von einander einfärben AWT, Swing, JavaFX & SWT 4
S Swing HTML-Text in JEditorPane einfärben AWT, Swing, JavaFX & SWT 5
U JTable: Zeilen abhängig vom Datensatz einfärben AWT, Swing, JavaFX & SWT 4
G JFreechart Balken einfärben AWT, Swing, JavaFX & SWT 6
P JTable zeile einfärben AWT, Swing, JavaFX & SWT 1
O Zeilen in JTable auf Grund eines Wertes einfärben AWT, Swing, JavaFX & SWT 6
A JXTable jede zweite Zeile einfärben AWT, Swing, JavaFX & SWT 4
M [Swing] Kalender mit JTable / Einfärben von Zellen AWT, Swing, JavaFX & SWT 10
B JTable-Zellen einfärben AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Anzeige

Neue Themen


Oben