【问题标题】:How to make a JTable with multiple Components?如何制作具有多个组件的 JTable?
【发布时间】:2016-02-14 11:43:27
【问题描述】:

我有一个 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;
        }

    };`

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

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • 这被称为“糖果剥离”(和其他一些),prepareRenderer 是一个糟糕的选择来实现它(恕我直言),因为它可能会覆盖渲染器可能一直在尝试的任何逻辑劝说(我只是不喜欢它:P)。你可以看看this alternative
  • 如果您对这种情况不感兴趣,请从第一种方法中调用第二种方法。 prepareRenderer 由 API 调用,因此这是入口点,然后您可以根据需要调用 prepareRowRenderer 后跟 prepareColumnRenderer 或反之亦然
  • @MadProgrammer 我尝试将第二种方法命名为“prepareColumnRenderer”并运行它,但没有运气
  • 你真的叫过它吗?
  • @MadProgrammer 是的,我打电话给table.getColumnModel().getColumn(6).setCellRenderer(new CustomRenderer());

标签: java swing colors jtable tablecellrenderer


【解决方案1】:

这被称为“糖果剥离”(以及其他一些),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;
}

【讨论】:

    【解决方案2】:

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

    不确定为什么您认为需要两个 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;
    }
    

    以上代码是从Table Row Renderring中的“数据示例”中“组合”而来的。

    所以你需要做的就是使用上面的结构稍微重构你的代码:

    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)。列可以再次移动。

    【讨论】:

    • 谢谢,效果很好。但是,红色单元格仅在被选中时才会显示为红色。你碰巧知道是什么原因造成的吗?谢谢
    • @SpencerCarlson,使用我建议整行应该是行选择颜色的逻辑,所以我不知道为什么它会是红色的。我看不到你的代码,所以我猜不出你在做什么。您需要发布 SSCCE 来证明问题。
    猜你喜欢
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    相关资源
    最近更新 更多