3

私はカスタムのスイング コンポーネント (まったく新しいものですが、JTree または JList を考えてください) を作成しています。一貫性を保つために、JTree、JTable、JList などの一般的な設計に従おうとしています (また、さまざまな貧弱なサードパーティ コンポーネントが分離可能なモデルやレンダラーのアプローチを放棄しているのを見てきました)。

したがって、ノード、コンポーネント自体、およびレンダラーでいっぱいのモデルがあります。ある時点で、ノードをテキストに変換し、レンダラーで表示する必要があります。これを行う最善の方法がわかりません:

  • ノード自体を (オブジェクトとして) レンダラーに渡し、レンダラーに表示方法を決定させます。
    • これが JList のやり方です。
    • テキストを変更するためだけに、カスタマイズされたレンダラーが必要です。
    • ノードの表示方法を非常に柔軟に設定できます (テキストである必要さえありません)。
  • ノード自体を (オブジェクトとして) レンダラーに渡しますが、コンポーネント クラスには convertValueToText() メソッドがあります。
    • これが JTree のやり方です。
    • レンダラーは以前と同じように柔軟にすることができます -この方法を使用する必要はありません。
    • テキスト変換を変更するには、コンポーネントをオーバーライドする必要があります。
  • 上記と同様ですが、convertValueTotext() をモデルにデリゲートします。
    • これが JXTable のやり方です。
    • モデルはおそらくこのメソッドに最適な場所であり、そこでオーバーライドする方が簡単です。

テキストを変更するためだけにレンダラーをカスタマイズする必要はありませんが、モデルに表示される文字列を表示する以上のことを行うためにレンダラーをカスタマイズできるようにしたいと考えています (そうでなければ、レンダラーを気にする必要があります)。JXTable がリフレクションを使用してモデル内の convertValueToText() を検索するという事実が本当に気に入りません。これは悪い魔法の匂いがします。

Swing のこの見過ごされがちな部分に光を当てることができる人はいますか?

解決

私がやったことはこれでした:

  • 指定されたノードの文字列を返すメソッドをモデルに追加します。重要なのは、レンダラーが何をすべきかを知っている必要があること、または単に有用なものを提供できないことを示すために、これを null にすることができることです。
  • コンポーネントには同じメソッドがあり、呼び出しをモデルに渡します。これは、ビュー モデルの分離にとって重要です。レンダラーはこのメソッドを呼び出すため、モデルと直接対話しません。
  • デフォルトのレンダラーは上記のメソッドを呼び出し、それが null でない場合はそれを使用します。

これにより、開発者は、表示された値をオーバーライドしたい場合に選択肢が残ります。デフォルトのレンダラーがこのテキストを表示することを認識して、null 以外の戻り値でメソッドをオーバーライドします。- 実際のノード オブジェクトが渡されるカスタム レンダラーを提供して、必要に応じて「賢い」ことを実行できるようにします。

私はとても満足しています - それは正しく「感じ」、機能し、使いやすいです。

あなたの視点をありがとう!

4

3 に答える 3

1

良い質問。これはSwingに固有のものではありませんが、モデルとビューの違いに関する哲学的な質問です。

一般に、オブジェクトをテキストに変換することは、モデルまたはビューの仕事ですか?私の純粋主義者の頭は、実際にはビューの階層が必要だと言っています。1つはオブジェクトモデルをテキストに変換し、もう1つはテキストを表示します。たとえば、オブジェクトからテキスト、テキストからドキュメント構造、ドキュメント構造からHTML、そしてCSSをユーザーに提示するなど、2つ以上が必要な場合もあります。

ただし、実用主義では、これを覚えて維持するのが難しくなる可能性があると述べています。したがって、あなたの状況では、私は提案します:モデルから非テキストデータを抽出したいと思う可能性がどれほどあるかを考えてください。可能性が低い場合は、convertValueToTextに相当するものをモデルに配置します。

それ以外の場合は、コンポーネントにレンダラーが指定されている場合はそれを使用するか、オブジェクト値を取得して内部でテキストに変換することを許可します。

これにより、最大限の柔軟性が得られ、APIのユーザーにとって最も自然に感じられるようになります。長い間Swingを使っていませんが、これはJTableモデルだと思います。

于 2008-10-18T14:52:40.907 に答える
0

AFAIKは、JListもJTreeも、レンダラーがテキストをレンダリングする必要はありません。レンダラーはデータオブジェクトを渡され、ツリー/リスト自体に子として配置されてレンダリングされるJComponentを返します。
私はこれで行きます。テキストのレンダラーは、単にJLabelを返します。方法を変更できるようにしたい場合は、テキストが作成され、フォーマッターがTextRenderに渡されます。これで完了です。

  • ステファン
于 2008-10-18T22:00:58.107 に答える
0

独自のコンポーネントを作成する必要がある場合は、できるだけ簡単に作成してください。多くの場合、カスタム レンダラーが必要な場合、コンポーネントやモデルによる解釈は気にしません。モデルはデータを保持します。そして、この場合も特注です。私の観点から、良い選択は最初のオプションに基づいています。AbstractRenderer を実装する DefaultRenderer を提供し、そこに toText(Object o) などのすべてのメソッドを追加します。次に、デフォルトの機能を使用するか、独自の機能を作成するかを決定します。カスタムコンポーネントが本当に必要ですか? それを正しく機能させるには、多くの作業が必要です。このコンポーネントはこれだけの価値がありますか?

于 2008-10-19T18:46:28.737 に答える