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

难以理解swing的JTable和JTree的渲染器机制

邵修诚
2023-03-14

通常在使用JTable或JTree时,用户定义自己的单元渲染器。

从DefaultTableCellRenderer继承用户组件是很常见的,它实现了renderer方法getTableCellRendererComponent。事实证明,DefaultTableCellRenderer实际上继承自JLabel,因此在调用super(在render方法中)时返回自身(this),因此用户的渲染器也可以类似地返回自身(this)。

这一切都很好。

我的问题是怎么可能?

每次表调用此方法时,都会为其指定不同的参数,并且输出标签会随着这些参数的变化而变化。如果它确实是标签的同一个实例,是否应该根据上次调用此方法来更改它?这难道不意味着表的所有单元格都由相同的label实例组成,该实例具有相同的值(上次调用renderer方法的值)?

我已经搜索了web,并在Swing的代码中进行了挖掘,但没有找到任何克隆或复制构造函数的行为,这些行为实际上复制了输出标签。我找不到任何证据表明(可能)swing每次都使用html" target="_blank">反射来从头开始重新实例化渲染器。

我已经阅读了Swing关于JTables的教程,在那里我可以找到以下几行内容:

您可能期望表中的每个单元格都是一个组件。但是,出于性能原因,Swing表的实现方式不同。相反,通常使用单个单元格渲染器来绘制包含相同类型数据的所有单元格。您可以将渲染器视为可配置的墨水印章,表格使用它将适当格式的数据印章到每个单元格上。当用户开始编辑单元格的数据时,单元格编辑器会接管单元格,控制单元格的编辑行为。

他们给出了一个暗示,我所说的确实是正确的,但没有解释它是如何实际完成的。

我拿不到。你们有人能吗?

共有3个答案

景承教
2023-03-14

经过一些挖掘,从DefaultTableCellRenderer文档中找到了下一个实现注释:

实现说明:这个类继承自JLabel,一个标准组件类。然而,JTable使用了一种独特的机制来渲染其单元格,因此需要对其单元格渲染器的行为进行一些轻微的修改。table类定义了单个单元格渲染器,并将其用作橡皮戳,用于渲染表中的所有单元格;它渲染第一个单元,更改该单元渲染器的内容,将原点移动到新位置,重新绘制它,等等。标准的JLabel组件不是设计用于这种方式的,我们希望避免每次绘制单元格时触发重新验证。这将大大降低性能,因为重新验证消息将在容器的层次结构中向上传递,以确定是否会影响任何其他组件。由于渲染器仅在绘制操作的生命周期内作为父级,因此我们同样希望避免与遍历绘制操作的层次相关的开销。因此,该类将validate、invalidate、revalidate、repaint和firePropertyChange方法重写为no-ops,并重写isOpaque方法以提高性能。如果您编写自己的渲染器,请记住这一性能考虑因素。

这基本上就是JB在上面所解释的。

感谢(快速)回答

田嘉澍
2023-03-14

除了@JB对JTableJTree如何使用轻量级模式的明确解释之外,请注意这两个类如何提供公共方法getCellRenler()getCellEditor()。检查这些方法以了解JTable如何使用类字面量作为运行时类型令牌来按类选择渲染器或编辑器,如果列没有指定。在内部,JTable使用Hashtable defaultRenderersByClonClass作为实例存储

宦翔
2023-03-14

这是轻量级模式的实现。

当JTable重新绘制自身时,它会启动一个循环,并迭代必须绘制的每个单元格。

对于每个单元,它使用对应于单元的参数调用渲染器。渲染器返回一个组件。此组件绘制在与当前表格单元格对应的矩形中。

然后为下一个单元格调用渲染器,返回的组件(例如具有不同的文本和颜色)被绘制在对应于单元格的矩形中,等等。

假设每次调用渲染器时,都会获取返回组件的屏幕截图并粘贴到表单元格中。

 类似资料:
  • 问题内容: 通常,在使用或用户编写和分配时,它是自己特定的单元格渲染器。 从中继承用户的组件并实现renderer方法是很常见的。事实证明,实际上是继承自JLabel,因此在调用super时(在render方法处)返回自己(此),因此用户的渲染器也可以类似地返回自己(此)。 而且一切正常。 我的问题是怎么回事? 每次表调用此方法时,都会为其分配不同的参数,并且输出标签将根据这些参数进行更改。如果确

  • 我试图使我的头的背景具有渐变。 这可以很好地使用代码: 然而,由于某种原因,我看不到我的边框和文本,似乎文本也应用了渐变? 我希望文本为黑色,各栏之间有彩色边框。有什么想法吗?

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

  • 我已经建立了一个,并使其包含18列。最初,当它是13列时,它非常适合JTable,并且没有撕裂。然而,一旦我使它包含18个表,并将自动调整大小设置为关闭,当我使用水平滚动条尝试滚动其他列时,JTable的撕裂开始发生,如图所示: Netbeans还开始向我发送大量错误消息,如: 为什么会这样?这个问题有什么解决办法吗?谢谢 真抱歉!下面是用于初始化表的代码。希望会有用!

  • 本文向大家介绍深入理解Vue 的条件渲染和列表渲染,包括了深入理解Vue 的条件渲染和列表渲染的使用技巧和注意事项,需要的朋友参考一下 这两天学习了Vue.js 感觉条件渲染和列表渲染知识点挺多的,而且很重要,所以,今天添加一点小笔记。 条件渲染 v-if 在 < template > 中配合 v-if 渲染一整组 在使用 v-if 控制元素的时候,我们需要将它添加到这个元素上去。然而如果要切换很

  • 我有一个swing应用程序,它在JScrollPane中包含一个SVG画布。应用程序修改显示的SVG文档,这也会导致文档大小的更改。此大小更改需要反映在应用程序中。调整SVG画布的大小,滚动JScrollPane的视口,以便它显示画布的正确部分。 然而,这导致了类似“视觉跳跃”的东西,因为用户首先看到画布大小的变化,然后看到滚动操作。 有没有一种方法可以告诉java停止处理给定组件(及其子组件)上