Swing JTable - Zeilen färben (mit Model)

ObiKenobi

Mitglied
Hallo,

folgendes Problem oder gegebenheit.

Ich würde ganz gerne einzelne Spalten (die die unterschiede in den Daten aufweisen) farblich hervorheben.

Bin mir nur nicht ganz sicher wie ich das mache wenn ich die Tabelle mit "model" zeichne.

Ich generiere die Tabelle folgendermaßen.

Java:
	private String[] titles = new String[] { "", "Database A", "Database B" };
	final DefaultTableModel model = new DefaultTableModel(titles, 0);
	private JTable table = new JTable(model);

Die daten kommen folgendermaßen in die JTable

Java:
							// model.addRow(new Object[] { "Schema", "", "" });
					model.addRow(new Object[] { "Tablename", columnData.tableName, columnData.tableName });
					model.addRow(new Object[] { "Columnname", columnData.columnName, columnData.columnName });
					model.addRow(new Object[] { "Type", columnData.columnTypeA, columnData.columnTypeB });
					model.addRow(new Object[] { "Size", columnData.columnSizeA, columnData.columnSizeB });
					model.addRow(new Object[] { "Auto Increment", columnData.isAutoIncrementA, columnData.isAutoIncrementB });
					model.addRow(new Object[] { "Case Sensitive", columnData.isCaseSensitive, columnData.isCaseSensitiveB });
					model.addRow(new Object[] { "Currency", columnData.isCurrencyA, columnData.isCurrencyB });
					model.addRow(new Object[] { "Writable", columnData.isWritableA, columnData.isWritableB });
					// model.addRow(new Object[] { "Def. Writable", columnData.isDefinitelyWritableA, columnData.isDefinitelyWritableB });
					// model.addRow(new Object[] { "Nullable", columnData.isNullableA, columnData.isNullableB });
					model.addRow(new Object[] { "Read Only", columnData.isReadOnlyA, columnData.isReadOnlyB });
					model.addRow(new Object[] { "Searchable", columnData.isSearchableA, columnData.isSearchableB });
					model.addRow(new Object[] { "Signed", columnData.isSignedA, columnData.isSignedB });

Für jeder der Variablen habe ich noch ein boolean im OBjekt (z.B. isSignedEqual).
Nun würde ich gerne für den Fall das z.B. "isSignedEqual" false is die dementsprechende Spalte farbig machen.

Wie ich das mache ist mir schon klar (von wegen JTree-Renderer überschreiben) ich hab nur absolut keine Idee wie ich dem die Variable ob sie nun gleich sind (oder nicht) übergeben soll...

Könntet ihr mir dabei helfen? Dafür wäre ich euch sehr dankbar.

Grüße,
Obi
 
dem Renderer kann man nichts übergeben, außer der Klasse an sich die ganze Tabelle/ das Model usw.,

der Renderer bekommt beim automatischen Ablauf in der render-Methode Zeile + Spalte und kann anhand dieser Informationen
im Model oder sonstwo Informationen abfragen und dann Farbe setzen usw.
 
Es wäre möglich z.B im Model die Daten in bestimmte Objekte zu packen, die Eigenschaften wie Farbe beinhalten. Auf diese müsstest du dann im Renderer casten und dann eben die Farbe einstellen.

z.B:
Java:
class MyTableCellValue
{
Color bgColor,textColor;
Object value;
}
 
@ObiKenobi
ich kann deine Aussagen nicht nachvollziehen, insofern vermute ich, dass du auf mein bezogen nicht richtig verstehst, nein

von Spalten generieren habe ich nicht gesprochen,
'direkt danach' klingt irgendwie komisch, mit 'quasi' noch mehr,

was jetzt speziell mit der letzen Zeile passiert kann ich nicht beurteilen,
mag sein dass du vorher irgendwann ja Farben zugewiesen hast, ja, wobei 'bunt' eine komische Farbe ist,
mit dem Render-Prozess scheint mir das wenig zu tun zu haben, jedenfalls ist dort jede Zeile/ Spalte gleich,
eine letzte fällt nicht direkt als solche auf

