Java:覆盖表格单元格渲染器,但具有默认背景和属性

发布于 2024-12-05 00:58:26 字数 2219 浏览 5 评论 0原文

如果您想添加自定义渲染器,通常,您可以扩展一些 JComponent (如 JLabel)并实现 TableCellRenderer,或者您' d 扩展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,第 2 部分 - 如何创建自定义渲染器

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

另一方面,如果我返回 this,那么我绝对什么也得不到。 Mac 原生 L&F 为我提供白色背景,而 Nimbus 为我提供其他颜色的纯色。

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

还有其他方法可以做到这一点吗?我考虑过尝试在其中放置一个本机样式的 JPanel ,然后将一个自定义(透明背景)组件作为其子组件,尽管我不确定如何去做,而且我'无论如何,我不太确定我是否会获得本机 L&F 表标题背景。事实上,我非常怀疑我是否会获得本机标头样式,而只是本机 JPanel 样式。

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

谢谢!

If you want to add a custom renderer, normally, you'd either extend some JComponent (like JLabel) and implement TableCellRenderer, or you'd extend DefaultTableCellRenderer. However, in either case, what I find is that the cell style is completely overridden.

What I'd really like is to be able to paint the default L&F background and then paint on top of it using other L&F defaults like foreground color and font.

So, here's what I tried to do. First, the class:

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.
    }
}

And then I override the cell (header) renderer like this:

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

I'm basically just following the suggestions here: TableCellRenderer, Part 2 - How To Create A Custom Renderer

If I return component, it renders as if I had overridden nothing. That is, I get the header with the label I had programmed with the chosen L&F background and style and everything. But, of course, there no way to render my stuff afterwards.

On the other hand, if I return this, then I get absolutely nothing. Mac native L&F gives me a white background, while Nimbus gives me a solid of some other color.

I'm clearly missing something. Are there other methods on the Component that I need to override and forward to the original? How does the default component get drawn if not by overriding paint? (I've also tried overriding paintComponent. No difference.)

Is there another way to do this? I've thought about trying to drop a native styled JPanel in there and then making a custom (transparent background) component its child, although I'm not sure about how to go about it, and I'm not really sure I'd get the native L&F table header background anyhow. In fact, I highly doubt I'd get the native header style, just the native JPanel style.

Basically, I need a custom table header (and separately, the cells too, actually), but I want to avoid messing too much with the native L&F.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白鸥掠海 2024-12-12 00:58:28

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

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

Check the DefaultTableCellRenderer source code, there you will see how the default behavior reads the defaults colors like:

        fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
        bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
调妓 2024-12-12 00:58:27

您可以查看 SelectAllHeaderTest,以及已接受答案中的有用警告。

附录:作为解释,请注意标头的外观受主机平台相应 UI 委托的支持,通常源自 TableHeaderUI。您可能希望将更改限制在 UIManager 默认值常见于流行的Look &感受实施。另外,不要重写paint()。我会避免重写paintComponent();并且,如有必要,重写 paintIcon(),如 TableSorter

You might look at the approach taken in updateUI() in SelectAllHeaderTest, as well as the helpful caveats in the accepted answer.

Addendum: By way of explanation, note that the header's appearance falls under the aegis of the host platform's corresponding UI delegate, usually derived from TableHeaderUI. You may want to confine your changes to the UIManager Defaults common to popular Look & Feel implementations. Also, don't override paint(). I would avoid overriding paintComponent(); and, if necessary, override paintIcon(), as shown in TableSorter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文