Discussion:
jak zmienic kolor tla danego wiersza w jtable
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
Grzegorz Dribczak
2004-04-18 20:21:55 UTC
Permalink
witam,

czy wie ktos jak zmienic kolor tla danego wiersza w jtable?
moze macie jakis przyklad.
--
drypek
pljosh(at)poczta_neostrada_pl
2004-04-18 23:33:27 UTC
Permalink
Post by Grzegorz Dribczak
witam,
czy wie ktos jak zmienic kolor tla danego wiersza w jtable?
moze macie jakis przyklad.
hmm - w sumie wydaje mi sie, ze wbrew pozorom nie jest to taka
trywialna sprawa - co nie znaczy (mam nadzieje), ze jest to jakies super
mega skomplikowane :)
Wydaje mi sie, ze w takiej tabeli trzeba by podmienic
DefaultTableCellRenderer dla wybranych kolumn/wierszy lub wg innego
wzorca na cos innego...
Ten link moze Cie naprowadzi:
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#renderer

Ogolnie to chetenie sie przylacze do pytania, bo sam mam w "to-do" (ale
to takie bardziej odlegle to-do) wpisane zrobienie roznego koloru tla
lub czcionki w ostatnim wietrszu mojej tabeli w zaleznosci od pewnych
zmiennych :)
pljosh(at)poczta_neostrada_pl
2004-04-18 23:43:36 UTC
Permalink
Post by Grzegorz Dribczak
witam,
czy wie ktos jak zmienic kolor tla danego wiersza w jtable?
moze macie jakis przyklad.
ha - chyba cos jednak mam:
w ponizszym linku:
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/table/DefaultTableCellRenderer.html#method_summary
czytamy:

setBackground(Color c)
Overrides JComponent.setBackground to assign the unselected-background
color to the specified color.

setForeground(Color c)
Overrides JComponent.setForeground to assign the unselected-foreground
color to the specified color.

Teraz jak sie dostac do tego DefaultTableCellRenderer?
w ponizszym linku:
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTable.html#method_summary
czytamy:

getCellRenderer(int row, int column)
Returns an appropriate renderer for the cell specified by this row and
column.

Wyglada to wiec jednak chyba trywialnie (o ile to zadziala)
mojaTabelka.getCellRenderer(2,3).setBackground(Color(GREEN));

Nie sprawdzalem, ale to moze byc to :)
pljosh(at)poczta_neostrada_pl
2004-04-19 00:08:17 UTC
Permalink
Post by pljosh(at)poczta_neostrada_pl
mojaTabelka.getCellRenderer(2,3).setBackground(Color(GREEN));
oczywiscie jak juz, to nie Color(GREEN) tylko Color.GREEN, bo GREEN to
jest pole a nie... no wlasnie - dobre pytanie - czym by musial byc
GREEN, zeby to tak dzialalo? Parametrem statycznego konstruktora? :)
hehe - chyba jednak raczej funkcja w wydaniu np. C albo TPascala :)
Oczywiscie to retorycznie - nie zebym proponowal dyskusje na ten temat...
Jarek Krochmalski
2004-04-19 05:19:26 UTC
Permalink
Uzytkownik "pljosh(at)poczta_neostrada_pl"
Post by pljosh(at)poczta_neostrada_pl
oczywiscie jak juz, to nie Color(GREEN) tylko Color.GREEN, bo GREEN to
jest pole a nie... no wlasnie - dobre pytanie - czym by musial byc
GREEN, zeby to tak dzialalo? Parametrem statycznego konstruktora? :)
hehe - chyba jednak raczej funkcja w wydaniu np. C albo TPascala :)
Oczywiscie to retorycznie - nie zebym proponowal dyskusje na ten temat...
widze, ze prowadzisz sobie taki maly wywodzik monolog, tak?

pozdro
http://jotkacafe.prv.pl
Bartek
2004-04-19 13:28:49 UTC
Permalink
Post by pljosh(at)poczta_neostrada_pl
Wyglada to wiec jednak chyba trywialnie (o ile to zadziala)
mojaTabelka.getCellRenderer(2,3).setBackground(Color(GREEN));
Nie sprawdzalem, ale to moze byc to :)
kiedyś zdarzyło mi się napisać taki CellRenderer, którego tło zależy od
przechowywanej wartośći (w moim przypadku wartość to obiekt klasy
org.apache.log4j.Priority).