vielleicht erzählst du auch richtiges zu deinem Programm, ich sehe aber nicht durch,
wie ein Renderer aufgebaut ist dürfte aus den Beispielen klar sein
 
Hallo,

vielen Dank für die Zahlreichen tipps.

Ich bin jetzt zu dem schluss gekommen das ich die Farbinformationen ganz gern im Vektor bzw. im Model speichern würde und dann über den Renderer aufrufen würde.

Da sich die Farbinformationen nur pro Zeile und nicht pro spalte ändern würden, ist es irgendwie möglich die Farbinformationen nur EINMAL für die ganze Zeile zu speichern oder muss ich für jede spalte ein extra Objekt anlegen das die Farbinformationen enhtält?

Und wenn ja, wie?

Grüße,
Obi
 
wie würdest du es denn pro Spalte (und anscheinend auch pro Zeile) machen?
wenn du das kannst, dann mache das erstmal, dann wäre es danach relativ leicht zu ändern,

du hast für jedes einzelnde Rendern den Zeilen- und den Spalten-Index,
selbstverständlich kannst du auch auf Daten zugreifen nur mit dem Zeilen-Index, wenn die Daten entsprechend aufgebaut sind,

grundsätzlich ist das nicht viel anders, irgendwo im Model, bei deinen normalen Daten oder in separaten Variablen/ Arrays/ Listen/ Maps, was auch immer, musst du die Daten ablegen und darauf zugreifen,
die normalste Sache der Welt

wenn du 50 Zeilen hast und ein Array mit 50 Feldern für die 50 Farben anlegst, dann kannst du sowieso nicht mehr machen
als mit Zeilenindes 0, 17 oder 49 drauf zugreifen, du kämst gar nicht in die Verlegenheit den Spaltenindex noch zu nutzen

bei 50 Zeilen und 7 Spalten aber ein 50x7 Array anzulegen, in jeder Zeile 7x dieselbe Farbe abzulegen
und später per Spaltenindex unter den jeweils 7 gleichen Farben auszuwählen, das erscheint nicht so schlau
 
Ich bin noch nicht so ganz sicher mit der Java-Materie. Deshalb sind meine Ideen meist nur Theoretisch.

Meine Idee war, ein eigenes Model anzulegen (nennen wirs mal MyModel :bahnhof🙂

Und in das MyModel die Daten folgendermaßen abzulegen :

IsDifferent (true / false - heißt Farblich hervorheben)
und
Vector ( { Spalte 1 , Spalte 2 , Spalte 3, ... } )

lässt sich das so pauschal machen?

Bin gerade schon wie wild am googlen wie ich ein eigenes "Model" anleg, aber so das der auch immer noch meine "Titles" übernimmt.

EDIT :

Okay, mein eigenes MOdel hab ich jetzt schonmal,

jetzt muss ich nurnoch die Farbkennung reinbekommen 😀
 
Zuletzt bearbeitet:
OKay Hi,

ich schon wieder,

aktueller stand :


Java:
		public class MyTableModel extends DefaultTableModel {
	
		public MyTableModel(String[] titles, int i) {
			super(titles, i);
		}

		public void addRow(boolean isEqual, Object[] rowData) {
			
		}



		public boolean isCellEditable(int rowIndex, int columnIndex) {
			return false;
		}

	}

	public class MyTableCellRenderer extends DefaultTableCellRenderer {

		public Component getTableCellRendererComponent(JTable table, Object value,boolean isEqual, boolean isSelected, boolean hasFocus, int row, int column) {
			Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

				comp.setBackground(Color.WHITE);
				comp.setForeground(Color.BLACK);
			

			return this;
		}

	}


jetzt müsste ich nurnoch die Boolean Variable aus dem Model in den Renderer kriegen...

weiß gerade aber absolut nicht wie...
 
Zuletzt bearbeitet:
welche boolean-Variable? die isCellEditable()-Methode?
du hast die JTable als Parameter, dort kannst du das Model abfragen, gegebenenfalls auf deine Klasse casten,
aber isCellEditable() gibt schon das Interface TableModel vor, diese Methode kann im Model aufgerufen werden
 
Heyho, ich schreite vorran...


Ich übergebe beim "model-Objekt"

folgendes

Java:
				model.addRow(false, new Object[] { "Tablename", columnData.tableName, columnData.tableName });
					model.addRow(true, new Object[] { "Columnname", columnData.columnName, columnData.columnName });
					model.addRow(false, new Object[] { "Type", columnData.columnTypeA, columnData.columnTypeB });

wobei false dafür steht das die Spalte farbig sein soll und true dafür das sie "einheitlich" sein soll.

Mein "eigenes" Modell sieht jetzt folgendermaßen aus :

Java:
	public class MyTableModel extends DefaultTableModel {
		private static final long serialVersionUID = 1L;
		private boolean colored;

		public MyTableModel(String[] titles, int i) {
			super(titles, i);
		}

		public void addRow(boolean isEqual, Object[] objects) {
			// TODO Auto-generated method stub
			addRow(objects);
			colored = !isEqual;
		}

		public boolean isCellEditable(int rowIndex, int columnIndex) {
			return false;
		}

		public boolean isColored() {
			return colored;
		}

	}

Und mien TableCellRenderer so :
Java:
	public class MyTableCellRenderer extends DefaultTableCellRenderer {
		private static final long serialVersionUID = 1L;

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

			System.out.println(model.isColored() + " and " + value);
			
			if (model.isColored()) {
				comp.setBackground(Color.RED);
				comp.setForeground(Color.WHITE);
			} else {
				comp.setBackground(Color.WHITE);
				comp.setForeground(Color.BLACK);
			}

			return this;
		}

	}

