【问题标题】:Java: Override table cell renderer, but with default background and propertiesJava:覆盖表格单元格渲染器,但具有默认背景和属性
【发布时间】:2011-11-19 22:06:41
【问题描述】:

如果您想添加自定义渲染器,通常,您要么扩展一些 JComponent(如 JLabel)并实现 TableCellRenderer,要么扩展 DefaultTableCellRenderer。但是,无论哪种情况,我都发现单元格样式被完全覆盖。

我真正想要的是能够绘制默认的 L&F 背景,然后使用其他 L&F 默认值(如前景色和字体)在其上绘制。

所以,这就是我尝试做的。一、类:

public class IntervalHeaderRenderer extends JLabel implements TableCellRenderer {

    private TableCellRenderer delegate;
    private Component component;

    public IntervalHeaderRenderer(TableCellRenderer defaultRenderer)
    {
        this.delegate = defaultRenderer;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
                           boolean isSelected, boolean hasFocus, int row, int column)
    {
        component = delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        // Maybe override some settings.  
        // You could make the label bold, for instance.

        return component;
        // return this;
    }

    @Override
    public void paint(Graphics g) {
        // What I really want to do is paint the original component
        component.paint(g);
        // And then draw on top of it.
    }
}

然后我像这样覆盖单元格(标题)渲染器:

TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();
table.getColumnModel().getColumn(1).setHeaderRenderer(new IntervalHeaderRenderer(renderer));

我基本上只是按照这里的建议:TableCellRenderer, Part 2 - How To Create A Custom Renderer

如果我返回 component,它会呈现为好像我没有覆盖任何内容。也就是说,我得到带有我选择的 L&F 背景和样式以及所有内容编程的标签的标题。 但是,当然,之后就无法渲染我的东西了。

另一方面,如果我返回this,那么我将一无所获。 Mac 原生 L&F 给了我一个白色的背景,而 Nimbus 给了我一个其他颜色的纯色。

我显然错过了一些东西。 Component 上是否还有其他方法需要我覆盖并转发到原始方法?如果不是通过覆盖paint,如何绘制默认组件? (我也尝试过覆盖paintComponent。没有区别。)

还有其他方法可以做到这一点吗?我考虑过尝试将原生样式的JPanel 放在那里,然后制作一个自定义(透明背景)组件作为它的子组件,尽管我不确定如何去做,我也不确定我无论如何都会得到原生 L&F 表 header 背景。事实上,我非常怀疑我会得到原生标题样式,只是原生 JPanel 样式。

基本上,我需要一个自定义表格标题(实际上也需要单独的单元格),但我想避免过多地与原生 L&F 混淆。

谢谢!

【问题讨论】:

  • 绘制默认的 L&F 背景,然后使用其他 L&F 默认值(如前景色和字体)在其上绘制。 - 如果一切都应该是默认值,只需使用 ..默认值 ;-) 因为这不是你的意图:究竟你想与默认值有什么不同?

标签: java swing jtable tablecellrenderer jtableheader


【解决方案1】:

您可能会在SelectAllHeaderTest 中查看updateUI() 中采用的方法,以及已接受答案中的有用警告。

附录:作为解释,请注意标头的外观属于主机平台的相应 UI 委托的保护,通常派生自 TableHeaderUI。您可能希望将更改限制在流行的外观实现常见的UIManager Defaults。另外,不要覆盖paint()。我会避免覆盖paintComponent();并在必要时覆盖paintIcon(),如TableSorter 所示。

【讨论】:

  • 感谢您的帮助!我快到了。根据您的建议,我现在有了正确的背景。但是,您说不要覆盖paint()。为了在背景上绘制我的自定义小部件,我需要覆盖什么?谢谢。
  • 其实用这个方法,Mac原生看起来不错,但Nimbus就不行了。
  • "Swing 程序应该覆盖paintComponent(),而不是覆盖paint()。"—Painting in AWT and Swing。请提供一个sscce 显示您修改后的方法。
【解决方案2】:

查看DefaultTableCellRenderer 源代码,您将看到默认行为如何读取默认颜色,例如:

        fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
        bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2013-01-11
    • 1970-01-01
    相关资源
    最近更新 更多