Jtable Row Hightlighter Based on Value from Tablecell

JTable row hightlighter based on value from TableCell

how to set Alignment for TableCell into prepareRenderer,

This should NOT be done in the prepareRenderer code. This property should be set in the renderer for the class or for the column because it only applies to a specific class or renderer. Instead use:

table.setPreferredScrollableViewportSize(table.getPreferredSize());
DefaultTableCellRenderer stringRenderer = (DefaultTableCellRenderer)table.getDefaultRenderer(String.class);
stringRenderer.setHorizontalAlignment( SwingConstants.CENTER );

For the highlighting code I used code that assumes that the dealld value is unique for a given set of transactions:

        private Map<Object, Color> rowColor = new HashMap<Object, Color>();
private Color nextColor = Color.ORANGE;

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent) c;

if (isRowSelected(row)) return c;

Object value = table.getValueAt(row, 7);
Color background = rowColor.get(value);

if (background != null)
{
c.setBackground( background );
}
else
{
rowColor.put(value, nextColor);
c.setBackground( nextColor );
nextColor = (nextColor == Color.ORANGE) ? Color.YELLOW : Color.ORANGE;
}

return c;
}

Note: It won't work if sorting is required.

Here is another approach that should work even if sorting is required (but I didn't test it with sorting);

        @Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent) c;
if (!isRowSelected(row))
{
c.setBackground(getRowBackground(row));
}

return c;
}

private Color getRowBackground(int row)
{
boolean isDark = true;

Object previous = getValueAt(0, 7);

for (int i = 1; i <= row; i++)
{
Object current = getValueAt(i, 7);

if (! current.equals(previous))
{
isDark = !isDark;
previous = current;
}
}

return isDark ? Color.ORANGE : Color.YELLOW;
}

Highlighting specific rows in a JTable

The renderers are "rubber stamps". That basically means that they carry there previous settings over to the next cell.

What you need to do is provide a "default" behavior

if (!isRowSelected(row) ) {
c.setBackground((hashMapcontainer
.containsKey(row)) ? Color.GREEN
: getBackground());
} else {

// Define the default background color
// Don't forget to take into the selection state

}

While I personally think that prepareRenderer in this case is probably a fair solution, you really should explore the possibly of providing a base line renderer. This is a lot of work to get right but has the advantage of been portable (if you change table implementations) as well as allowing other
people the chance to define the highlight rules of a given cell, which you've basically just gone and overridden, IMHO.

I'd also suggest taking a look at JXTable as it has in built highlighting

JTable row color depending on Value in model?

Since you want to color an entire row, its easier to use Table Row Rendering than it is to create muuliple custom renderers.

I've found examples that recolor rows depending on values in JTable. But getIsValid and getIsRegistered() aren't actually displayed, they exist only in model

You can still access the model from the table. You just use:

table.getModel().getValueAt(...);

Change Color of JTable Row Based on the Value of the Database

Overriding the prepareRender(...) method of the JTable allows your to customize rendering for the entire row based on a value in one of the columns.

The basic logic would be something like:

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

// Color row based on a cell value

if (!isRowSelected(row))
{
c.setBackground(getBackground()); // set default background

int modelRow = convertRowIndexToModel(row);
String value = (String)getModel().getValueAt(modelRow, ???);

if ("Single".equals(value)) c.setBackground(Color.GREEN);
}

return c;
}

Check out Table Row Rendering for more information and working examples.

Change background color of JTable whole row based on column value

The problem with your approach is that you use getTableCellRendererComponent so only that cell will have its color changed.

I had to make something similar. Based on the value of a column, I had to color the row.

I used a class that extended the JTable and Override prepareRenderer

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component comp = super.prepareRenderer(renderer, row, column);
if (populated) { //this if was just to make sure that I have data in my table
/*
*This piece makes the code ignore the rows that are selected as this approach messes up that blue color that selected rows get
*/
int[] rows = this.getSelectedRows();
boolean rowisSelected = false;

for (int rowIndex : rows) {
if (row == rowIndex) {
rowisSelected = true;
break;
}
}
/*
*And this is the part that does the coloring
*/
if (!rowisSelected) {
Integer status = Integer.parseInt((String)
int modelRow = convertRowIndexToModel(row);
this.getModel().getValueAt(modelRow, Constants.HIDDEN_COLUMN));
switch (status) {
case 1:
comp.setForeground(Color.BLACK);
comp.setBackground(Color.WHITE);
break;
case 2:
comp.setForeground(Color.LIGHT_GRAY);
comp.setBackground(Color.WHITE);
break;
case 3:
comp.setForeground(Color.BLACK);
comp.setBackground(Constants.DOWNLOADED_COLOR);
break;
case 4:
comp.setForeground(Color.LIGHT_GRAY);
comp.setBackground(Constants.DOWNLOADED_COLOR);
break;
}
}
}
return comp;
}

