# Cell Farbe in JTable



## JAVA_INSEL (3. Jun 2007)

Hi,

ich habe lang gesucht viel gefunden aber haben bis jetzt zu keiner Lösung geführt. Ich will, wenn ein User in der Tabelle eine Zelle klickt, dann soll diese Zelle farbig markiert werden. Leider konnte ich bis jetzt nicht hinkriegen, dass es die Zelle rot markiert. Ich würde mich freuen, fall Ihr mir helfen könnt.

Grüße
java insel


----------



## Wildcard (3. Jun 2007)

Dafür brauchst du einen Renderer.
In unserer FAQ wirst du fündig.


----------



## JAVA_INSEL (3. Jun 2007)

Wildcard hat gesagt.:
			
		

> Dafür brauchst du einen Renderer.
> In unserer FAQ wirst du fündig.



so was habe ich auch eingebaut:


 public class ColorRenderer extends JLabel implements TableCellRenderer {

	    	public ColorRenderer(boolean isBordered) {
	    		setOpaque(true); //MUST do this for background to show up.
	    	}

	       public Component getTableCellRendererComponent( JTable table, Object color, boolean isSelected, boolean             hasFocus,int row, int column) {
	    	   	  Color newColor = (Color)color;
	    	   	  setBackground(newColor.red);

	    	   	  return this;
	}
	}


table.setDefaultRenderer(Color.class, new ColorRenderer(true));


Irgendwie hilft es nicht. Muss ich irgendwie refreshen oder ???


----------



## Wildcard (3. Jun 2007)

JAVA_INSEL hat gesagt.:
			
		

> table.setDefaultRenderer(Color.class, new ColorRenderer(true));


In deiner Table sind also Color-Objekte?


----------



## JAVA_INSEL (3. Jun 2007)

Wildcard hat gesagt.:
			
		

> JAVA_INSEL hat gesagt.:
> 
> 
> 
> ...




Jetzt habe ich so umgeschrieben:


public class YourTableCellRenderer extends DefaultTableCellRenderer {

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

			System.out.println(row);



    return c;
 }

Es funktioniert so:

TableColumn tableColumn = table.getColumnModel().getColumn(column);
			  tableColumn.setCellRenderer(new YourTableCellRenderer());


d.h. nur mit Spalten

so:
table.setDefaultRenderer(Object.class, new YourTableCellRenderer() );

funktioniert es nicht. Ich weiss nicht warum?


----------



## Wildcard (3. Jun 2007)

Was steht den nun in deiner Tabelle? Objects wohl kaum...


----------



## JAVA_INSEL (3. Jun 2007)

Wildcard hat gesagt.:
			
		

> Was steht den nun in deiner Tabelle? Objects wohl kaum...



Ich habe alle Daten so String[][] rowData angelegt.

Gruß


----------



## Wildcard (3. Jun 2007)

Dann setz den Renderer für String.class


----------



## JAVA_INSEL (3. Jun 2007)

Wildcard hat gesagt.:
			
		

> Dann setz den Renderer für String.class



Leider hat es so:

table.setDefaultRenderer(String.class, new YourTableCellRenderer() );

auch nichts gebracht. Muss man dann irgendwie refresh von table machen oder so was ähnliches?


----------



## Wildcard (3. Jun 2007)

Poste mal ein kleines, lauffähiges Beispiel, das deinen Fehler demonstriert.


----------



## JAVA_INSEL (3. Jun 2007)

Wildcard hat gesagt.:
			
		

> Poste mal ein kleines, lauffähiges Beispiel, das deinen Fehler demonstriert.



Ich habe das ganze über mehrere Klassen verteilt. Das ist wirklich schlecht.

Aber was mich ein bisschen verwirrt:

 table.setDefaultRenderer(String.class, new YourTableCellRenderer() );


Ich mache das nicht am Anfang wo ich dann die JTable anlege sondern erst wenn der User eine Zeile ausgewählt hat. Hat es damit was zu tun. Weisst du vielleicht etwas darüber?


----------



## Wildcard (3. Jun 2007)

Die Renderer setzt man einmalig und nicht zur Laufzeit.



> Ich habe das ganze über mehrere Klassen verteilt. Das ist wirklich schlecht.


Daher habe ich dich gebeten ein Beispiel zu schreiben, nicht eins zu kopieren  :wink: 
Wenn ich ein Beispiel schreibe bringt das wohl wenig, denn in der FAQ ist ja schon eins.


----------



## JAVA_INSEL (3. Jun 2007)

Wildcard hat gesagt.:
			
		

