2

私はJMapViewerのオープンソースコードを熟読してきました。他の誰かがそれを見たい場合は、SVNを確認してください。

一言で言えば、メインクラスはJMapViewer、の拡張であるJPanelです。メインクラスのDefaultMapControllerとして機能する別の非常に重要なクラスがあります。MouseListener

私が最初に気付いた奇妙なことは、ビューアがコントローラへの参照を持っていないことです。コンストラクターは、次のようJMapViewerに、の匿名インスタンスをインスタンス化します。DefaultMapController

public JMapViewer() {
    // other stuff
    new DefaultMapController(this);
}

コントローラにはたくさんのメソッド(オプション、トグルなど-以下に示す例)があり、現在はまったくアクセスできないため、これは設計上の選択としては不適切なように思われます。

public void setMovementMouseButton(int movementMouseButton) {
    // changes which mouse button is used to move the map
}

上記の最初のスニペットに示されているように、コントローラーにはビューアーへの参照があります。これは、コントローラーが制御を実行する方法です。

しかし、それから私はさらに奇妙なことを考えました!リスナーのこの匿名インスタンスに参照がない場合、なぜそれが存続することさえ許可されるのですか?GCはすぐにそれを破壊するべきではありませんか?または、GCは、ライブを参照するリスナークラスJComponentも、なんらかの奇妙な理由で名前がない場合でも、正しく機能するために存続する必要があることを知っているほど賢いですか?

したがって、2つの実際の質問:

  • GCがオブジェクトを破棄しないのはなぜですか?
  • これは確かに貧弱な設計の選択ですか、それともビューアをインスタンス化するクラスからコントローラにアクセスすることに気付いていない方法がありますか?

このオープンソースライブラリに貢献したいと思います。変更の最初のアイデアは、JMapViewerクラスを変更してそのコントローラーを参照するフィールドを作成し、コンストラクターを変更して現在匿名のコントローラーをこの新しいフィールドに割り当てることです。しかし、私は無意識のうちに何かを見逃していないことを確認したいと思います。コードベース全体でテキストを検索しましたDefaultMapControllerが、それは独自のクラス定義とJMapViewerコンストラクターの匿名インスタンス化でのみ発生します。


編集:

java.awt.Componentメソッドを使用して、匿名リスナーにアクセスする方法があるように見えますgetMouseListeners()。したがって、技術的には、私のアプリケーションでは、このコレクションでのインスタンスを検索しDefaultMapController、それを使用して、コントローラーオプションを変更するために使用する必要のあるメソッドにアクセスできます。

ただし、悪魔の代弁者を演じるために、元のアイデアを使用してマップにそのコントローラーの参照を与えると、一種の循環参照が得られます(マップはコントローラーを認識し、コントローラーはマップを認識します)。これは悪い考えですか?

4

2 に答える 2

6

抽象親である、は、コンストラクターによって渡されたJMapControllerものへの参照を保持します。JMapViewerDefaultMapController

public DefaultMapController(JMapViewer map) {
    super(map);
}

補遺:コントローラーが保持する参照は、ここで説明mapするマップへの最大3つのコントローラー参照を(選択的に)追加するために使用されます。これらのいずれかがGCを排除します。少なくとも1つの有益な設計上の利点は、コンクリートが利用可能なインターフェースを実装するだけでよいことです。EventListenerListJMapController

このMVCの概要で示唆されているように、ビューにコントローラーへの参照を与えることは珍しいでしょう。対照的に、ここで提案されているように、コントローラーをビューのリスナーとして登録させることには何の問題もありません。

引数なしのJMapViewerコンストラクターのみがをインストールすることに注意してくださいDefaultMapController。のリビジョン29113の57〜59行目のコメントに記載されているように、代替コンストラクターを使用できますDemo.java。完全な例をここで調べます

于 2012-12-24T02:29:27.263 に答える
1

1)知っていることはすべて、VMが適切であると判断した場合、死んだオブジェクトの一部またはすべてを収集するということです。GCは何もする必要はありません。

2)一番いいのは、図書館の管理人に聞いてみることです。とにかく、原則として、読みやすさを大幅に向上させるなどの正当な理由がない限り、私は何も変更せず、むしろ実際の問題に集中したいと思います。

3)それが当てはまるかどうかはわかりませんが、JComponentをシリアル化すると、そのすべてのフィールドもシリアル化されます。そして、あなたは多くの未使用のものをシリアル化したくありません。

于 2012-12-24T02:08:07.263 に答える