• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:JLabelとJLabelを結ぶ直線をJComponentとしてカプセル化)

JLabelとJLabelを結ぶ直線をJComponentとしてカプセル化する方法

このQ&Aのポイント
  • JPanel上のJComponentを繋ぐ直線を表すクラスを作成する方法について教えてください。
  • 線をオブジェクトとしてカプセル化するための効果的な方法はありますか?
  • ピュアJavaのライブラリでこの機能を実装するためのヒントを教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • HarukaV49
  • ベストアンサー率53% (48/89)
回答No.2

>OriginalPanelに実装したMouseListenerやMouseMotionListenerの中で、 >カーソルがどのOriginalLine上にあるか判定しなければいけないという >ことでしょうか。 いかにも面倒で処理が重そうに感じるという意味での疑問でしょうか? 私は、何の疑問も持たずに以前そのように実装した経験を持ちます(^^; 別の意味での質問でしたら、再質問をお願いいたします。 他の方法があるとすれば、私としても知りたい限りです。 なお私の場合、具体的な当たり判定には、マウス周りの(微小)正方形領域と OriginalComponentをintersectsで判定していたと思います。 containsを使って、思い通りに判定できていれば問題ありませんが。

unchikun
質問者

お礼

> いかにも面倒で処理が重そうに感じるという意味での疑問でしょうか? おっしゃる通り、リスナの全てのメソッド実装部で、forループを回すのが面倒だな~と感じたのと、追加する部品が増えると重くなるのでは、と感じたためです。 心配することでもないようなので、気にしないようにします。 > containsを使って、思い通りに判定できていれば問題ありませんが。 直線の判定はうまくいかなかったので、おっしゃる通りintersectsで判定するようにしました。 あとは、mouseEnteredやmouseExitedをどうエミュレートしようか迷っているところですが、教えていただいた方法も無事理解でき、実装できたので今回はここまでにしたいと思います。 大変助かりました。 ご回答ありがとうございました。

その他の回答 (1)

  • HarukaV49
  • ベストアンサー率53% (48/89)
回答No.1

JPanel上に描画した直線をJComponentのサブクラスとする発想は 少し無理があると思います。 代替案として、まずShapeインターフェースを実装したOriginalLine クラスを実装します。そこに、座標、色、結合しているJComponentの 情報等を持たせます。 (今回の場合には、これを描画するパネルも独自に作成するため  Shapeインターフェースを実装しなくても大丈夫ですが) このクラスに、addMouseIntersectListener(MouseIntersectListener l)等の オリジナルのメソッドを実装して、MouseIntersectListenerクラスを 描画したパネルのMouseMotionListenerから呼び出されるようなListenerクラスと Eventクラスを作ります。 そして、JPanelを継承したOriginalPanelクラスを作成して、 add(OriginalLine line), remove(OriginalLine line)メソッドを 実装して、OriginalLineをArrayListに格納しておいて、paint(Grarhics g) をオーバーライドし、OriginalLineを描画するようにします。 このようにすることで、JComponent同士を結ぶ直線は、addメソッドで 追加できますし、イベントを生成することも出来るようになるため、 JComponentと違わない、使いやすさを実現できるでしょう。 非常に大雑把な説明ですが、概略は以上です。 具不明な点がありましたら、追加質問をお願いいたします。

unchikun
質問者

お礼

ご回答ありがとうございます。 なるほど、大体の流れはつかむことが出来ました。 結局Shapeのメソッドは実装しました。 というのも後々あたり判定をする際に必要になってくると感じたためです。 しかし全て1から実装するのは面倒だったので、OriginalLineの内部にGeneralPathを持たせて処理を委譲するという形にしました。 また、OriginalLineに、OriginalPanelに描画するオリジナルのコンポーネントを表すクラス abstract class OriginalComponent implements Shape {  List<MouseIntersectListener> listener;  ...  abstract void paint(Graphics g);  addMouseIntersectListener(MouseIntersectListener l) {   listener.add(l);  }  public boolean contains(double x, double y){} ... } を継承させて、描画処理を実装し class OriginalPanel extends JPanel {  List<OriginalComponent> components;  void paint(Graphics g) {   for (OriginalComponent c : components)    c.paint(g);  } } みたいな感じで描画することにしました。 1つ疑問なのですが、パネル上で発生したイベントを、OriginalLine上で発生したイベントとして扱うためには(どのOriginalLineに登録されたリスナにイベントを渡すか)は、OriginalPanelに実装したMouseListenerやMouseMotionListenerの中で、カーソルがどのOriginalLine上にあるか判定しなければいけないということでしょうか。たとえば、 public void OriginalPanel#mouseClicked(MouseEvent me) {  Point p = me.getPoint();  <オリジナルイベントオブジェクト生成>  for (OriginalComponent c : components) {   // 当たり判定   if (c.contaions((double) p.x, (double)p.y) {    for(MouseIntersectListener l : c.listener) {     l.mouseClicked(オリジナルイベントオブジェクト);    }    break;//1つのコンポーネントに対してイベントを処理したら終わり   }  } }