如何在几个不同的位置更改JTable彩色单元?

时间:2017-02-27 10:20:42

标签: java swing jtable

我有一个JTable对象,它显示Excel表的内容。加载另一个Excel表后,必须显示差异(因此某些单元格将更改其背景颜色,例如蓝色)。这是我桌子的结构。

enter image description here

这是我的代码:

 tblGSM.setDefaultRenderer(Object.class, new CustomTableRenderer(diffs));

CustomTableRenderer.java

public class CustomTableRenderer extends DefaultTableCellRenderer {

    private Vector<Diff> diffs;


public PersoTableRenderer(Vector<Diff> diffs){
    this.diffs = diffs;
}

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

   Component c = null;

    for (int x = 0; x < diffs.size(); x++){

        Diff d = diffs.elementAt(x);

        c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, 
                d.getRow(), d.getColumn());
        c.setBackground(Color.BLUE);
    }
    return c;
}}

Diff.java

/*
A class to store the difference of corresponding cells
*/

public class Diff {
    private int row, col;

    public Diff(int row, int col){
        this.row = row;
        this.col = col;
    }

    public Diff(){
        this(0,0);
    }

    public int getRow(){
        return row;
    }

    public int getColumn(){
        return col;
    }
}

我的问题是差异是否正确填充,但是应该更改的单元格颜色不是。结果显示第1,2,3和1列中的所有单元格都已更改。这是什么解决方案呢?

1 个答案:

答案 0 :(得分:2)

来自the documentation for DefaultTableCellRenderer(强调我的):

  

然而,JTable采用独特的机制来渲染其单元格,因此需要从其单元格渲染器中稍微修改一些行为。 表类定义单个单元格渲染器,并将其用作橡皮图章,用于渲染表格中的所有单元格;它渲染第一个单元格,更改该单元格渲染器的内容,将原点移动到新位置,重新绘制它,依此类推。

正如您所看到的,super.getTableCellRendererComponent()可能会为多个单元格返回相同的组件,因此您的方法将无效。

请注意,getTableCellRendererComponent在呈现时每个单元格调用一次,因此除了上述警告之外,在检索时将表中的所有渲染器组件设置为蓝色的一般方法单个单元格的组件不正确。

相反,您只需要 修改所请求组件的背景颜色,例如(伪代码):

c = super.getTableCellRendererComponent(..., row, column)

// also don't forget to translate to model coords
model_row = table.convertRowIndexToModel(row)
model_column = table.convertColumnIndexToModel(column)

if diffs contains model_row,model_column:
    c.setBackground(blue)
else
    c.setBackground(table.getBackground()) // don't forget to reset

return c

注意到如果不是“diff”单元格,您还必须将背景颜色重置为默认值,因为正如文档所述,组件在多个单元格之间共享。

顺便说一句,您不应该在渲染器中存储Vector<Diff>,而应该使用正确的TableModel,然后查询模型以获取信息。通过一个明智的实现模型,这也可以让您不断地查询单元格是否应该是蓝色,而不必搜索整个Diff列表。

PS:Don't forget to translate your renderer/view coordinates to model coordinates使用Diff时,假设它们在模型坐标中。如果例如,视图坐标可能与模型坐标不一致表已排序或用户已重新排列列。我在上面的伪代码中已经证明了这一点。

Here is a complete example显示使用表格模型和每单元格自定义背景。您可以对表格进行排序并重新排列其列。