> Die Renderer setzt man einmalig und nicht zur Laufzeit.
> 
> 
> 
> ...



Aber ich brauche zur Laufzeit, weil der User selektiert eine Zelle erst nachdem er die Daten gesehen hat. Was für Möglichkeiten bestehen noch? Weisst du vielleicht etwas darüber?


Gruß


----------



## Wildcard (3. Jun 2007)

Nein, du setzt den Renderer einmal. Im Renderer reagierst du dann auf isSelected


----------



## André Uhres (3. Jun 2007)

JAVA_INSEL hat gesagt.:
			
		

> ..wenn ein User in der Tabelle eine Zelle klickt, dann soll diese Zelle farbig markiert werden..


Tabellen-abhängige Erfordernisse löst man am einfachsten über "prepareRenderer" (man braucht dann keinen Renderer).
Hier ist das Beispiel aus Benis JTable Tutorial (hab nur die Logik in prepareRenderer etwas angepasst):

```
package table;
import java.awt.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableRendering extends JFrame{
    public TableRendering(){
        //  Model:
        Object[] columnNames = {"Type", "Date", "Company", "Shares", "Price"};
        Object[][] data =
        {
            {"Buy", new Date(), "IBM", new Integer(1000), new Double(80.50)},
            {"Sell",new Date(), "MicroSoft", new Integer(2000), new Double(6.25)},
            {"Sell",new Date(), "Apple", new Integer(3000), new Double(7.35)},
            {"Buy", new Date(), "Nortel", new Integer(4000), new Double(20.00)}
        };
        DefaultTableModel model = new DefaultTableModel(data, columnNames) {
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        // prepareRenderer überschreiben:
        table = new JTable( model ) {
            public Component prepareRenderer(
                    TableCellRenderer renderer, int row, int column) {
                JComponent c = (JComponent) super.prepareRenderer(renderer, row, column);
                c.setBackground(Color.WHITE);
                if (isRowSelected(row) && isColumnSelected(column))
                    c.setBackground(Color.RED);
                return c;
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        getContentPane().add(new JScrollPane( table ), BorderLayout.CENTER);
    }
    private JTable table;
    public static void main(String[] args) {
        TableRendering frame = new TableRendering();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}
```


----------



## JAVA_INSEL (3. Jun 2007)

André Uhres hat gesagt.:
			
		

> JAVA_INSEL hat gesagt.:
> 
> 
> 
> ...



Zuerst Vielen Dank für so ein ausführlicheres Beispiel. Würde es auch gehen,wenn ich den User eine Farbpalette anbieten wo er dann die Farbe auswählen kann und dann wenn er die Farbe ausgewält hat ,soll die Zelle mit dem ausgewählten Farbe markiert werden.

Gruß


----------



## André Uhres (3. Jun 2007)

JAVA_INSEL hat gesagt.:
			
		

> ...Würde es auch gehen,wenn ich den User eine Farbpalette anbieten
> wo er dann die Farbe auswählen kann und dann wenn er die Farbe ausgewält hat ,
> soll die Zelle mit dem ausgewählten Farbe markiert werden..


In dem Fall speicherst du die Farbe in einer Variablen auf die du in prepareRenderer zugreifst.
Kann sein, daß du "table.updateUI();" aufrufen musst, wenn du die Farbe nachträglich änderst.
Wenn die Zelle dauerhaft gefärbt bleiben soll, dann musst du die Information pro Zelle speichern, z.B. in einer Map.
Dazu hier ein Bespielcode: http://www.java-forum.org/de/viewtopic.php?p=287701#287701


----------



## JAVA_INSEL (4. Jun 2007)

André Uhres hat gesagt.:
			
		

> JAVA_INSEL hat gesagt.:
> 
> 
> 
> ...



Danke. Ich probiere es mal aus. Sobald ich was habe, dann melde ich mich wieder.

Gruß

 :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:


----------



## thE_29 (4. Jun 2007)

Achja, das mit Object.class müsste auf alles zutreffen (es ist alles von Object).

Hast du vielleicht irgendwo ein fireTableDataStructurChanged()? Den das ENTFERNT alle Renderer automatisch (es setzt auch die Spaltenbreiten auf das hin was Java grad so einfällt).

Das Problem hatte ich auch mal 

Und war das erste Bsp mit dem Color Code ernst gemeint? Sowas ist doch net lauffähig!


----------



## André Uhres (4. Jun 2007)

thE_29 hat gesagt.:
			
		

> ..Hast du vielleicht irgendwo ein fireTableDataStructurChanged()? Den das ENTFERNT alle Renderer automatisch..


