Szeretném megváltoztatni egy JTable objektum egy cellájának háttérszínét.
A neten van ezerrel példa, arra, hogy az egész oszlopnak hogyan változtassam meg.
De egyetlen cellának nem bírok rájönni hogyan.
E az egész tábláét változtatja:
tabla.setBackground(Color.blue);
Ez az egész oszlopét változtatja:
tabla.getColumnModel().getColumn(0).setCellRenderer(new BlackTableCellRenderer());
Nekem csak egyetlen cella színét kellene változtatnom.
Csinált már valaki ilyet?
- 8541 megtekintés
Hozzászólások
A link alapján csináltam ezt a szösszenetet:
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.Component;
import java.awt.Color;
class Program01 extends JFrame
{
private JTable tabla;
public Program01()
{
setLayout(null);
tabla = new JTable(9, 9);
tabla.setBounds(100, 100, 300, 200);
int columnWidht = 20;
int rowHeight = 25;
for(int i=0; i<9; i++)
tabla.getColumnModel().getColumn(i).setPreferredWidth(columnWidht);
for(int i=0; i<9; i++)
tabla.setRowHeight(i, rowHeight);
tabla.setDefaultRenderer(String.class, new DefaultTableCellRenderer()
{
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
Component component = super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
if (row == 3 && column == 3)
component.setBackground(isSelected ? Color.blue : Color.black);
return component;
}
});
add(tabla);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setVisible(true);
}
public static void main(String args[])
{
new Program01();
}
}
Persze eredetileg ez a sor:
Component component = super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
getTableCellRendererComponent() nélkül van:
Component component = super(table, value, isSelected, hasFocus, row, column);
Akkor viszont azt mondja a fordító, hogy a super()-t a konstruktor elején kell meghívni.
Nyilván nem értek valamit.
Csak szeretnék egy-egy kockát feketére festeni. De mindez úgy hogy bármikor
megváltoztatható legyen futás közben is, ezzel a módszerrel. Nem megy.
:(
A linket azért köszönöm!
- A hozzászóláshoz be kell jelentkezni
tabla.setDefaultRenderer(String.class,... => tabla.setDefaultRenderer(Object.class, ...
vagy pakolj a tábla modellbe String-et.
- A hozzászóláshoz be kell jelentkezni
Esetleg próbáld így, de a legjobb ha megnézed az apidoc-ot hogy miért lesz ez így most jó
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (row == 3 && column == 3) {
component.setBackground(Color.BLUE);
} else {
component.setBackground(Color.BLACK);
}
return component;
}
});
Ebben is van okosság
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
- A hozzászóláshoz be kell jelentkezni
Megoldva:
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.Component;
import java.awt.Color;
import javax.swing.table.DefaultTableModel;
class Program01 extends JFrame
{
private JTable tabla;
public Program01()
{
setLayout(null);
tabla = new JTable(9, 9);
tabla.setBounds(100, 100, 300, 200);
int columnWidht = 20;
int rowHeight = 25;
for(int i=0; i<9; i++)
tabla.getColumnModel().getColumn(i).setPreferredWidth(columnWidht);
for(int i=0; i<9; i++)
tabla.setRowHeight(i, rowHeight);
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(5,2));
add(tabla);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setVisible(true);
}
public static void main(String args[])
{
new Program01();
}
public class BlackTableCellRenderer extends DefaultTableCellRenderer
{
private int x, y;
public BlackTableCellRenderer(int y_, int x_)
{
x = x_;
y = y_;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column)
{
Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
if(isSelected == false)
if(row == x && column == y)
cell.setBackground(Color.black);
else
cell.setBackground(Color.white);
return cell;
}
}
}
Köszönöm a hozzászólásokat, a segítséget! Amit írtatok azok alapján ez született.
- A hozzászóláshoz be kell jelentkezni
Revidiálnám ezt sikert. Valóban a topic megnyitásakor megfogalmazott példa működik. Néhány napja elkezdtem volna alkalmazni, mire kiderült, hogy nem jó, mert ezzel a módszerrel csak egyetlen cella lehet mindig fekete. Ha újabb cellát adok meg, akkor az előző fehér lesz. Ez meg nem jó így.
Kiadva az alábbi két utasítást:
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(2,2));
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(4,4));
a 2,2 cella valóban fekete lesz, de az utána következő utasítás után már csak a 4,4 cella.
A gond persze ebben metódusban van:
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column)
{
Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
if(!isSelected)
if(row == x && column == y)
cell.setBackground(Color.black);
else
cell.setBackground(Color.white);
return cell;
}
Component cell kezdetű sor után kellene jó feltételeket írni. Logikusan adódna a
if( row == x && column == y)
cell.setBackground(Color.black)
Ez viszont nem jó mert a metódus az összes cellát beállítja x, y értéktől feketére.
Van persze olyan megoldás is, hogy JLabel-eket teszek tartalomnak, és működik is. Most jön a de. Viszont akkor a táblázat nem szereti ha szöveget írok bele.
Keresztrejtvény generálás lenne a végcél, így ez nem jó. A fekete kockák mellett írni is kellene egy-egy karaktert a cellákban.
Gondoltam már arra is, hogy megrajzoltatom a fekete kockákat, hiszen tudok rajzolni a táblázatra. Ennyi erővel az már készen is lenne. De jobb lenne ha ez a fenti dolog működne és nem ilyen workround" típusú megoldást kellene használnom.
flame on
Már vagy három napja esténként ezzel szívok. Nem bírok egy jó feltétel összehozni. Egyszer ezt megoldottam már C# nyelven. Monoval is megy. De szerettem volna C#-tól valamilyen eltérő nyelvben. Jó lett volna még nekem a wxWidget bármilyen nyelven is, de ott meg nem lehet a táblázatra rajzoltatni. Néztem FreePascal (Lazarus), itt kevesebb az ismeretem, de a rövid vele töltött idő után sem tudtam színezni egy cella hátterét. Nincs a C# nyelven kívül egy nyelv, egy környezet amiben meg tudom oldani? Szerettem volna platformfüggetlenül. Azért is Java, wxWidgets, Lazarus, stb. A monora (C#) nem szeretnék visszatérni.
flam off
Gondoltam írok még ide, hátha van valakinek jó ötlete, mielőtt a táblázat felé rajzoltatom a fekete cellákat. Ötlet?
- A hozzászóláshoz be kell jelentkezni
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(2,2));
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(4,4));
a 2,2 cella valóban fekete lesz, de az utána következő utasítás után már csak a 4,4 cella.
Vajon miért? :D elárulom: mert az Object.class-hoz beállítod a default renderert :) és nyilvánvaló a 4,4 felülírja a 2,2 változatot....
A megoldás 1 azaz egy db setDefaultRenderer hívás lesz, de 1 db koordi helyett sokkal, így:
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(feketeCellákKoordinátái));
a getTableCellRendererComponent(...) -ben pedig a feketeCellákKoordinátái lista alapján állítgatod a hátteret.
good luck...
- A hozzászóláshoz be kell jelentkezni
Igaz, ez talán kevesebb munkával jár. Ennek neki is ugrottam, íme:
....
List<CoorHash> m = new Vector<CoorHash>();
m.add(setCell(2,2));
m.add(setCell(4,4));
tabla.setDefaultRenderer(Object.class, new BlackTableCellRenderer(m));
...
Létrehoztam a setCell() eljárást és a CoorHas osztályt, majd javítottam a BlackTableCellRenderer() osztályt:
CoorHash setCell(int x, int y)
{
CoorHash m = new CoorHash();
m.x = x;
m.y = y;
return m;
}
class CoorHash
{
int x;
int y;
}
public class BlackTableCellRenderer extends DefaultTableCellRenderer
{
private List<CoorHash> m;
public BlackTableCellRenderer(List<CoorHash> m_)
{
m = m_;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int col)
{
Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, col);
int n = m.size();
int i = 0;
while(i<n && !(m.get(i).x == row && m.get(i).y ==col))
i++;
boolean van = false;
if(!isSelected)
if(i<n)
cell.setBackground(Color.black);
else
cell.setBackground(Color.white);
return cell;
}
}
Most vagy kellene egy lehetőség (amivel megint gondban vagyok), amellyel lekérdezem a cellák aktuális színét, vagy külön nyilvántartást vezetek róluk. Mondjuk ezt az utóbbit szintén kerülni szerettem volna. De azt hiszem marad akkor a külön nyilvántartás.
Krumplicska számára is köszönöm a választ!
- A hozzászóláshoz be kell jelentkezni
Lehet neked ez kell igazából és nem a table.setDefaultRenderer(class,renderer):
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#ed…
To specify a cell-specific renderer, you need to define a JTable subclass that overrides the getCellRenderer method. For example, the following code makes the first cell in the first column of the table use a custom renderer:
TableCellRenderer weirdRenderer = new WeirdRenderer();
table = new JTable(...) {
public TableCellRenderer getCellRenderer(int row, int column) {
if ((row == 0) && (column == 0)) {
return weirdRenderer;
}
// else...
return super.getCellRenderer(row, column);
}
};
A rendererben még lehet instanceof-al vizsgálgatni a cella típusát és aszerint változtatni a színt, bár nekem az kicsit büdös most :D
Csináltam egy példát itt találod:
http://pastebin.com/tTksQ9eJ
good luck
update:
Na most már biztos vagyok benne, hogy a JTable.getCellRenderer(x,y)-ot kell felülírnod és simán a koordi vagy a modellből a cella típusától függően más-más cellrenderert kell visszaadnod, így a rendererek is egyszerűek maradnak, mert nem kell beléjük semmi cella típus vizsgálgatás, csak simán háttérszín beállítás.
- A hozzászóláshoz be kell jelentkezni
Komplett példa! Köszönöm!
(Közben el kellett mennem itthonról, sőt most két nap jön. De kedden mindenképpen folytatom.)
- A hozzászóláshoz be kell jelentkezni
[Feliratkozás]
- A hozzászóláshoz be kell jelentkezni