Yours should be something like this (without the selected row thing):

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component comp = super.prepareRenderer(renderer, row, column);
int modelRow = convertRowIndexToModel(row);
String second = this.getModel().getValueAt(modelRow, 1));
String forth= this.getModel().getValueAt(modelRow, 3));
if(second.equals(forth)){
comp.setBackground(Color.GREEN);
}
return comp;
}

How do I color individual cells of a JTable based on the value in the cell?

There is a relationship between the data/model and the view/table. The model maintains the "what", the view controls the "how".

JTable provides a means by which you can the behaviour of the "how" (stuff gets rendered) through the use of TableCellRenderers, these are responsible for determining how a cell should be "painted" based on the value from the "what" from the model.

Start by having a look at How to Use Tables and Using Custom Renderers

Now, this example uses a double value to determine the distance from 1 the cell value is, which represents the color (black = 0; white = 1) that the cell should be painted. To accomplish this, it uses a custom TableCellRenderer which converts the value in the model (the "what") into a color (or the "how")

public class PaintTableCellRenderer extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);
if (value instanceof Double) {
double distance = (double) value;
int part = (int) (255 * distance);
Color color = new Color(part, part, part);
setBackground(color);
} else {
setBackground(Color.WHITE);
}
return this;
}

}

Smile

It also demonstrates a couple of other things you might need to know about the JTable as well.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.Enumeration;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