fireTableStructureChanged() entfernt die Renderer die an bestimmten Spalten hängen, 
aber nicht die DefaultRenderer, d.h. die Renderer, die mit table.setDefaultRenderer(..) gesetzt werden, bleiben erhalten.


----------



## thE_29 (4. Jun 2007)

Naja, dann halt nur die 

Ich setze ja nie per default für alle Spalten den gleichen Renderer! Aber es entfernt eben die Renderer!


----------



## André Uhres (4. Jun 2007)

Upps


----------



## André Uhres (4. Jun 2007)

thE_29 hat gesagt.:
			
		

> ..Aber es entfernt eben die Renderer!


Das ist auch logisch: wenn die *Struktur *der Tabelle geändert wird, 
dann kann man ja nicht mehr sagen, ob der Renderer einer bestimmten Spalte 
noch immer auf diese Spalte passt.
Anders verhält es sich mit fireTable*Data*Changed(), da bleibt die Struktur ja gleich
und daher bleiben auch die Renderer.


----------



## thE_29 (4. Jun 2007)

Jop 
Auf das bin ich dann auch draufgekommen 
Man sollte sich halt Befehle durchlesen, bevor man sie nimmt! Aber oft ist es halt so, das es in den meisten Fällen hinhaut und dann in ein paar eben nicht!


----------



## JAVA_INSEL (6. Jun 2007)

Hallo,

bei mir funktioniert irgendwie nicht. Ich glaube deshalb:

JTable table = new JTable();


Ich lege table zuerst an und nachher will ich die Zellen Farbe ändern. Hat es vielleicht damit was zu tun? Nachdem alle Daten drin sind, will ich dynamisch die Zellen Farbe ändern:

public void changeCellColor(Color color, int[] rows, int[] columns) {

		for(int i = 0; i < rows.length; i++) {
			Component c = table.prepareRenderer(cellRenderer, rows_, columns);
			c.setBackground(color);
		}
		table.updateUI();

	}




Hilft mir bitte mal weiter?

Gruß_


----------



## André Uhres (6. Jun 2007)

Du musst "prepareRenderer" *überschreiben* und nicht aufrufen.
Die Methode "prepareRenderer" wird dann zum Zeitpunkt der Darstellung der Daten automatisch aufgerufen.


----------



## JAVA_INSEL (6. Jun 2007)

André Uhres hat gesagt.:
			
		

> Du musst "prepareRenderer" *überschreiben* und nicht aufrufen.
> Die Methode "prepareRenderer" wird dann zum Zeitpunkt der Darstellung der Daten automatisch aufgerufen.



Hallo,

aber in der Bespiel wo du zeigst, ruftst du die prepareRender Methode gleich mit new JTable auf. Aber ich will nachdem es angelegt wurde, dass diese Methode aufgerufen wird. 

Ich würde mich freuen, falls due mir weiterhelfen würdest.

Gruß


----------



## André Uhres (6. Jun 2007)

JAVA_INSEL hat gesagt.:
			
		

> ..aber in der Bespiel wo du zeigst, ruftst du die prepareRender Methode gleich mit new JTable auf..


Du meinst den super-Aufruf? Aber der ist doch ein Teil der überschriebenen prepareRender-Methode!
Er wird demnach ebenfalls nicht direkt ausgeführt, sondern indirekt durch die JTable API.


----------



## JAVA_INSEL (6. Jun 2007)

André Uhres hat gesagt.:
			
		

> JAVA_INSEL hat gesagt.:
> 
> 
> 
> ...



Okay ich habe soweit hingekriegt. Aber nächste Problem ist, wenn ich mit Maus auf eine Zeile klicke, dann verschwindet die Farbe wieder. 



Woran kann es denn liegen?


----------



## JAVA_INSEL (7. Jun 2007)

JAVA_INSEL hat gesagt.:
			
		

> André Uhres hat gesagt.:
> 
> 
> 
> ...




Wie du gesagt hast, habe ich einfach alle Cells in Map gespeicher. Weil ich will, dass die Farben aufs Dauer gespeichert werden. UND ES FUNKTIONIER.Vielen Dank:


 :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :applaus:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:  :lol:


----------



## JAVA_INSEL (7. Jun 2007)

Hallo,

wenn ich die Farben aufs Dauer speichern will, würde es denn mit Methode:

getTableCellEditorComponent  auch nicht gehen?

Nur eine Neugierige Frage.

Gruß


----------



## André Uhres (7. Jun 2007)

Die Darstellung der JTable erfolgt nur im Renderer (bzw. prepareRenderer). 
Der Editor spielt eine ganz andere Rolle.


----------

