JTable einzelne Zeilen färben

MechanU

Mitglied
Hi, ich hab folgendes Problem, ich befülle ein JTable mit Daten und würde nun gerne bestimmt Zeilen, anhand eines Wertes in der Tabelle, färben.

Hier mal der Code:

Code:
tblAcSoon = new javax.swing.JTable();
    private Object[][] SoonToBePaidData = {{"", "", "", "", ""}};
    private String []   SoonToBePaidColnames = {"IVNR", "Due to ", "Customer", "Sum", "Status", "Paid"};

        SoonToBePaidData = frontPageService.getSoonToBePaid();
        tblAcSoon.setModel(new DefaultTableModel(SoonToBePaidData, SoonToBePaidColnames) 
        {
            Class[] types = new Class [] {
                java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Boolean.class
            };
            
            boolean[] canEdit = new boolean [] {
                    false, false, false, false, false, true
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
            
            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });

Wenn nun der Wert Status in der Tabelle einen bestimmten wert hat, soll sich die gesamte Zeile färben. Ich weiß, dass ma da einen Renderer benötigt, schaff es aber einfach nicht das umzusetzten.

Hoffe mir kann da wer helfen

mfg
 
Was hast du denn mit dem Renderer schon probiert?

Ich würde dir auf jeden Fall empfehlen ein eigenes Tabellenmodell in einer eigenen Klasse zu schreiben. Dann übergibst du ein ordentliches Objekt in das Modell auf dem du abfragen kannst ob eine Zeile eingefärbt werden soll.

Dann kannst du dir im Renderer für die entsprechende Zeile das Objekt holen und darauf die Eigenschaft abfragen und entsprechend die Hintergrundfarbe ändern.
 
Danke schonmal für die Hilfe, aber es funktioniert immer noch nicht.

Also ich erzeuge hiermit den Renderer:
Code:
        DefaultTableCellRenderer ren = new ColoredTableCellRenderer();
        tblAcSoon.setDefaultRenderer(Object.class , ren);

Und hier ColoredTableCellRenderer:
Code:
import java.awt.*; 
import javax.swing.JTable;
import javax.swing.table.*; 
 
class ColoredTableCellRenderer extends DefaultTableCellRenderer 
{ 
  private static final int VALIDATION_COLUMN = 4;  
  public Component getTableCellRendererComponent(  JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int col)
  {
      Component comp = super.getTableCellRendererComponent(table,  value, isSelected, hasFocus, row, col); 
      String s =  table.getModel().getValueAt(row, VALIDATION_COLUMN ).toString();

        if(s.equalsIgnoreCase("Open")) 
       {
        	System.out.println("Open");
        	comp.setBackground(Color.RED);
       }
       return( comp );
   } 
}

Wenn ich value ausgebe, wir mir nur die komplette dritte Spalte ausgegeben.
Bei System.out.println("Open"); wird es so oft ausgeben, wie es vorhanden ist, dass passt auch, nur wird dann die falsche Kompenete gefärbt.

mfg
 
Hi MechanU,
ich denke es liegt an der Zuweisung des Renderes im Table.
tblAcSoon.setDefaultRenderer(Object.class , ren);

Gruß Takidoso
 
ok, hab das einfärben jetzt hinbekommen, hab jetzt aber schon wieder ein Problem, und zwar in der letzten Spalte sind nur checkboxen enthalten (java.lang.Boolean.class), wenn ich jetzt den Aufruf

Code:
tblActTodo.setDefaultRenderer(Boolean.class, ren);

mache, wird die Hintergrundfarbe zwar richtig angezeit, nur verschwinden die Checkboxen und es steht nur noch true oder false darin, weiß da jemand eine Lösung?
 
Jo :)
ist logsch das das so passieren muss, da Du den schon vordefinierten Defaultrenderer für Booleans mit dem Deinen ausgetauscht hast.

Mir ist geade noch nicht ganz klar was Du machen möchtest. Möchtest Du die einzelne Zelle einfärben, wenn Du ein Open findest, oder möchtest Du die ganze Zeile einfärben wo ein Open in der entsprechenden Spalte vorkommt?

letzteres könne man prinzipiell vielleicht so angehen, in dem man die Original Renderer entweder ableitet und lediglich die Farbe entsprechend der Spalte variieren lässt und diese als DefaultRenderer mit den alten einsetzt.
Oder man erschaft sich einen Renderer, der den DefaultRenderer holt und zurückgibt aber die Farbe wie gewünscht ändert. Diesen Renderer würde man dann für alle anderern DefaultRenderer einsetzen.
Du könntest aber auch (was ich normalerweise tuhe) der Spalte also TableColumn den Renderer geben.

Da die Farbgebung meistens nicht viel mit der eigetnlichen Gestaltung oder Formatierung der Ausgabe zu tun hat, habe ich mir angewöhnt diese getrennt zu betrachten und ein ColorModel zu erschaffen, welches alle meine Renderer unterstützen. Du könntest auf diese Weise eine total getrennte Algorythmik für die Färbung mit nur setzen des ColorModels in den Renderern erreichen. Finde ich recht angenehm.
Soetwas findest Du in diesem Thread
 
