I've already read a lot about CellRendering in Java and I have also visited other Q&As from this great site. Unfortunately I still haven't found the solution for the following Problem:
I want to render a JTable which displays StatusEvents - this is necessary for monitoring a running System. However, those StatusEvents consist of a timestamp, a text and a color.
My goal is it to enable multiple colored rows. To achieve this, I've already defined a new JTable-subclass (Overloading "getCellRenderer related to the Row which is being painted during the inseration process) and a new TableCellRenderer-Subclass, which applies the Color to the Cell.
the Methods look like the following:
MyCustomJTable:
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
TableCellRenderer result = super.getCellRenderer(row, column);
if ( row == 0 )
{
result = colcr;
}
return result;
}
colcr is my custom CellRenderer which is coloring a Cell in a specific color which is being set before.
The new Cell Renderer looks like the following:
public class ColorCellRenderer extends DefaultTableCellRenderer {
ColorCellRenderer ( )
{
this.m_Color = null;
}
@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);
if ( m_Color != null )
{
if ( row == 0 && column == 0)
{
c.setForeground(m_Color);
}
}
return c;
}
public void setColor ( Color c )
{
this.m_Color = c;
}
private Color m_Color;
}
Unfortunately the current solution colors just the first row in the latest configured color, but the previously colored rows lose their color and get formatted by default.
Which possibilities do I have to avoid this 开发者_开发百科behaviour?
sincerely
Markus
You have to retain the state necessary for the renderer to apply the expected color at a specified location at any time. Swing will not remember the color for you.
You probably want to derive the color from the StatusEvents displayed in your table. In this case you must read the status in the renderer and apply the corresponding color.
for example by using prepareRenderer()
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TablePrepareRenderer extends JFrame {
private static final long serialVersionUID = 1L;
private JTable table;
public TablePrepareRenderer() {
Object[] columnNames = {"Type", "Company", "Shares", "Price"};
Object[][] data = {
{"Buy", "IBM", new Integer(1000), new Double(80.50)},
{"Sell", "MicroSoft", new Integer(2000), new Double(6.25)},
{"Sell", "Apple", new Integer(3000), new Double(7.35)},
{"Buy", "Nortel", new Integer(4000), new Double(20.00)}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
int firstRow = 0;
int lastRow = table.getRowCount() - 1;
if (row == lastRow) {
((JComponent) c).setBackground(Color.red);
} else if (row == firstRow) {
((JComponent) c).setBackground(Color.blue);
} else {
((JComponent) c).setBackground(table.getBackground());
}
/*if (!isRowSelected(row)) {
String type = (String) getModel().getValueAt(row, 0);
c.setBackground("Buy".equals(type) ? Color.GREEN : Color.YELLOW);
}
if (isRowSelected(row) && isColumnSelected(column)) {
((JComponent) c).setBorder(new LineBorder(Color.red));
}*/
return c;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
}
public static void main(String[] args) {
TablePrepareRenderer frame = new TablePrepareRenderer();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
精彩评论