JTable - Hintergrundfarbe von Zeilen ändern

chriss_2oo4

Erfahrenes Mitglied
Hi,

ich habe eine Tabelle, die mir Daten aus einer DB anzeigt. Nach einer Suchfunktion sollen alle Zeilen, die Treffer beinhalten, durch eine andere Hintergrundfarbe hervorgehoben werden.

Bisher bin ich soweit gekommen, dass alle Zeilen-Nummern ermittelt werden, deren Hintergrundfarbe geändert werden soll.

Nun weiss ich aber nicht, wie ich die Farben der einzelnen Zeilen ändern kann... wenn ich ein neuen CellRenderer erstelle, kann ich diesen ja nur auf Spalten, jedoch nicht auf Zeilen, anwenden.

Gibt es eine Möglichkeit innerhalb des CellRenderers abzufragen in welcher Zeile die Komponente liegt, so dass ich dem von mir erzeugten CellRenderer einfach ein Array oder einen Vector übergebe und ich dann prüfen könnte ob sich die Komponente in einer der angegebenen Zeilen befindet, und somit setBackground() aufrufe?

Erstmal vielen Dank

Mfg Chriss
 
Hallo,

bei der Methode vom CellRenderer bekommst du auch die Zeile übergeben, du musst nur allen Spalten deinen Renderer zuweisen und dann müsste es funktionieren.

Das ist ein Beispiel wie du die Zeilen abwechselnd einfärbst.

Java:
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

@SuppressWarnings("serial")
public class MyCellRenderer extends DefaultTableCellRenderer{

        Color color = new Color(240,240,240)
	@Override
	public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
		JLabel label = (JLabel)super.getTableCellRendererComponent(table, obj, isSelected,hasFocus, row, column);
		
		if((row % 2) == 1 && !isSelected){
			label.setBackground(color);
		}
		else if((row % 2) == 0 && !isSelected){
			label.setBackground(Color.WHITE);
		}
		
		return label;
	}
	

}


MFG

zEriX
 
Zuletzt bearbeitet:
Hi,

erstmal vielen Dank zerix, für deine schnelle und hilfreiche Antwort!

Ich hab da noch ne Frage, ich hab jetzt die Methode so überschrieben dass geprüft wird ob sich die Ziele (row) im übergebenen Vector befindet. Der Vector ergibt sich aus der Suche, dieser Vector wird dem Konstruktor des CellRenderers übergeben.

Aber wie setze ich jetzt den CellRenderer, es gibt die Methode table.setDefaultCellRenderer(Class, TableCellRenderer), aber was geb ich dort als ersten übergabeparameter an, oder ist das die falsche Methode, muss ich die Tabelle danach neu zeichnen (repaint())?

Und noch ein paar kurze Fragen nebenbei:

Was bewirkt dieses @Override?

Gibt es eine Funktion die Überprüft, ob sich ein bestimmter Wert in einem Array, Vector oder ArrayList etc. befindet?

Mfg chriss
 
Hi,

Sorry... hab zuerst gepostet und dann gedacht:rolleyes:

Ich hab als Übergabeparameter einfach Object.class übergeben und färbe somit jedes Objekt ein... hat geklappt.

Aber es werden irgendwie alle Zeilen, ab dem ersten Treffer eingefärbt. Ich poste am besten mal meinen Quellcode für den CellRenderer

Also wenn der übergebene Vector nur den Wert 5 enthält werden alle Zeilen ab der 5 Zeile eingefärbt.
Code:
import java.awt.*; 
import javax.swing.table.*; 
import java.util.Vector;
 
class CellRenderer extends DefaultTableCellRenderer
{
	private Vector rows 			= null;
	private Color color 			= new Color(255,0,0);
	private boolean isMarked 		= false;
	
	CellRenderer( Vector rows )
	{
		this.rows = rows;
	}

    public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) 
    {
    	JLabel label = (JLabel)super.getTableCellRendererComponent(table, obj, isSelected,hasFocus, row, column);

        
    	for(int i=0 ; i<rows.size() ; i++)
    	{
	    	int value = ((Integer)rows.get(i)).intValue();
	    	System.out.println("Zeile: "+value + "/ Row.size():" +rows.size());
	    	if( value==row )
	    	{
	    		isMarked = true;
	    	}
    	}
    	
    	if( isMarked  && !isSelected )
        {
        	label.setBackground(color);
        }
        else 
        {   
            label.setBackground(Color.WHITE);
        }
    	
        return label;
    }
	
}
Mfg Chriss
 