Leider bekommt der Table Cell renderer aber irgendwie immer den selben Boolean obwohl ich verschiedene übergeb. Kann mir gerade nicht so erklären warum.
 
colored ist ein einzelnes Feld/ Attribut im Model, selbst wenn sich das bei mehreren addRow()-Aufrufen ändert wird maximal der letzte Wert gespeichert,
wie kann so eine grundlegende Tatsache, nicht nur von Programmierung sondern von der Welt allgemein, unverständlich sein?

wenn du auf eine Wand immer wieder Aufkleber übereinander klebst, ist am Ende nur der letzte zu sehen..

du brauchst eine Liste, Array oder sonst eine Datenstruktur für mehrere Werte, wie schon gesagt,
auch habe ich gesagt bzw. ist komplett selbstverständlich, dass du den Zeilenindex irgendwie nutzen musst,
wie soll ein Aufruf model.isColored() für Zeile 7 was anderes zurükgeben als für Zeile 8?
dass der Index mit übergeben werden muss ist doch so sonnenklar..,
oder soll ein Bankautomat den richtigen Kontostand anzeigen ohne dass man eine Karte hineinsteckt?
grundlegendste Grundlagen der gesamten Logik überhaupt..
 
colored ist ein einzelnes Feld/ Attribut im Model, selbst wenn sich das bei mehreren addRow()-Aufrufen ändert wird maximal der letzte Wert gespeichert,
wie kann so eine grundlegende Tatsache, nicht nur von Programmierung sondern von der Welt allgemein, unverständlich sein?

wenn du auf eine Wand immer wieder Aufkleber übereinander klebst, ist am Ende nur der letzte zu sehen..

du brauchst eine Liste, Array oder sonst eine Datenstruktur für mehrere Werte, wie schon gesagt,
auch habe ich gesagt bzw. ist komplett selbstverständlich, dass du den Zeilenindex irgendwie nutzen musst,
wie soll ein Aufruf model.isColored() für Zeile 7 was anderes zurükgeben als für Zeile 8?
dass der Index mit übergeben werden muss ist doch so sonnenklar..,
oder soll ein Bankautomat den richtigen Kontostand anzeigen ohne dass man eine Karte hineinsteckt?
grundlegendste Grundlagen der gesamten Logik überhaupt..

Naja ich bin davon ausgegangen das er die Zeile Zeichnet und dann zum nächsten AddRow springt. Wenn das so ist ist das problem ja echt nur Trivial 😀

Danke!
 
der Renderer kommt erst viel später dran und auch diverse Male, je nachdem wann wie oft gezeichnet werden muss,
mit dem seltenen Zusammenstellen der Daten ist das nicht verknüpft
 

Zurück
Oben