JTable alignment of cell content in custom Renderer - java

I want to align the contents of the first column of my JTable to the center, but I can't get it to work. I got it to work if I set it without a custom Renderer but then it would overwrite the changes I'm trying to make for the row colors.
Eclipse tells me that the method setHorizontalAlignment is undefined for the type Component but that doesn't ring any bells with me. Any ideas what I'm missing?
final TableCellRenderer renderer = table_1.getDefaultRenderer(Object.class);
table_1.setDefaultRenderer(Object.class, new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
Component c = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
c.setBackground(row % 4 == 2 || row % 4 == 3 ? new Color(230,230,230) : Color.WHITE);
c.setHorizontalAlignment(JLabel.CENTER);
return c;
}
});

Declare and cast the variable c to JLabel:
JLabel c = (JLabel) renderer.getTableCellRendererComponent(...);
The API for DefaultTableCellRenderer will show you that this class in fact derives from JLabel which has the method that you're interested in.

Related

Trying to color specific cell in JTable... getTableCellRendererComponent Overide

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;
}
});

need to split the particular cell in to two JTextField in Swing Java

i am having one Jtable and assign rendered for column.
Now i want to split particular cell into two parts so that i can provide two value in to it.
Splitting can be through Cellrenderer or may be anything else.
Use JPanel with GridLayout as the cell renderer:
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus,int row,int col) {
if (isSplitted(value) {
JPanel panel = new JPanel(new GridLayout(1,2));
JLabel left = new JLabel(getLeft(value));
JLabel right = new JLabel(getRight(value));
panel.add(left);
panel.add(right);
return panel;
} else {
return super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, col)
}
}
Here getLeft, getRight and isSplitted are up to you to define for the value you render in that cell.
If makes sense, you can also optimize retaining an instance of this panel with the two labels; it is possible to reuse it on every call upon setting the required content. For the case when left and rights components are very different in size, BorderLayout may work better.
Similarly, you can provide the cell editor, just you need JTextField or the like as JLabel is not editable. Derive from AbstractCellEditor, overriding getCellEditorValue (return the value composed from the panel) and getTableCellEditorComponent (return the panel itself after setting the fields to the current value).
#Stifler has commented on my answer:
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);
JPanel panel = new JPanel(new GridLayout(1, 2));
if ("History".equals(obj)) {
JTextField left = new JTextField("Left");
left.setEditable(true);
JTextField right = new JTextField("Right");
left.setEditable(true);
panel.add(left);
panel.add(right);
return panel;
}
return cell;
}

Hiding an individual cell in JTable depending on model value

I have a JTable showing values from a model allowing integer values 0, 1 and 2. The values are shown in a 9 by 9 grid (like a sudoku game board).
My question is: How do I hide the zero values from the GUI?
That is, in the table cells that has a model value of zero, I dont want the GUI to show any value. The model must however contain the zero value due to calculations being done.
I have tried to use a DefaultTableCellRenderer and setting the cell component to invisible by using setVisible(true) (as in this question), but I get no result.
I have managed to use a DefaultTableCellRenderer to toggle any cell's background color depending on the model state (if a cell is considered "negative"). I do want to keep the background color visible.
I am a bit new to java, so maybe this is just an update issue?
Here is my DefaultTableCellRenderer:
private static class GameTableRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
#Override
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);
GameModel model = (GameModel) table.getModel();
if(model.isNegative(row, column))
c.setBackground(Color.lightGray);
else
c.setBackground(Color.white);
if(model.getAbsoluteValueAt(row, column) == 0)
c.setVisible(false);
else
c.setVisible(true);
return c;
}
}
The "getAbsoluteValueAt" method returns an integer 0, 1 or 2. The change of background color works perfectly fine.
My model extends AbstractTableModel, and the JTable uses the renderer like this:
table.setDefaultRenderer(int.class, renderer);
I hope this information is enough to explain my problem and the efforts I so far have put in. Please ask for more information and I will provide it.
Thank you in advance. /Fredrik
Or you can use the following:
if(model.getAbsoluteValueAt(row, column) == 0)
c.setForeground(c.getBackground());
else
c.setForeground(Color.BLACK);
Instead of making the component invisible, set its text to the empty string:
if (model.getAbsoluteValueAt(row, column) == 0) {
((JLabel) c).setText("");
}

JTable trouble changing colors for first column

i try to change the color of fields in a JTable according to their value. I don't want to change any color of the first column but it changes anyway in a buggy way(some fileds are not correctly filed like University and Possible_Reviewer):
My code is as following:
table.setDefaultRenderer(Object.class, new CustomRenderer());
private class CustomRenderer extends DefaultTableCellRenderer {
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);
try {
Double val = Double.parseDouble(value.toString());
if(col == 0){
comp.setBackground(Color.white);
} else {
comp.setBackground(changeColor(val));
}
} catch (NumberFormatException e){}
return( comp );
}
private Color changeColor(Double val) {
//returns a Color between red and green depending on val
}
}
The weird thing is that when i use "col == 2" it turns the second column white but the first remains strangely colored.
Anyone an idea?
You should extend JTable class and override this method:
public TableCellRenderer getCellRenderer(int row, int column){}
Otherwise JTable will use the same renderer for each cell in the same column.
EDIT:
Like #Mark Bramnik pointed out, it's better to not instantiate a new TableCellRenderer object for every getCellRenderer call. You could implement a method like the following:
setCellRenderer(int row, int col, TableCellRenderer render)
and store the renderer in the extended JTable itself.
How to Use Tables: Using Custom Renderers mentions this alternative approach: "To specify that cells in a particular column should use a renderer, you use the TableColumn method setCellRenderer()."
Addendum: A benefit of this approach is that the renderer "sticks" to the column if the user drags it to a different position. In this example, replace setDefaultRenderer() with setCellRenderer().
table.getColumnModel().getColumn(DATE_COL).setCellRenderer(new DateRenderer());

JTable renderer with sorting

I am trying to sort a table using rowsorter.
RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
cTable.setRowSorter(sorter);
I am using a renderer which extends DefaultTableCellRenderer. I am using the renderer to paint the contents of the cell in some color based on its value.
cTable.setDefaultRenderer(Object.class,new <renderer name>());
eg:
public Component getTableCellRendererComponent(JTable table, Object v,
boolean isSelected, boolean hasFocus, int row, int column)
{
super.getTableCellRendererComponent(table, v, isSelected, hasFocus,
row, column);
int k=table.getValueAt(row,column);
if (k >= 0) this.setForeground(Color.red);
}
Note:This is just a sample code.No real functionality.
when i sort, sorting happens perfectly but the renderer functionality of changing the color is not happening. Has anyone faced this issue earlier?Please help
You need to extend the logic in your renderer to:
if (isSelected) {
this.setForeground(table.getSelectionForeground());
} else if (k >= 0) {
this.setForeground(Color.red);
} else {
this.setForeground(table.getForegroundColor());
}
You may also wish to set the background colour depending on each condition. The reason for doing this is because the DefaultTableCellRenderer acts like a "rubber stamp" which is applied to each cell in turn. If for example, the cell at row 5, column 1 has a value of k >= 0 then you are switching the foreground colour to red for this cell and all subsequent cells. Therefore, it is important to explicitly set it back to the "normal" foreground colour if your check fails.

Categories

Resources