当前位置: 首页 > 知识库问答 >
问题:

我们可以一起使用准备渲染器组件和自定义单元格渲染器吗?

崔单弓
2023-03-14

我正在尝试将准备渲染器组件与自定义单元格渲染器一起使用。这个想法是使用准备渲染器绘制整行,并使用客户单元格渲染器绘制基于单元格值的自定义

prepareRenderer 通过突出显示整行来按预期工作,但自定义单元格呈现器突出显示的单元格不会显示颜色,除非选定该属性。自定义单元格呈现似乎仅在单元格选择时起作用(突出显示包含 1 的单元格,但仅在选择时)。

关于如何使两者齐头并进,有什么想法吗?

下面的代码重现此问题。

[![import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import java.awt.*;

public class SortTableWithColors_ extends JFrame {
    public static void main(String\[\] args) {
        SortTableWithColors_ frame = new SortTableWithColors_();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public SortTableWithColors_() {
        Object\[\] columnNames = {"B", "C"};
        Object\[\]\[\] data = {{new Integer(1), new Integer(4)},
                {new Integer(2), new Integer(5)},
                {new Integer(3), new Integer(3)},
                {new Integer(4), new Integer(1)}};
        // table model
        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        // set table model in Jtable
//        JTable table = new JTable(model);
        NewJTable table = new NewJTable(model);
        table.setAutoCreateRowSorter(true);
        getContentPane().add(new JScrollPane(table));

        // Tell the table what to use to render our columns
        for (int i = 0; i < 2; i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(new NewRenderer());
        }
    }

    // Custom Renderer
    public class NewRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent
                (JTable table, Object value, boolean isSelected,
                 boolean hasFocus, int row, int column) {
            JLabel cell = (JLabel) super.getTableCellRendererComponent
                    (table, value, isSelected, hasFocus, row, column);

            int rowModel = (int) table.convertRowIndexToModel(row);
            int colModel = (int) table.convertColumnIndexToModel(column);
            int rowView = (int) table.convertRowIndexToView(row);
            int colView = (int) table.convertColumnIndexToView(column);

            // set color
//            cell.setBackground(new Color(0xFFFFFF));
//            cell.setForeground(new Color(0x000000));

            //set selection colors
            if (isSelected) {
                cell.setBackground(new Color(0x4AC3FF));
                cell.setForeground(new Color(0x000000)); // AM
            }
            // Selective cell colouring based on value

            // paint cells
            int val = (int) value;
            if (val == 1) {
                cell.setBackground(Color.GREEN);
            }
            return cell;
        }
    }

    public class NewJTable extends JTable {
        public NewJTable(TableModel model) {
            super(model);
        }

        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());
                int modelRow = convertRowIndexToModel(row);
                int val = (int) getModel().getValueAt(modelRow, 0);
                if (val == 3) {
                    c.setBackground(Color.YELLOW);
                }
            }
            return c;

        }
    }
}]

共有1个答案

赵元白
2023-03-14

不要试图同时做两件事。您需要在逻辑上将渲染分解为两个步骤。

渲染器代码在准备渲染器代码之前执行。所以:

> < li>

首先,您需要让渲染器按照您希望的方式工作。

然后,其次,通过突出显示包含值 3 的行来覆盖默认呈现。

在渲染器中更改背景的关键点是,在执行任何自定义之前,必须始终将其重置为默认值。

因此,在渲染代码中,您需要注释掉的行:

// set color (ie. restore the default values)
cell.setBackground(new Color(0xFFFFFF));
cell.setForeground(new Color(0x000000));

然后,在准备渲染器中,您不需要重置背景,只有在满足条件时才更改它:

// get rid of this, the default has already been set. 
// this code should only provide the override
//c.setBackground(getBackground());

注意:仅当您在将背景重置为默认值的所有列上都有自定义渲染器时,这才有效。由于我们需要注释掉上述语句,因此现在每个渲染器都有责任重置背景。

 类似资料:
  • 我创建了一个带有自定义表格呈现和自定义单元格编辑器的JTable,它在图像中给出结果 我使用一个扩展JPanel的单独类创建了第一个表格单元格中显示的面板。并将表值添加为, 这是我的表格自定义类来创建这个表格, 我的问题是认为面板如我预期的那样显示,我不能在文本字段中键入或更改复选框或单击按钮。请告诉我如何解决这个问题。

  • 问题内容: 我正在跟踪发现的一些代码,(是的,我知道它是如何工作的)它来自这里:代码链接 我想做的是如果单元格值设置为“黄色”,则设置单元格前景色 这是我的代码: 和单元格渲染器 问题是,如果我将任何单元格值设置为“黄色”,它就不会改变 提前致谢! 问题答案: 您的渲染器曾经使用过吗?您将其设置为包含String的单元格的默认渲染器,但是是否重载了模型的方法,以便它知道某些单元格包含String

  • 我想从vaadin表切换到到处都是赞美的网格,但我不知道如何克服网格无法呈现组件的限制。在表格中,我有一列显示水平布局,按钮数量动态。网格允许使用按钮渲染器,但这意味着每列中只有一个按钮将呈现,我需要它更灵活。也许我可以编写自己的渲染来支持我需要的东西,但它需要一些较低级别的/ gwt / javascript编程,我不确定所需的结果是否可以实现。亲爱的瓦丁伙计们,你们有什么建议?

  • 我对React Router中路由的渲染顺序有问题。据我所知,任何子路由都将在其父路由之后进行渲染,因此将在DOM中的父路由之上进行渲染。 <代码> 我有这个路由器设置,但是在我从IndexRoute导航到/browse路由之后,浏览路由呈现在我的导航组件的顶部,我不能单击导航组件上的任何内容。 我的问题是如何强制Nav组件始终最后渲染,或者是否有更好的方法来构建我的应用程序以避免这种情况。 谢谢

  • 问题内容: 假设我有以下JTable,只要按下一个按钮,就会显示该JTable: 我想呈现 最初 对JCheckBox 为真的单元格,以及所有 最初为 false的所有单元格不显示任何内容(无JCheckBox)。用户可以选中或取消选中最初为真的单元格中的JCheckBoxes,这会对我创建的图表有所帮助。 现在,我的单元格渲染器在所有单元格中显示JCheckBoxes,包括最初为false的单元

  • 问题内容: 我已将JTable设置为在同一列中显示String和Boolean值。我有以下代码来设置两种对象类型的渲染器。 我面临的问题是,总是调用Object的渲染器,而不是布尔值或字符串。我尝试删除对象的渲染器,仍然没有运气。 问题答案: 我已将JTable设置为在同一列中显示String和Boolean值 然后,您不能只使用普通的渲染逻辑。 通常,根据方法返回的值选择渲染器。但是,这是基于列