如何制作一个包含多个组件的 JTable?

How to make a JTable with multiple Components?

我有一个 JTable,我想对其应用两种 prepareRenderer 方法,但我不确定如何应用这两种方法。

JTable table = new JTable(model){

        public Component prepareRenderer(TableCellRenderer renderer, int row, int column){
            Component returnComp = super.prepareRenderer(renderer, row, column);
            Color alternateColor = new Color(241, 243, 247);
            Color whiteColor = Color.WHITE;
            if (!returnComp.getBackground().equals(getSelectionBackground())){
                Color bg = (row % 2 == 0 ? alternateColor : whiteColor);
                returnComp .setBackground(bg);
                bg = null;
            }
            return returnComp;
        }


        public Component prepareRenderer2(TableCellRenderer renderer, int rowIndex,
                int columnIndex) {
            JComponent component = (JComponent) super.prepareRenderer(renderer, rowIndex, columnIndex);  

            if(Double.parseDouble(getValueAt(rowIndex, 0).toString()) > (Double.parseDouble(rollReq.getText())) && columnIndex == 6) {
                component.setBackground(Color.RED);
            } else if(Double.parseDouble(getValueAt(rowIndex, 0).toString()) > (Double.parseDouble(rollReq.getText())) && columnIndex == 6){
                component.setBackground(Color.GREEN);
            }
            return component;
        }

    };`

第一个是将一行设为白色,将下一行设为灰色,以便于阅读。第二个是根据列的值更改列的单元格颜色。

如有任何帮助,我们将不胜感激。

谢谢!

这被称为 "candy stripping"(以及其他一些)并且 prepareRenderer 是实现它的一个糟糕选择(恕我直言),因为它可能会覆盖渲染器可能试图传达的任何逻辑(并且我只是不喜欢它 :P)。你可以看看 this alternative

我不喜欢使用 PrepareRenderer,它有可能覆盖单元格渲染器的规定逻辑,作为开发人员,我会诅咒你搞砸我

许多功能实际上更适合自定义单元格渲染器,但糖果剥离有点复杂。

在您的情况下,您需要从 prepareRenderer 方法调用您的自定义方法,因为没有其他人会为您做这件事

public Component prepareRenderer(TableCellRenderer renderer, int row, int column){
    Component returnComp = super.prepareRenderer(renderer, row, column);
    prepareRowRenderer(returnComp, row);
    prepareColumnRenderer(returnComp, col);
    return returnComp;
}

protected void prepareRowRenderer(Component returnComp, int row) {
    Color alternateColor = new Color(241, 243, 247);
    Color whiteColor = Color.WHITE;
    if (!returnComp.getBackground().equals(getSelectionBackground())){
        Color bg = (row % 2 == 0 ? alternateColor : whiteColor);
        returnComp .setBackground(bg);
        bg = null;
    }
}


public Component prepareColumnRenderer(TableCellRenderer renderer, int columnIndex) {
    if(Double.parseDouble(getValueAt(rowIndex, 0).toString()) > (Double.parseDouble(rollReq.getText())) && columnIndex == 6) {
        component.setBackground(Color.RED);
    } else if(Double.parseDouble(getValueAt(rowIndex, 0).toString()) > (Double.parseDouble(rollReq.getText())) && columnIndex == 6){
        component.setBackground(Color.GREEN);
    }
    return component;
}

The first one is to make one row white, and the next row grey, for easier readability. And the second one is to change the cell color of a column based on it's value.

不确定您为什么认为需要两个 prepareRenderer。只需将逻辑合并为一个:

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()); //removed
        c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY); // added
        int modelRow = convertRowIndexToModel(row);
        String type = (String)getModel().getValueAt(modelRow, 0);

        if ("Buy".equals(type)) c.setBackground(Color.GREEN);
        if ("Sell".equals(type)) c.setBackground(Color.YELLOW);
    }

    return c;
}

以上代码 "combined" 来自 Table Row Renderring 中的 "Data Example"。

所以您需要做的就是使用上述结构稍微重组您的代码:

  1. 检查行是否被选中
  2. 设置交替颜色背景
  3. 使用基于数据的背景颜色检查覆盖交替颜色

此外,您不应使用 columnIndex。用户可能对列重新排序。

(Double.parseDouble(getValueAt(rowIndex, 0).toString()) >
    (Double.parseDouble(rollReq.getText())) && columnIndex == 6) 

您应该使用:

int modelColumn convertColumnIndexToModel(columnIndex));
(Double.parseDouble(getValueAt(rowIndex, 0).toString()) >
    (Double.parseDouble(rollReq.getText())) && modelColumn == 6) 

出于同样的原因,您不应使用:getValueAt(rowIndex, 0)。再次可以移动该列。