私は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
、それを使用して、コントローラーオプションを変更するために使用する必要のあるメソッドにアクセスできます。
ただし、悪魔の代弁者を演じるために、元のアイデアを使用してマップにそのコントローラーの参照を与えると、一種の循環参照が得られます(マップはコントローラーを認識し、コントローラーはマップを認識します)。これは悪い考えですか?