Java:覆盖表格单元格渲染器,但具有默认背景和属性
如果您想添加自定义渲染器,通常,您可以扩展一些 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
检查
DefaultTableCellRenderer
源代码,您将看到默认行为如何读取默认颜色,例如:Check the
DefaultTableCellRenderer
source code, there you will see how the default behavior reads the defaults colors like:您可以查看
SelectAllHeaderTest
,以及已接受答案中的有用警告。附录:作为解释,请注意标头的外观受主机平台相应 UI 委托的支持,通常源自
TableHeaderUI
。您可能希望将更改限制在 UIManager 默认值常见于流行的Look &感受实施。另外,不要重写paint()
。我会避免重写paintComponent()
;并且,如有必要,重写paintIcon()
,如TableSorter
。You might look at the approach taken in
updateUI()
inSelectAllHeaderTest
, 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 overridepaint()
. I would avoid overridingpaintComponent()
; and, if necessary, overridepaintIcon()
, as shown inTableSorter
.