代码之家  ›  专栏  ›  技术社区  ›  Draemon

自定义Swing组件-将节点转换为文本

  •  3
  • Draemon  · 技术社区  · 16 年前

    我正在编写一个定制的Swing组件(完全是新的,但可以考虑jtree或jlist)。为了保持一致性,我试图遵循jtree、jtable、jlist等的总体设计(我还看到了各种糟糕的第三方组件放弃了可分离的模型和/或渲染器方法)。

    所以,我有一个充满节点的模型,组件本身和一个渲染器。在某一点上,节点必须转换为文本并由渲染器显示。我不清楚如何做到这一点:

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

    我不想为了改变文本而定制渲染器,但我想 能够的 将渲染器自定义为不仅仅显示模型显示的字符串(否则,为什么要使用渲染器)。我真的不喜欢jxtable使用反射在模型中查找convertValueToText()这对我来说是一种糟糕的魔力。

    有人能解释一下这个经常被忽视的摆动部分吗?

    解决方案

    我最后做的是:

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

    这样,当开发人员想要覆盖显示的值时,他们就有了一个选择。 -使用非空返回值覆盖该方法,因为知道默认渲染器将显示此文本。 -提供一个自定义渲染器,该渲染器将传递实际节点对象,以便在需要时执行“巧妙”操作。

    我很满意它-它“感觉”对,它工作,而且很容易使用。

    谢谢你的观点!

    3 回复  |  直到 16 年前
        1
  •  1
  •   Leigh Caldwell    16 年前

    问得好。这不是特定于Swing,而是一个关于模型和视图之间差异的哲学问题。

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

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

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

    这允许最大的灵活性,并且可能使API的用户觉得事情最自然。我相信这是JTable模型,虽然我已经很久没有使用Swing了。

        2
  •  0
  •   ZeissS    16 年前

    afaik jlist和jtree都不需要渲染器渲染文本。渲染器将传递数据对象并返回一个jcomponent,该jcomponent将定位为树/列表本身的子级,然后进行渲染。
    我会同意的。文本渲染器只返回jLabel。如果希望能够更改方式,则构造文本时会将格式化程序传递给textfrender,这样就完成了。

    • 斯蒂芬
        3
  •  0
  •   Rastislav Komara    16 年前

    如果必须编写自己的组件,请尽可能简单地编写。在很多情况下,如果您需要自定义渲染器,那么您不关心按组件或模型进行解释。模型保存您的数据。在这种情况下,也是定制的。从我的观点来看,好的选择是基于第一选择。提供实现abstractrenderer的defaultrenderer,并在其中添加所有方法,如totex(object o)等。然后让我决定是使用默认功能还是自己编写。您真的需要自定义组件吗?要使它正确工作,需要做很多工作。这个部件值这么多钱吗?