![](/img/trans.png)
[英]JTable is coloring every cell when I only want it to color specific cells
[英]Coloring a single cell in a JTable when representing Color objects
我有一个JTable,用于在不同的行中显示许多不同的数据类型。 只有两列,其中左列是变量名,右列是与变量关联的变量(因此,使用ColumnModel不适合我的解决方案)。 到目前为止,这对于基元确实非常有效,对于JComboBox和JCheckBox的DefaultRenderer效果很好。
我现在正在尝试将java.awt.Color集成到表中,但是我希望将其呈现为使得单元格实际上充满了Color,并且根本没有文本(我不相信这在任何时候都不会很困难我明白了这一点。 到目前为止,我已经完成了单元的功能; 单击单元格将弹出JColorChooser并返回Color,然后将其应用于与该单元格关联的对象。 我为此使用的代码是:
JTable table = new JTable(new CustomModel(columnNames, values))
{
//Other functions inside here are excluded to keep it concise
public void changeSelection(int row, int col, boolean toggle, boolean extend)
{
/*Row is a custom object I am using for each row in the table. Its purpose is to
hold more information about the rows than I would normally be able to. Suffice
to say for this example, it will be returning something with a Color in it*/
Row obj = ((CustomModel)(table.getModel())).getRow(row);
/*ObjectProperties is essentially a modified version of a hashmap that also
stores the objects type among other things*/
if(obj.getType() == ObjectProperties.TYPE.COLOR)
{
Color newColor = JColorChooser.showDialog(null, "Pick color", Color.RED);
if(newColor != null)
{
table.getModel().setValueAt(newColor, row, col);
}
}
super.changeSelection(row, col, toggle, extend);
}
}
因此,这似乎工作得很好,但现在用于渲染。 我发现如果尝试设置DefaultRenderer,它将起作用,所以我使用了以下代码:
table.setDefaultRenderer(Color.class, new ColorRenderer());
我的ColorRenderer类如下:
public class ColorRenderer extends JLabel implements TableCellRenderer
{
public ColorRenderer()
{
setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col)
{
Color newColor = (Color)value;
setBackground(newColor);
return this;
}
}
但是,当我使用它时,我并没有显示实际的Color,而是获得了Color的String表示(我认为这意味着我的渲染器根本无法工作)。 因此,我仍然没有真正使它呈现正确的方式,更不用说当用户选择新内容时,它还可以更改显示的颜色。
我一直在努力让CustomRenderer正常工作,已经浏览了我可以使用的所有资源。 我认为Oracle的JTable部分中的教程非常有用,但最终并没有按我希望的那样工作。 这个论坛上的其他问题已经接近于适用于我的情况,但是通常缺少适用于特定对象类型(而不仅仅是特定单元格)的关键要素。 如果我要在表中存储许多Color对象,则理想情况下,我希望它们都以相同的方式运行。
如果我的实现中存在明显的错误或遗漏,那么指出这一点将是很棒的。 仔细研究一下代码(在多次发布之前,我已经重新阅读了一下,以确保我已经包括了所有内容),我相信问题可能出在我的Row类中。 它包含一个名为getValue()的方法,该方法将返回该对象,因此从技术上讲,我可以调用以下方法:
if(rowObject.getValue() instanceof Color)
//Apply renderer
但是,如何使用为特定类设置默认渲染器的代码来做到这一点呢?
不知道它是否是执行此操作的最佳方法,但重写getCellRenderer(int row, int col)
可能会帮助您:
public TableCellRenderer getCellRenderer(int row, int col){
//Only care about the first column
if(col == 1){
Row obj = ((CustomModel)(table.getModel())).getRow(row);
//Check to see if this is a color
if(obj.getType() == ObjectProperties.TYPE.COLOUR){
return super.getDefaultRenderer(Color.class);
}
}
//Either this wasn't a color or it wasn't the first column, either way its super.getCellRenderer's problem now
return super.getCellRenderer(row, col);
}
getCellRenderer(int row, int col)
似乎仅适用于列上的单元格渲染器位置,因此如果您只想以不同的方式渲染单个单元格,则效果不佳。
我见过的另一种替代方法是定义一个单元格渲染器,将其应用于列,并在您的单元格渲染器的getTableCellRendererComponent(...)
函数中确定这是哪种数据类型,以及是否渲染它或将其传递给另一个渲染器。
就我个人而言,我更喜欢第一种选择,但是如果您要渲染大量不同的自定义单元格类型,并且希望将所有呈现代码保留在一个类中,那么我可以看到第二种选择的吸引力。
您必须重写方法getColumnClass(int c)
int您的表模型中(最好使用DefaultTableModel ...)
class MyTableModel extends AbstractTableModel {
private String[] columnNames = ...//same as before...
private Object[][] data = ...//same as before...
//taken from http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
public Object getValueAt(int row, int col) {
return data[row][col];
}
public Class getColumnClass(int c) {
//here - check that the proper class is returned!
return getValueAt(0, c).getClass();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.