Z tego co pamiętam, to nie było to całkiem trywialne (kod przedstawiam
poniżej, może do czegoś Ci się przyda).
ZTCP musiałem przepisać kawałek oryginalnej implementacji tej klasy ze
źródeł javy, bo inaczej coś tam nie grało. W każdym razie poniższa
klasa działa poprawnie (jest częścią projektu chainsaw - przeglądarki
logów generowanych przez log4j).

Pozdrawiam
Bartek




package com.puppycrawl.tools.chainsaw;

import javax.swing.table.*;
import javax.swing.*;

import org.apache.log4j.Category;
import org.apache.log4j.Priority;
import java.awt.*;

public class PriorityFieldCellRenderer extends DefaultTableCellRenderer
{

private Color unselectedForeground;
private Color unselectedBackground;

protected void setValue(Object value) {
super.setValue(value);
}

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

Priority priority = (Priority)value;
Color priorityColor = null;

if (priority.equals(Priority.FATAL))
priorityColor = Color.red;
else if (priority.equals(Priority.ERROR))
priorityColor = Color.orange;
else if (priority.equals(Priority.WARN))
priorityColor = Color.yellow;

if (isSelected) {
super.setForeground(table.getSelectionForeground());
if (priorityColor!=null)
super.setBackground(priorityColor.darker());
else
super.setBackground(table.getSelectionBackground());
}
else {
super.setForeground((unselectedForeground != null) ?
unselectedForeground : table.getForeground());
if (priorityColor!=null)
super.setBackground(priorityColor);
else
super.setBackground((unselectedBackground != null) ?
unselectedBackground : table.getBackground());
}

setFont(table.getFont());

if (hasFocus) {
setBorder(
UIManager.getBorder("Table.focusCellHighlightBorder") );
if (table.isCellEditable(row, column)) {
super.setForeground(
UIManager.getColor("Table.focusCellForeground") );
super.setBackground(
UIManager.getColor("Table.focusCellBackground") );
}
} else {
setBorder(noFocusBorder);
}

setValue(value);

return this;
}


public void setForeground(Color c) {
super.setForeground(c);
unselectedForeground = c;
}

public void setBackground(Color c) {
super.setBackground(c);
unselectedBackground = c;
}

}
Grzegorz Dribczak
2004-04-19 09:04:07 UTC
Permalink
dzieki za podpowiedzi. biore sie za czytanie i praktyke.
--
pozdrawiam
drypek
Grzegorz Dribczak
2004-04-19 15:23:15 UTC
Permalink
nie dalem rady.
chyba sie poddaje.
--
drypek
pljosh(at)poczta_neostrada_pl
2004-04-19 16:34:53 UTC
Permalink
Post by Grzegorz Dribczak
nie dalem rady.
chyba sie poddaje.
jak wpiszesz:

mojaTabelka.getCellRenderer(2,3).setBackground(Color.GREEN);

to tlo komorki o wspolrzednych 2,3 nie zmienia koloru? Jakis blad wyskakuje?
Grzegorz Dribczak
2004-04-19 17:15:28 UTC
Permalink
Post by pljosh(at)poczta_neostrada_pl
mojaTabelka.getCellRenderer(2,3).setBackground(Color.GREEN);
to tlo komorki o wspolrzednych 2,3 nie zmienia koloru? Jakis blad wyskakuje?
mojaTabelka.getCellRenderer(2,3); zwraca typ TableCellRenderer

TableCellRenderer nie ma metody setBackground
--
drypek
pljosh(at)poczta_neostrada_pl
2004-04-19 19:22:30 UTC
Permalink
Post by Grzegorz Dribczak
Post by pljosh(at)poczta_neostrada_pl
mojaTabelka.getCellRenderer(2,3).setBackground(Color.GREEN);
to tlo komorki o wspolrzednych 2,3 nie zmienia koloru? Jakis blad wyskakuje?
mojaTabelka.getCellRenderer(2,3); zwraca typ TableCellRenderer
TableCellRenderer nie ma metody setBackground
getCellRenderer(2,3) nie zwraca "typu" tylko OBIEKT.
Skoro w API od Javy pisza, ze standartowo tabela (JTable) uzywa
DefaultTableCellRenderer to znaczy, ze getCellRenderer zwroci wlasnie
taki obiekt. Skoro sie czepie kompilator, ze TableCellRenderer nie ma
metody setBackground to zrob rzutowanie na DefaultTableCellRenderer i
kurde musi dzialac...