public class Smile {

public static void main(String[] args) {
new Smile();
}

public Smile() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private double[][] smily = {
{1, 1, 1, 1, 1, 0.996, 1, 0.843, 0.784, 0.788, 0.773, 0.769, 0.765, 0.765, 0.788, 0.784, 0.847, 1, 0.996, 1, 1, 1, 1, 0.996},
{1, 1, 1, 1, 1, 0.871, 0.733, 0.761, 0.847, 0.941, 0.941, 0.941, 0.941, 0.941, 0.933, 0.843, 0.761, 0.733, 0.871, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0.784, 0.733, 0.902, 0.941, 0.941, 0.941, 0.945, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.898, 0.733, 0.784, 1, 1, 1, 1},
{1, 1, 1, 0.765, 0.773, 0.945, 0.945, 0.941, 0.929, 0.937, 0.941, 0.941, 0.945, 0.941, 0.957, 0.91, 0.941, 0.941, 0.941, 0.78, 0.761, 1, 1, 1},
{1, 1, 0.808, 0.773, 0.941, 0.941, 0.941, 0.941, 0.294, 0.447, 0.941, 0.941, 0.941, 0.941, 0.702, 0.239, 0.886, 0.941, 0.945, 0.941, 0.78, 0.8, 1, 1},
{1, 0.89, 0.725, 0.945, 0.941, 0.941, 0.945, 0.843, 0, 0, 0.922, 0.945, 0.941, 0.941, 0.408, 0, 0.663, 0.941, 0.941, 0.945, 0.941, 0.725, 0.89, 1},
{0.992, 0.753, 0.902, 0.941, 0.945, 0.945, 0.941, 0.725, 0.051, 0, 0.808, 0.941, 0.941, 0.945, 0.294, 0.051, 0.553, 0.941, 0.941, 0.941, 0.941, 0.91, 0.741, 0.984},
{0.871, 0.78, 0.941, 0.941, 0.945, 0.945, 0.941, 0.694, 0.051, 0, 0.784, 0.945, 0.941, 0.941, 0.278, 0, 0.518, 0.941, 0.941, 0.945, 0.941, 0.941, 0.78, 0.878},
{0.816, 0.855, 0.941, 0.945, 0.945, 0.945, 0.941, 0.737, 0, 0.051, 0.82, 0.941, 0.941, 0.941, 0.302, 0.051, 0.565, 0.941, 0.949, 0.945, 0.941, 0.941, 0.863, 0.804},
{0.8, 0.945, 0.941, 0.945, 0.945, 0.941, 0.941, 0.875, 0, 0, 0.937, 0.941, 0.941, 0.941, 0.443, 0, 0.694, 0.945, 0.945, 0.945, 0.945, 0.949, 0.941, 0.765},
{0.769, 0.941, 0.945, 0.957, 0.961, 0.941, 0.945, 0.941, 0.443, 0.565, 0.945, 0.941, 0.941, 0.941, 0.769, 0.388, 0.918, 0.941, 0.941, 0.941, 0.945, 0.941, 0.941, 0.78},
{0.753, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.953, 0.941, 0.941, 0.941, 0.941, 0.945, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.788},
{0.741, 0.945, 0.839, 0.427, 0.624, 0.941, 0.941, 0.945, 0.941, 0.941, 0.941, 0.949, 0.945, 0.945, 0.941, 0.941, 0.941, 0.941, 0.941, 0.6, 0.376, 0.941, 0.945, 0.784},
{0.749, 0.941, 0.914, 0.345, 0.647, 0.941, 0.945, 0.949, 0.945, 0.945, 0.941, 0.941, 0.945, 0.941, 0.945, 0.945, 0.945, 0.945, 0.941, 0.702, 0.384, 0.941, 0.941, 0.78},
{0.796, 0.945, 0.941, 0.627, 0.592, 0.941, 0.941, 0.941, 0.945, 0.945, 0.945, 0.941, 0.949, 0.945, 0.941, 0.945, 0.945, 0.937, 0.945, 0.58, 0.631, 0.941, 0.937, 0.776},
{0.812, 0.859, 0.941, 0.855, 0.384, 0.957, 0.941, 0.945, 0.945, 0.945, 0.941, 0.953, 0.941, 0.945, 0.945, 0.945, 0.941, 0.941, 0.941, 0.384, 0.941, 0.941, 0.867, 0.812},
{0.871, 0.788, 0.941, 0.941, 0.533, 0.51, 0.941, 0.941, 0.941, 0.945, 0.949, 0.945, 0.945, 0.945, 0.941, 0.937, 0.941, 0.945, 0.522, 0.522, 0.941, 0.941, 0.792, 0.886},
{0.992, 0.761, 0.914, 0.941, 0.941, 0.325, 0.612, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.624, 0.318, 0.941, 0.945, 0.91, 0.765, 0.988},
{1, 0.882, 0.741, 0.941, 0.941, 0.922, 0.337, 0.475, 0.894, 0.941, 0.941, 0.941, 0.941, 0.941, 0.945, 0.894, 0.49, 0.325, 0.925, 0.941, 0.941, 0.753, 0.894, 1},
{1, 1, 0.796, 0.78, 0.941, 0.941, 0.941, 0.592, 0.447, 0.565, 0.667, 0.737, 0.737, 0.667, 0.565, 0.451, 0.588, 0.941, 0.941, 0.941, 0.796, 0.808, 1, 1},
{1, 1, 0.996, 0.753, 0.788, 0.941, 0.941, 0.941, 0.941, 0.702, 0.584, 0.557, 0.553, 0.592, 0.698, 0.906, 0.941, 0.945, 0.941, 0.796, 0.769, 0.996, 1, 1},
{1, 1, 1, 1, 0.769, 0.745, 0.922, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.918, 0.741, 0.776, 1, 1, 0.996, 1},
{1, 0.996, 1, 1, 1, 0.851, 0.733, 0.773, 0.867, 0.945, 0.941, 0.941, 0.941, 0.941, 0.945, 0.867, 0.769, 0.725, 0.851, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0.984, 0.843, 0.78, 0.761, 0.78, 0.796, 0.796, 0.784, 0.765, 0.78, 0.835, 0.984, 1, 1, 1, 1, 1, 1}
};

public TestPane() {
AsciiTableModel model = new AsciiTableModel();
model.setData(smily);

JTable table = new JTable(model);
table.setRowHeight(24);
Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn col = columns.nextElement();
col.setWidth(24);
col.setPreferredWidth(24);
col.setMinWidth(24);
col.setMaxWidth(24);
}
table.setRowHeight(24);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setDefaultRenderer(Object.class, new PaintTableCellRenderer());

setLayout(new BorderLayout());
add(new JScrollPane(table));
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

}

