java - 自定义 swing 组件 - 将节点转为文本

标签 java swing

我正在编写一个自定义 swing 组件(一些全新的东西,但想想 JTree 或 JList)。我试图遵循 JTree、JTable、JList 等的一般设计以保持一致性(我还看到各种糟糕的第 3 方组件放弃了可分离模型和/或渲染器方法)。

所以,我有一个充满节点的模型、组件本身和渲染器。在某些时候,节点必须转换为文本并由渲染器显示。我不清楚执行此操作的最佳方法:

  • 将节点本身(作为对象)传递给渲染器,让渲染器决定如何显示它。
    • JList 就是这样做的。
    • 需要自定义渲染器来更改文本。
    • 允许在如何显示节点方面有很大的灵 active (甚至不必是文本)。
  • 将节点本身(作为对象)传递给渲染器,但在组件类中有一个 convertValueToText() 方法。
    • JTree 就是这样做的。
    • 渲染器可以像以前一样灵活 - 不必使用此方法。
    • 必须覆盖组件才能更改文本转换。
  • 同上,但将 convertValueTotext() 委托(delegate)给模型。
    • JXTable 就是这样做的。
    • 模型可能是此方法的最佳位置 - 在那里更容易重写。

我不想仅仅为了更改文本而自定义渲染器,但我希望能够自定义渲染器来做更多的事情,而不是显示模型显示的字符串 (否则为什么要费心渲染器)。我真的不喜欢 JXTable 使用反射来寻找模型中的 convertValueToText() 这一事实 - 这对我来说是一种糟糕的魔法。

谁能阐明 Swing 中这个经常被忽视的部分?

解决方案

我最后做的是这样的:

  • 向模型添加一个方法,该方法返回给定节点的字符串。重要的是,这可以为 null,表示渲染器应该知道该做什么,或者我们根本无法提供任何有用的东西。
  • 该组件具有相同的方法,并将调用传递给模型。这对于 View 模型分离很重要。渲染器调用此方法,因此它不会直接与模型对话。
  • 默认渲染器调用上述方法,如果它不为 null,则使用它,否则它可以对值调用 toString,或提供默认值,或其他任何方式。

这让开发人员可以选择何时覆盖显示的值 - 使用非空返回值覆盖该方法,知道默认渲染器将显示此文本。 - 提供传递给实际节点对象的自定义渲染器,以便它可以在需要时做“聪明”的事情。

我对它非常满意 - 它“感觉”正确、有效且易于使用。

感谢您的观点!

最佳答案

好问题。这不是 Swing 特有的,而是一个关于模型和 View 之间区别的哲学问题。

一般来说,将对象转换为文本是模型的工作还是 View 的工作?我的纯粹主义者说实际上你想要一个 View 层次结构——一个将对象模型转换为文本,一个显示文本。您甚至可能需要两种以上 - 例如,对象到文本、文本到文档结构、文档结构到 HTML,然后是 CSS 以呈现给用户。

然而,实用主义认为这可能会变得难以记住和维护。因此,在您的情况下,我建议:考虑一下您想要从模型中提取非文本数据的可能性有多大。如果不太可能,则将 convertValueToText 的等效项放入模型中。

否则,允许组件使用渲染器(如果给定的话),或者获取对象值并在内部将其转换为文本。

这允许最大的灵 active ,并且可能使 API 的用户感觉最自然。我相信这是 JTable 模型,尽管我已经很长时间没有使用 Swing 了。

关于java - 自定义 swing 组件 - 将节点转为文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/215074/

相关文章:

java - a4j :included rich:dataTable negatively affects a4j:commandButton

java - SwingWorker publish()/process() 就像 done()

java - 如何更改 JSpinner 上的默认选择?

java - 如何从 JFrame 切换到 java 类?

java - 如何更改 JButton 的文本颜色

java - 提供上下文时出现异常 :annotation-config

java - 如何检查可能存在或不存在的元素的可见性?

java - catch block 在 C++ native 库中不起作用

java - Firebase .indexOn 未按预期工作

java - 使 JTree 叶子显示为空目录而不是文件