sprawdz wiec tak:
((DefaultTableCellRenderer)mojaTabelka.getCellRenderer(2,2)).setBackground(Color.GREEN);

...no bo szkoda, zebys od nowa pisal cala klase tylko dlatego, ze nie
mozesz skorzystac z tego - co juz dla nas chlopaki od JFC przygotowali... :)
Grzegorz Dribczak
2004-04-19 20:08:45 UTC
Permalink
Post by pljosh(at)poczta_neostrada_pl
((DefaultTableCellRenderer)mojaTabelka.getCellRenderer(2,2)).setBackground(Color.GREEN);
sprawdzilem. w ten sposob koloruje cala jtable. dalej nie jest
to dana komorka (docelowo wiersz).
--
drypek
pljosh(at)poczta_neostrada_pl
2004-04-19 21:08:23 UTC
Permalink
Post by Grzegorz Dribczak
Post by pljosh(at)poczta_neostrada_pl
((DefaultTableCellRenderer)mojaTabelka.getCellRenderer(2,2)).setBackground(Color.GREEN);
sprawdzilem. w ten sposob koloruje cala jtable. dalej nie jest
to dana komorka (docelowo wiersz).
Tak sobie mysle, ze moze ten jeden obiekt jest dzielony na wszystkie
komorki - tzn, ze getCellRenderer zwraca zawsze ten sam obiekt, ktory
przywiazany jest do standartowej tabeli...
Trzeba by w takim wypadku cos wykombinowac, zeby
albo jakos wymisic na tabeli uzywanie innego CellRenderera w danych
komorkach
albo jesli sie tak nie da to wprowadzic wlasny Cell renderer (najlepiej
cos w stylu "class MyCellRenderer extends DefaultCellRenderer" i zeby w
nim ustawic ten setBackground() na dany kolor w zaleznosci od
renderowanej wlasnie komorki...
Jak juz pisalem - bede to robil, ale pozniej. Chetnie dowiem sie czegos
w tej sprawie, zebym potem nie musial kombinowac :)
Jak do czegos dojdziesz to daj znac na grupe :)
rDarek
2004-04-19 22:44:13 UTC
Permalink
Post by pljosh(at)poczta_neostrada_pl
Tak sobie mysle, ze moze ten jeden obiekt jest dzielony na wszystkie
komorki - tzn, ze getCellRenderer zwraca zawsze ten sam obiekt, ktory
przywiazany jest do standartowej tabeli...
Trzeba by w takim wypadku cos wykombinowac, zeby
albo jakos wymisic na tabeli uzywanie innego CellRenderera w danych
komorkach
albo jesli sie tak nie da to wprowadzic wlasny Cell renderer (najlepiej
cos w stylu "class MyCellRenderer extends DefaultCellRenderer" i zeby w
nim ustawic ten setBackground() na dany kolor w zaleznosci od
renderowanej wlasnie komorki...
Trochę zaciekawił mnie ten temat. Jeśli chodzi o CellRenderery, to
domyślnie typy takie jak Boolean, Integer i jeszcze trochę używają
innych klas niż DefaultCellRenderer. Stąd realizacja Twego pomysłu
spowoduje, że kolumny z tym typem danych będą wyglądać inaczej.

Lepszym IMO sposobem, byłoby stworzenie klasy dziedziczącej z JTable
i przeciążenie metody prepareRenderer. Napisałem sobie coś takiego:

public Component prepareRenderer(TableCellRenderer renderer,
int row,
int column) {
Component co = super.prepareRenderer(renderer, row, column);

if (row%2 == 0)
co.setBackground(Color.BLUE);
else
co.setBackground(Color.GREEN);

return co;
}
co wygeneruje nam tabelką z kolorowymi wierszami. Oczywiście do pełnego
szczęścia należałoby też w podobny sposób napisać metodę prepareEditor.


D.
--
Jeśli chcesz do mnie napisać to pisz na adres:
drdar (małpa)
acn (kropka) waw (kropka) pl
pljosh(at)poczta_neostrada_pl
2004-04-19 23:27:48 UTC
Permalink
Post by rDarek
Trochę zaciekawił mnie ten temat. Jeśli chodzi o CellRenderery, to
domyślnie typy takie jak Boolean, Integer i jeszcze trochę używają
innych klas niż DefaultCellRenderer. Stąd realizacja Twego pomysłu
spowoduje, że kolumny z tym typem danych będą wyglądać inaczej.
Lepszym IMO sposobem, byłoby stworzenie klasy dziedziczącej z JTable
public Component prepareRenderer(TableCellRenderer renderer,
int row,
int column) {
Component co = super.prepareRenderer(renderer, row, column);
if (row%2 == 0)
co.setBackground(Color.BLUE);
else
co.setBackground(Color.GREEN);
return co;
}
co wygeneruje nam tabelką z kolorowymi wierszami. Oczywiście do pełnego
szczęścia należałoby też w podobny sposób napisać metodę prepareEditor.
Heh - ja tez piszac cos innego akurat mimowolnie wpadlem na cos bardzo
prostego - moze to zadziala, moze nie, ale warto sprobowac.
Otoz, jesli podczas rysowania tabeli (JTable) brany jest pod uwage
sposob renderowania zwracany przez metode:
getCellRenderer(int row, int column)
to moze latwiej by bylo po prostu zastapic ta metode?

//MyTable.java
//zakladam, ze interesuje nas zmiana koloru w wierszu nr 5.
//Podmienic nalezy "costam" na cokolwiek co nas interesuje
//jako parametr konstruktora tabeli.
//Mozna oczywiscie zrobic kilka roznych konstruktorow.

public class MyTable extends JTable {
public MyTable(costam) {
super(costam);
}

getCellRenderer(int row, int column) {
if (row == 5) return MyDefaultTableCellRenderer;
else return DefaultTableCellRenderer;
}
class MyDefaultTableCellRenderer extends DefaultTableCellRenderer {
MyDefaultTableCellRenderer() {
super();
setBackground(Color.GREEN)
}
} //koniec MyDefaultTableCellRenderer.
} //koniec MyTable

Oczywiscie, zamiast na stale kodowac numer wiersza i kolor mozna zrobic
metody publiczne, ktore bedza ustawiac jakies zmienne i do niej bedzie
przyrownywany "if (row == ... ) ..." oraz kolor zamiast GREEN.
Teraz wystarczy, ze zamiast uzywac JTable bedzies uzywal MyTable i po
sprawie... Jesli to dziala to jest to chyba najprostrzy sposob, co myslicie?
pljosh(at)poczta_neostrada_pl
2004-04-20 12:48:27 UTC
Permalink
Post by pljosh(at)poczta_neostrada_pl
//MyTable.java
//zakladam, ze interesuje nas zmiana koloru w wierszu nr 5.
//Podmienic nalezy "costam" na cokolwiek co nas interesuje
//jako parametr konstruktora tabeli.
//Mozna oczywiscie zrobic kilka roznych konstruktorow.
public class MyTable extends JTable {
public MyTable(costam) {
super(costam);
}
getCellRenderer(int row, int column) {
if (row == 5) return MyDefaultTableCellRenderer;
else return DefaultTableCellRenderer;
}
class MyDefaultTableCellRenderer extends DefaultTableCellRenderer {
MyDefaultTableCellRenderer() {
super();
setBackground(Color.GREEN)
}
} //koniec MyDefaultTableCellRenderer.
} //koniec MyTable
Oczywiscie, zamiast na stale kodowac numer wiersza i kolor mozna zrobic
metody publiczne, ktore bedza ustawiac jakies zmienne i do niej bedzie
przyrownywany "if (row == ... ) ..." oraz kolor zamiast GREEN.
Teraz wystarczy, ze zamiast uzywac JTable bedzies uzywal MyTable i po
sprawie... Jesli to dziala to jest to chyba najprostrzy sposob, co myslicie?
Ha - to dziala - dzisiaj sprawdzilem na swojej tabelce! Podmieniajac
odpowiednio warunek getCellRenderer mozna zrobic dowolny "wzor" wg
ktorego komorki moga miec najrozniejsze kolory, czcionki i w ogole...
moza zrobic dowolny wiersz, kolumne, w ogole dowolna kombinacje bardzo
latwo. aha - oczywisty blad sie wdarl do getCellRenderer - najpierw
trzeba stworzyc obiekty a potem je zwracac :)
Post by pljosh(at)poczta_neostrada_pl
getCellRenderer(int row, int column) {
if (row == 5) return MyDefaultTableCellRenderer;
else return DefaultTableCellRenderer;
}
podmienic tylko
MyDefaultTableCellRenderer na myDefaultTableCellRenderer
oraz
DefaultTableCellRenderer na defaultTableCellRenderer
a w konstruktorze dodac:
myDefaultTableCellRenderer = new MyDefaultTableCellRenderer();
defaultTableCellRenderer = new DefaultTableCellRenderer();
i po sprawie :)
Grzegorz Dribczak
2004-04-20 13:55:26 UTC
Permalink
ja zrobilem troche inaczej a u mnie tez dziala :)
zakladam, ze koloruje wiersz nr 3.