Zuletzt bearbeitet:
Ich möchte die ganze Zeile einfärben (Hintergrund), wenn in der Spalte Status, Open drin steht, auch der Hintergrund der checkboxen soll miteingefärbt werden.

Leider befasse ich mich erst seit kurzen mit diesem Thema. Ein eigenes ColorModel zu erstellen erscheint mir hier etwas zuviel (wird nur einmal benötigt). Wäre super wenn die mir codausschnitte posten könntest, damit ich die umsetzug hinbekommen

mfg und danke
 
Ich würds so in etwa machen:

Java:
public class PayingTableModel extends DefaultTableModel {

	private String[] colnames = {"IVNR", "Due to ", "Customer", "Sum",
			"Status", "Paid"};

	private List<PayingData> rows;

	public PayingTableModel(List<PayingData> data) {
		this.rows = data;
	}

	@Override
	public String getColumnName(int column) {
		return colnames[column];
	}

	@Override
	public boolean isCellEditable(int row, int column) {
		return false;
	}

	@Override
	public Object getValueAt(int row, int column) {

		if (row >= 0 && row < rows.size( )) {
			final PayingData payingData = rows.get(row);

			switch (column) {
				case 0:
					return payingData.getIVNR( );
				case 1:
					return payingData.getDueTo( );
				case 2:
					return payingData.getCustomer( );
				case 3:
					return payingData.getSum( );
				case 4:
					return payingData.getStatus( );
				case 5:
					return payingData.isPaid( );
				default:
					return "";
			}

		}

		return super.getValueAt(row, column);
	}

	@Override
	public void setValueAt(Object value, int row, int column) {
		// TODO Auto-generated method stub
	}

	@Override
	public int getRowCount() {
		if (rows == null) {
			return 0;
		}
		return rows.size( );
	}

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

	public boolean isOpen(int row) {
		return rows.get(row).getStatus( ).equalsIgnoreCase("open");
	}

Java:
public static class PayingData {

		private String IVNR;
		private String dueTo;
		private String customer;
		private String sum;
		private String status;
		private boolean paid;

		public PayingData(String ivnr, String dueTo, String customer,
				String sum, String status, boolean paid) {
			this.IVNR = ivnr;
			this.dueTo = dueTo;
			this.customer = customer;
			this.sum = sum;
			this.status = status;
			this.paid = paid;
		}

		/**
		 * @return the iVNR
		 */
		public String getIVNR() {
			return IVNR;
		}

		/**
		 * @return the dueTo
		 */
		public String getDueTo() {
			return dueTo;
		}

		/**
		 * @return the customer
		 */
		public String getCustomer() {
			return customer;
		}

		/**
		 * @return the sum
		 */
		public String getSum() {
			return sum;
		}

		/**
		 * @return the status
		 */
		public String getStatus() {
			return status;
		}

		/**
		 * @return the paid
		 */
		public boolean isPaid() {
			return paid;
		}

	}

Java:
public static class ColoredTableCellRenderer extends
			DefaultTableCellRenderer {

		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int col) {

			final Component comp;
			PayingTableModel model = (PayingTableModel) table.getModel( );

			if (col == 5) {
				final JCheckBox checkBox = new JCheckBox( );
				checkBox.setSelected((Boolean) value);
				comp = checkBox;

			}
			else {
				comp = super.getTableCellRendererComponent(table, value,
						isSelected, hasFocus, row, col);
			}

			if (model.isOpen(row)) {
				comp.setBackground(Color.RED);
			}
			else {
				comp.setBackground(Color.WHITE);
			}
			return comp;
		}
	}

Java:
public static void main(String[] args) {
		PayingTableModel model = new PayingTableModel(Arrays
				.asList(new PayingData("test", "test", "test", "test",
						"closed", false), new PayingData("test", "test",
						"test", "test", "open", false)));

		JFrame f = new JFrame("title");
		f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		f.setLayout(new BorderLayout( ));

		JTable table = new JTable(model);
		f.add(table, BorderLayout.CENTER);
		table.setDefaultRenderer(Object.class, new ColoredTableCellRenderer( ));

		JScrollPane scroll = new JScrollPane(table);
		f.add(scroll, BorderLayout.CENTER);

		f.setSize(300, 300);

		f.setVisible(true);
	}
 
Zuletzt bearbeitet:
Danke vielmals für den Code, hab dass auch gleich ausprobiert, hab nur zwei Probleme:
1. Im ColoredTableCellRenderer bekomm ich bei
Code:
PayingTableModel model = (PayingTableModel) table.getModel();
eine "cannot be cast to others.PayingTableModel" Exception, also auf diese Model Casten funktioniert nicht.

2. Meine Daten für die Tabelle stehen in einem Object[][], wo baue ich das ein?

mfg
 
Zurück