Zuletzt bearbeitet:
Hi,

danke schuetzejanett, hat einwandfrei geklappt.

Jetzt muss ich mal ne evtl. dumme Frage stellen: Bisher dachte ich immer, dass eine einzelne Zelle ein Objekt dieses Renderers wäre das eigentlich nichts anderers ist als ein modifiziertes JLabel... das ist dann wohl nicht so?

Was genau ist eigentich der Renderer
Mfg Chriss
 
Zuletzt bearbeitet:
Moin!
Jede Tabelle(nzelle) hat einen Renderer, welche sie quasi graphisch darstellt.
Normalerweise ist der Renderer im Falle von TabellenZellen ein modifiziertes JLabel, welches u.a. die Schnittstelle ListCellRenderer implementiert.(D.h. auch, man kann jede beliebige Swing Komponente als Renderer nutzen, in dem man sie die beötigten Renderer Schnittstelle implentieren lässt)

Allerdings muss man sich das so vorstellen, das nicht ein Label auf deine Zelle gelegt wird, sondern einfach ein Label an der Stelle gemalt wird.
Ums mal so auszudrücken, es wird nur ein Foto gemacht und abgelegt , anstatt der Komponente selbst.
In den codeblöcken von getTableCellRendererComponent wird dann die Komponente zurückgegeben, von der dann ein Foto gemacht werden soll.

Sobald du dann beispielsweise auf die Stelle in der Tabelle klickt, wir das "Foto" entfernt, und die Editorkomponente aufrufen.. , welche auch wieder eine beliebige Komponente sein kann..

So.. ziemlich unwissenschafftlich, aber ich hoffe mal alle Umklarheiten sind beseitigt. ;)

*grüssle*
MeinerEiner
 
Zuletzt bearbeitet von einem Moderator:
Hi,

@ MeinerEiner_80. jetzt hab ich es glaub schon verstanden, das ist quasi eine "Vorlage" nach der sich die Componenten der Tabelle orientieren.

Desshalb muss ich die Variable "isMarked" am ende wieder auf "false" setzen, weil das selbe "Schablonen-Objekt" für jede Komponente aus der Tabelle verwendet wird, und wenn von der vorherigen Prüfung noch "true" ist wird es für alle weiteren Komponenten auch so bleiben?

Was ich aber nicht ganz verstehe ist, wenn ich folgende Abfrage verwende und mit setValuAt(new ImageIcon("test.gif"), 2,2) verwende, dann wird für jede Zelle das Bild "test.gif" verwendet... welchen Zweck hat dann das übergebene Object obj, immerhin frage ich es doch bei jedem Aufruf ab, warum wird es dann trotzdem angezeigt?

Code:
    	if( obj instanceof ImageIcon )
    	{
    		setIcon((ImageIcon)obj);
    		System.out.println("Image Icon");
    	}
    	else
    	{
    		String value = obj==null ? "" : obj.toString(); 
    		setText(value);
    	}

------------------------------------------------------------------
Falls es noch jemand gebrauchen kann, mit folgender Konfiguration wird auch beim Selektieren der Datensätze die orginal Farbe / Rahmen verwendet.

Code:
    	if(isSelected)
        {
           setBackground(table.getSelectionBackground());
           setForeground(table.getSelectionForeground());
        } 

    	if(hasFocus)
    	{
    		setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
    	}
    	else
    	{
    		setBorder(UIManager.getBorder("Table.cellBorder")); 
    	}


Leider hab ich bisher keine Lösung dafür gefunden, dass nach einer Selektion einer hervorgehoben Zeile, diese wieder in ihre Ursprungsfarbe (weiß) zurück gesetzt wird :confused:

Mfg Chriss
 
Zuletzt bearbeitet:
Hallo

du musst es natürlich auch wieder zurück setzen.
Code:
        if(isSelected)
        {
           setBackground(table.getSelectionBackground());
           setForeground(table.getSelectionForeground());
        } 
        else
        {
            //hier auf die Farbe setzen die du willst.
        }


MFG

zEriX
 
Hi,

wenn ich die Hintergrundfarbe auf weiss setze, wenn isSelected "false" ist, dann sind meine Hervorhebungen weg.

Wenn ich zuerst die Selektierungsfarbe setze und dann die hervorhebungen, dann funktioniert es nicht.

Mfg Chriss
 
Zurück