public class PaintTableCellRenderer extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);
if (value instanceof Double) {
double distance = (double) value;
int part = (int) (255 * distance);
Color color = new Color(part, part, part);
setBackground(color);
} else {
setBackground(Color.WHITE);
}
return this;
}

}

public class AsciiTableModel extends AbstractTableModel {

private double[][] data;

public AsciiTableModel() {
data = new double[24][24];
}

public void setData(double[][] value) {
data = value;
fireTableDataChanged();
}

@Override
public int getRowCount() {
return 24;
}

@Override
public int getColumnCount() {
return 24;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}

}

}

I had intended to provide a "sad" face which you could switch between, but my daughter wanted me to go paint with her, sorry ;)

Highlighting row selection in JTable with custom rendering

Don't create another JLabel in the TableCellEditor, DefaultTableCellEditor extends from JLabel already, you just to apply the settings you need, leave the DefaultTableCellRenderer to take care of the rest

Selected

public class LabelRenderer extends DefaultTableCellRenderer {

public static final Border focusedCellBorder = UIManager.getBorder("Table.focusCellHighlightBorder");

public static final Border unfocusedCellBorder = createEmptyBorder();

private static Border createEmptyBorder() {
Insets i = focusedCellBorder.getBorderInsets(new JLabel());
return BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);
}

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

String text = value.toString();

try {
setIcon(new ImageIcon(getClass().getResource("ok_16px.png")));
// This below code setting the border to be highlighted, but not whole

} catch (Exception ex) {
System.out.println(ex);
}
setBorder(hasFocus ? focusedCellBorder : unfocusedCellBorder);

return this;
}
}

Also, note, that with cellSelection enabled, you will need to click a cell in the second column to see the highlighting. Turn it off to allow for full row selection

How to color specific rows in a JTable

you could use my answer to change the color of the cell. the same technique could be used to apply it to each cell in the row.

This is also example with prepareRenderer

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;

public class TableWithPrepareRendererExample extends JFrame {
ColorName colors[] = { new ColorName("Red"), new ColorName("Green"), new ColorName("Blue"),
new ColorName("Black"), new ColorName("White") };

public TableWithPrepareRendererExample() {
super("Table With prepareRenderer Example");
setSize(500, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);

JTable table = new JTable(new AbstractTableModel() {
ColorName data[] = { colors[0], colors[1], colors[2], colors[3], colors[4], colors[0],
colors[1], colors[2], colors[3], colors[4] };

public int getColumnCount() {
return 3;
}

public int getRowCount() {
return 10;
}

public Object getValueAt(int r, int c) {
switch (c) {
case 0:
return (r + 1) + ".";
case 1:
return "Some pithy quote #" + r;
case 2:
return data[r];
}
return "Bad Column";
}

public Class getColumnClass(int c) {
if (c == 2)
return ColorName.class;
return String.class;
}

public boolean isCellEditable(int r, int c) {
return c == 2;
}

public void setValueAt(Object value, int r, int c) {
data[r] = (ColorName) value;
}

}) {
public Component prepareRenderer(TableCellRenderer renderer,
int rowIndex, int vColIndex) {
Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
Object value = getValueAt(rowIndex, vColIndex);
if (value.toString().equals("Red"))
c.setBackground(Color.RED);
else {
if (rowIndex % 2 == 0 && !isCellSelected(rowIndex, vColIndex)) {
c.setBackground(Color.YELLOW);
} else {
// If not shaded, match the table's background
c.setBackground(getBackground());
}
}
return c;
}
};

JComboBox combo = new JComboBox(colors);
table.setDefaultEditor(ColorName.class, new DefaultCellEditor(combo));
table.setRowHeight(20);
getContentPane().add(new JScrollPane(table));
}

public static void main(String args[]) {
TableWithPrepareRendererExample ex = new TableWithPrepareRendererExample();
ex.setVisible(true);
}

public class ColorName {
String cname;

public ColorName(String name) {
cname = name;
}

public String toString() {
return cname;
}
}

}


Related Topics



Leave a reply



Submit