class MojRenderer1 extends DefaultTableCellRenderer implements
TableCellRenderer
{

public Component getTableCellRendererComponent (JTable table, Object
value, boolean selected, boolean focused, int row, int column)
{
Component cell = super.getTableCellRendererComponent(table, value,
selected, focused, row, column);

if (row==3)
{
cell.setBackground(Color.lightGray);
cell.setForeground(Color.black);
}
else
{
cell.setBackground(Color.white);
cell.setForeground(Color.black);
}

return cell;
}
}




MojRenderer1 tcr1 = new MojRenderer1();
TableColumn col;
for (int i=0; i<(jTable1.getColumnCount()); i++)
{
col = jTable1.getColumnModel().getColumn(i);
col.setCellRenderer(tcr1);
}
--
pozdrawiam
drypek
rDarek
2004-04-20 18:48:14 UTC
Permalink
Post by Grzegorz Dribczak
class MojRenderer1 extends DefaultTableCellRenderer implements
TableCellRenderer
Uparcie powtórzę, DefaultTableCellRenderer nie jest używany do
wszystkich klas. Dla typów numerycznych, daty, logicznych używany jest
inny renderer. Postawienie DefaultTableCellRenderera w kolumnach z tego
rodzaju danymi spowoduje inne wyświetlanie danych (no, chyba że o to
chodzi).
Do sprawdzenia proponuję wykonanie następującego fragmentu:

