According to all the examples I've looked at my code should work. Why isn't it working?
I am able to change the cell color in my table if i specify a row and column but it's not working if I specify a value.
Here is what I have:
//Custom renderer to color table cells red
//cellValue = 00:00:00 - a LocalTime in the table, so all cells with that value should be red.
public class MyTableCellRenderer 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);
if (value == cellValue) {
c.setForeground(Color.red);
} else {
c.setForeground(table.getForeground());
}
return c;
}
}
Please help before I go nuts!
if (value == cellValue)
Don't use "==" to compare objects.
Instead you should be using the equals(...) method:
if (value.equals(cellValue))
Related
So I know this may be a duplicate question, but I've looked through many of the ones already on here and none of them seem to work for me, so I thought I would post my own and hopefully some of the other people having trouble with this will find this helpful also.
Here is my code
table.getColumn("Name").setCellRenderer(
new DefaultTableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setText(value.toString());
if (row==3)
{
setForeground(Color.RED);
}
return this;
}
}
);
Here is what is displayed in the JFrame. As you can see I am trying to to only color the text in the third row of the Column "Name" but it colors the whole row.
Any suggestions?
Thanks!
Canaan
The render is unique for column "Name". You are setting Red as foreground color when row is 3 but you dont reset it for others rows, so when painter is called it always paint red.
You have to set red when row is 3 but you also have to reset the original color in other case.
EDITED: Performed version. Now original foreground color is backed up, and super is used to render like others columns.
table.getColumn("Name").setCellRenderer(
new DefaultTableCellRenderer() {
Color originalColor = null;
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (originalColor == null) {
originalColor = getForeground();
}
if (value == null) {
renderer.setText("");
} else {
renderer.setText(value.toString());
}
if (row == 3) {
renderer.setForeground(Color.RED);
} else {
renderer.setForeground(originalColor); // Retore original color
}
return renderer;
}
});
I am working on a color based database program that shows bookings inside an accommodation based on color. the problem I've been having is that the table has 367 columns (the name of the accommodation and then all days of a year.) the problem I've been having is that I can't figure out how to make the first column of the row display a string and the rest a color.
I made a basic renderer that should display colors but I don't know how to use it.
public class MyRenderer 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);
if (! table.isRowSelected(row))
{
if(row == 2 && column == 2)
c.setBackground(new java.awt.Color(0, 0, 255));
else
c.setBackground(table.getBackground());
}
return c;
}
}
how would I integrate this with a JTable?
PS I have a header I want to show but the rows should be empty to begin with. then when a button is pressed it should add a row. this last button I can make myself I just need help with the cellrenderer
At the moment my JTable is initialized like this: JTable table = new JTable();
Does anybody have any tips?
I suppose there is two state for a day, booked or not. So the value is boolean. You can set renderers by class types. For example:
table.setDefaultRenderer(Boolean.class, new MyRenderer());
With that, your renderer will be uses only if value is a boolean.
public class MyRenderer 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);
if(value)
c.setBackground(/*Color for booked days*/ );
else
c.setBackground(table.getBackground());
return c;
}
}
I try to change the background color of each second row. The problem is that only first COLUMN is affected. Why?
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
{
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
return c;
}
});
Using the renderer approach you need to write a custom renderer for every data type in the table. So if you have String, Data, Integer, Boolean you would need to write 4 custom renderers.
See Table Row Rendering for an approach that will allow you to write the code once no matter haw many data types you have in the table. This approach overrides the preparerrenderer(...) method of the JTable.
As stated in Concepts: Editors and Renderers section of How to Use Tables tutorial, if you din not specify a renderer for a particular column then the table invokes the table model's getColumnClass method to get a default renderer for the column type.
If you have overridden getColumnClass method then your approach might not work as expected. For instance:
DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0) {
#Override
public Class<?> getColumnClass(int columnIndex) {
Class columnClass = Object.class;
switch(columnIndex) {
case 0: columnClass = String.class; break;
case 1: columnClass = Boolean.class; break;
}
return columnClass;
}
};
Then doing this:
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {// your code here});
Won't work for the second column since the getColumnClass method will return Boolean.class and there's a default cell renderer for that class (JCheckBox).
In your case I would suggest you override JTable.prepareRenderer() method instead to set rows background color independently of the renderer type (JLabel, JCheckBox, or even custom renderers):
JTable table = new JTable(model) {
#Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
return c;
}
};
Okay, scrap all of what I just wrote.
Attempt #2:
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
return this;
}
});
You need to be returning the current object, not the reference of the super() call.
I'm trying to change the colour of one or more particular cells in a column in my JTable. The answers I have seen on here all refer to this particular method;
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
Component y = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
y.setBackground(new Color(255,0,0));
return y;
}
But the problem is I do not understand in any way how this works, in my other class I have a Jtable of strings and I want to change the colour of certain cells according to their string value, however the solutions i find only allow me to change the colour of an entire column of cells in the jtable and not a specific one.
I have a Jtable of strings and I want to change the colour of certain cells according to their string value
The same renderer is used for all cells so you need to reset the background every time.
You will need an if condition in your custom renderer code. Something like:
if (!isSelected)
if (value.equals(...))
y.setBackground(new Color(255,0,0));
else
y.setBackground(table.getBackground())
You can use DefaultTableCellRenderer to color alternate row from JTable.
table.setDefaultRenderer(Object.class, new TableCellRenderer(){
private DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer();
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = DEFAULT_RENDERER.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(isSelected){
c.setBackground(Color.YELLOW);
}else{
if (row%2 == 0){
c.setBackground(Color.WHITE);
}
else {
c.setBackground(Color.LIGHT_GRAY);
} }
//Add below code here
return c;
}
});
If you want to color your row using the value of a particular row then you can use something like this. Add these line to above
if(table.getColumnModel().getColumn(column).getIdentifier().equals("Status")){//Here `Status` is column name
if(value.toString().equals("OK")){//Here `OK` is the value of row
c.setBackground(Color.GREEN);
}
}
I have a JTable that is showing some records in a Java Swing application. The user only works with whole rows, not with individual cells. Is there any way I can focus on a whole row of a JTable? The default is to focus only the cell that the user has clicked on. I use a different color for the focus, so it doesn't look good if only a cell is focused instead of the whole row.
UPDATE: This is my current code of my custom TableCellRenderer, the issue is that when a row has focus and is painted with the "focus" color, and then the JTable loses focus, only the cell that had focus is repainted with the "selected" color but all cells in the selected row should be repainted with the "selected" color.
#Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
// Has any cell in this row focus?
if(table.getSelectedRow() == row && table.hasFocus()) {
hasFocus = true;
}
if (hasFocus) {
this.setBackground(CustomColors.focusedColor);
} else if (isSelected) {
this.setBackground(CustomColors.selectedColor);
} else {
// alternate the color of every second row
if(row % 2 == 0) {
this.setBackground(Color.WHITE);
} else {
this.setBackground(CustomColors.grayBg);
}
}
setValue(value);
return this;
}
Sounds like you're looking for the setRowSelectionAllowed() method.
Since you said just changing the color would be sufficient, you might want to look at the custom cell renderer section of the Swing Tutorial. You'd just have to set the logic to check on whether a given cell was in a selected row, and paint the background color accordingly.
A first idea would be something like
JTable jTable = new JTable() {
public TableCellRenderer getCellRenderer(int row, int column) {
final TableCellRenderer superRenderer = super.getCellRenderer(row, column);
return new TableCellRenderer() {
#Override
public Component getTableCellRendererComponent(JTable table, Object object, boolean isSelected, boolean hasFocus, int row, int column) {
// determine focus on row attribute only
hasFocus = hasFocus() && isEnabled() && getSelectionModel().getLeadSelectionIndex() == row;
return superRenderer.getTableCellRendererComponent(table, object, isSelected, hasFocus, row, column);
}
};
}
};
where I use my own logic to determine the focus based on the row attribute only. It uses the underlying cell renderers but looks strange if focus border is used.