JTable table = new JTable();
System.out.println(((Object)table.getDefaultRenderer(Integer.class)).getClass().getName());
System.out.println(((Object)table.getDefaultRenderer(Object.class)).getClass().getName());
System.out.println(((Object)table.getDefaultRenderer(Boolean.class)).getClass().getName());

D.
--
Jeśli chcesz do mnie napisać to pisz na adres:
drdar (małpa)
acn (kropka) waw (kropka) pl
Grzegorz Dribczak
2004-04-19 18:54:28 UTC
Permalink
udalo mi sie zmienic oklor tla w kolumnie. nie wiem teraz jak to zrobic dla
danego wiersza.

stworzylem taka klase:

class MojRenderer1
extends DefaultTableCellRenderer
implements TableCellRenderer
{
public Component getTableCellRendererComponent
(JTable table, Object value, boolean selected, boolean
focused, int row, int column)
{
Component cell = super.getTableCellRendererComponent
(table, value, selected, focused, row, column);

cell.setBackground(Color.red);
// You can also customize the Font and Foreground this way
// cell.setForeground();
// cell.setFont();
return cell;
}
}

a w programi pokolorowanie kolumny wyglada tak:

MojRenderer1 tcr = new MojRenderer1();
TableColumn col = jTable1.getColumnModel().getColumn(1);
col.setCellRenderer(tcr);
jTable1.repaint();


teraz chcialbym korzystajac z mojej klasy pokolorowac wiersz lub
jedna konkretna komorke jtabel.

probowalem:
prepareRenderer(TableCellRenderer renderer, int row, int column)
jTable1.prepareRenderer(tcr, 1, 1);
ale nie bardzo chce to dzialac.

pomozcie prosze
--
drypek
Loading...