イベントリスナーのクラスの書きどころ

このQ&Aのポイント
  • イベントリスナーのクラスをどこに記述するのか、分からない初心者の質問です。
  • BaseFrameクラスのwindowOpened()内部クラスで基本動作を記述し、AFrameクラスとBFrameクラスから実現したいイベントリスナーのクラスを切り分ける方法が良いでしょう。
  • しかし、この方法ではコントロールとイベントの関連性が不透明になる可能性があるため、慎重に検討する必要があります。
回答を見る
  • ベストアンサー

イベントリスナーのクラスの書きどころ

まだまだ勉強したての超初心者で拙い質問ですが、宜しくお願い致します。 AWTのFrameクラスで参考書など何も無く勉強をしていたのですが、 イベントリスナーのクラスをどこに記述するのが一番良いのか、分かりません。 BaseFrameクラス、AFrameクラス、BFrameクラスが存在し、AFrame、BFrameはBaseFrameを継承しているとします。 windowOpened()の基本となる動作(「abc」という文字列を出力とする)はBaseFrameクラスの内部クラスに記述、 その後、AFrameクラスから実行されたFrameの場合は「abc」と出力された後に「def」と出力したい。 BFrameクラスから実行されたFrameの場合は「ghi」と出力された後に「abc」と出力したい。 とした時、AFrameクラスの方はAFrameの内部クラスで定義し、addWindowListener()により追加すれば実現出来たのですが、 BFrameクラスの場合は初めにBaseFrameクラスのwindowOpened()が実行されるので実現出来ません。 とすると、BaseFrameクラスにあるイベントリスナーの内部クラスから、 AFrame・BFrameクラスで実現したいイベントリスナーのクラスまで、 全てを完全に切り分けた方が良いのか?(切り分ければ可能だと思った) しかし、そうすると、他のコントロールについても同じ対応が必要であり、 コントロールとイベントの関連性が不透明化しないか?などと考えてしまい、 どうするのが一番か悩んでいます。どなたかご教示下さい。

  • Java
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • bgbg
  • ベストアンサー率53% (94/175)
回答No.1

BaseFrameクラスの動作は、 public void windowOpened(WindowEvent e){ foo(); // 基本となる動作を行うメソッド } protected void foo(){ System.out.println("abc"); } こういうような感じなのでしょうか。 ここでサブクラスの振る舞いを変えるには、foo()をオーバーライドすると良いでしょう。 AFrameでは、 protected void foo(){ super.foo(); // BaseFrameのfooが呼び出される System.out.println("def"); } BFrameでは protected void foo(){ System.out.println("ghi"); super.foo(); // BaseFrameのfooが呼び出される } というように処理を切り分けてメソッド化させると良いのではないでしょうか。

naktak
質問者

補足

やはり文章だけだと伝わりませんよね^^;文字数増やしてもらいたいです・・・。 現在、以下のようになっています。別に作りにはこだわっていません。 【BaseFrame】 public class BaseFrame extends Frame { //コンストラクタ public BaseFrame() { addWindowListener(new eventWindowListener()); } //ウィンドウイベント protected class eventWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } public void windowOpened(WindowEvent e) { System.out.println("abc"); } } } 【AFrame】 public class CoreFrame extends BaseFrame { //コンストラクタ public CoreFrame() { super(); setSize(150, 150); addWindowListener(new eventWindowListener()); } protected class eventWindowListener extends WindowAdapter { public void windowOpened(WindowEvent e) { System.out.println("def"); } } } BFrameについては途中でこの作りだとダメだという事に気付いたので、作っていません。 そして、この作りだと、なんか美しくない気もします・・・。イベントリスナーの内部クラス部だけ継承とか無視してますし。 やはり仰る通り、コントロールとイベントを完全に切り分けるのが良いのでしょうか? やりたい事は、『ベースとなる基本的な動作が存在し、継承先は基本的にそれを利用して足りない所は個々で補うが、 場合によってはベースとなる基本的な動作が実行される前に実行したい処理があった時にも対応したい』のです。 なので、仰る方法のようにベースになる処理をいつ呼ぶか、を制御したいのですが、 切り分けが大きくなると、Frameクラス自体と、イベントリスナークラスが完全に切り分けられ、 どのFrameクラスでどのイベントリスナークラスを使っているのか追えなくなってくるのか?などと思ってしまいました。 試してはいませんーー^^;

その他の回答 (1)

  • bgbg
  • ベストアンサー率53% (94/175)
回答No.2

仰るとおり、イベントとコントロールの処理は切り分けた方がいいです。 イベントリスナーをサブクラスにしていると切り分けが難しくなるかもしれません。 なので、WindowAdapterクラスは使わず、FrameにWindowListenerをimplementsさせたほうが いいかと思います(誤解を承知で書きますがWindowAdapterはイベント処理を手抜きするためのクラスです) そうすればイベントリスナーとFrameが一体になりますし、サブクラスにイベントリスナーの 追加処理を書くこともないのでコードの分散化も防ぐことができるでしょう。 public class BaseFrame extends Frame implements WindowListener{ //コンストラクタ public BaseFrame() { addWindowListener(this); } public void windowOpened(WindowEvent e){ ... } ... }

naktak
質問者

お礼

あ、なるほど。WindowListenerを利用すれば何の問題もなく すっきりと解決できますね^^ ありがとうございました。

関連するQ&A

  • イベントとリスナーに関すること

     Javaの初心者です。AWTについてご質問します。 処理をしたい手順として (1) したい処理の手順の選択(Aの処理か、Bの処理か、のように)をRadio Button で選択し (2) データの入力(Aの処理に対するデータ、Bの処理に対するデータ、の入力)を行い (3) それぞれの処理の実行と結果の表示、これをButton で促す。 の手順でプログラムを行いたいのです。((1)と(2)を逆にすれば実行できることは確認しましたが、何とか自然な形でということで上記の手順で行いたいのです。)  私の作ったプログラムではリスナーの中から内部クラスで定義された別のリスナーを呼び出すという形になってしまいます。これではだめらしいのです。呼び出し側で、その内部クラスの生成を行った後、実行のためのメソッドにはenableを使ってしまいました。どのメソッドを添えたらよいのかわからなくて苦し紛れに使いました。 内部クラスの初期設定の部分までは実行されているのですが、イベントハンドラであるactionPerformedの中で書かれた命令は実行されていません。 AWTに堪能な方、お時間を煩わせて申し訳ありませんが、お教えくださいますようお願い申し上げます。

    • ベストアンサー
    • Java
  • リスナについて

    Java を勉強している者です GUIライブラリである awt,swing のリスナについての質問です awt,swing では リスナというイベント処理用のクラスと処理内容を用意して その部品に、イベント用のリスナを登録することによって、コールバックする仕組みになっていると思います。 リスナとイベントの対応ですが、マウスリスナやキーリスナ、ボタンを押したときに対応するアクションリスナ などがありますが、多用する再描画に関しての paintListener がありません 再描画に対応する場合、常に部品を継承して、paintcomponent をオーバーライドして記述しなければなりません 再描画も重要なイベントだと思うのですがなぜリスナが用意されてないのか。 JFrame j = new JFrame(); j.addPaintListener( new PaintAdapter { void onPaint() { ... } } のように描画処理を後付できないかという質問です。 できるようならサンプルのコードを教えてください。 またpaintリスナが用意されない理由があればこれも教えていただけると幸いです。

    • ベストアンサー
    • Java
  • イベントリスナーの重複登録について

    ひとつのエレメントに複数のイベントリスナーを登録した場合、各々のイベントはマルチタスクで動作するのでしょうか? こちらでテストしてみたところ、先に登録されたイベントの動作途中で後のイベントの動作にジャンプしてしまっているような挙動が見られましたが、たまたまでしょうか? この際エラーは特に出ていないようでした。 よろしくお願いします。

  • イベントリスナーがうまくいかない

    delBtnがない場合にイベントリスナーを読み込むとエラーが出てその後の処理が行われないため 下記のようにあった場合のみ予約するようにしたところ今度はクリックしても実行されない問題が起きました。 読み込み時は、エラーにならないようにし、かつボタンを押したときに要素を削除するようにするにはどうしたらよいでしょうか? var Result = document.getElementsByClassName('Result')[0].innerHTML = '<span class="u-mr-1rem">あああああ</span><input id="DelBtn" type="button" value="削除">; var Result = document.createElement('p'); BtnWrap.appendChild(Result); Result.classList.add('Result u-mtb-1rem'); var delBtn = document.getElementById('DelBtn'); if(delBtn !== null) { delBtn.addEventListener('click', function() { document.getElementsByClassName('Result')[0].remove(); }); }

  • SWTのイベント発生

    (質問) SWINGではなくSWTで自作のEVENT発生のプログラムを作りたい場合どのように記述すればよいのでしょうか。SWTでEVENTなどを継承しようとするとエラーになります。 SWTはSWINGに比べてサイトも少なく参考になりそうなところが探し出せませんでした。ご存知の方がおられましたら 教えていただけないでしょうか。 やりたいことはあるクラスからリスナーを登録してイベントの発生を知ることが出来ればいいのですが。

  • カスタムクラス内でURLLoaderへ登録したイベントリスナー関数が呼ばれない

    表題のように package{ import flash.events.*; import flash.net.*; import flash.utils.*; class myclass{ private loader:URLLoader; public function myclass(){} public function do():void { loader = new URLLoader(); loader.dataFormat = URLLoaderDataFormat.VARIABLES; loader.load(new URLRequest("test.php")); loader.addEventListener( Event.COMPLETE, handleComp ); } private function handleComp(event:Event):void { //呼ばれない } } } といったようなクラスを作ったとして、上のクラスでのdo関数を呼んだ場合にloaderに追加したイベントハンドラが実行されません。

    • ベストアンサー
    • Flash
  • クラスから自分のオブジェクトを操作するには

    高橋麻奈著の「やさしいJava」を買って、Javaプログラミングをはじめたのですが、どうしても分からないことがあるので質問させてください。 次のようなコードがあります。 class Abc{  public static void main(String arg[]){   Def de = new Def();   de.object_null();   Def de2 = new Def();   de2.object_null();   Ghi gh = new Ghi();   gh.object_null();  } } class Def{  int d,e,f;  Abc abc;  Def(Abc a,int i1,int i2){   //略  }  public void object_null(Abc a){   abc = a;   abc.de = null;  } } class Ghi extends Def{  Ghi(Abc a,int i1,int i2){   super(a,i1,i2);  } } Defクラス側から自分自身のクラス変数deをnullにする場合、public void object_null()メソッドのような方法でクラス変数を指定してnullにしていました。 しかし、この場合、クラス変数de2のobject_null()メソッドではde2をnullできないし、 サブクラスGhiから、クラス変数ghをnullにする場合も、クラス変数deを指定してしまいます。 クラス側から自分自身のクラス変数を指定する良い方法を教えてください。 よろしくお願いします。 #ここは半角スペース無効なんですね(^^;

    • ベストアンサー
    • Java
  • Ajaxによる非同期通信のイベントリスナ

    JavaScriptで以下の関数を実行した場合、(1)の実行後関数を抜けるので、 (2)のイベントリスナは(1)の実行後も呼ばれることはあるのでしょうか。    function hoge(){     var xhr = new XMLHttpRequest();     xhr.open("GET","http://www.example.com/data.txt");     xhr.onreadystatechange = function(){ //(2)      if(xhr.readyState == 4 && xhr.status == 200){       $("#foo").html(xhr.responseText);      }     }     xhr.send(null); //(1)    } ローカル変数xhrは、関数を抜けたら変数とその領域が解放されるので、 XMLHttpRequestインスタンスも消滅する、そして、インスタンスが 消滅してしまうと、onreadystatechangeプロパティも消滅すると思っ たためです。 (2)が(1)の実行後も呼ばれるとしたら、どのような仕組になっていると 理解すればよいのでしょうか。

  • Label を リスナーと結びつける方法

    フレーム上に (ボタンやリストやチェックボックスではなくて) ラベルを用いて、ラベルを押すことにより 背景が変わるプログラムを作りたいのですが どのようにイベント処理すれば、うまくいくのでしょうか。 プログラムは以下のように作りましたがイベントリスナを どのように加えればいいのかがわかりません>< よろしくお願いしますm(_ _)m import java.awt.*; import java.awt.event.*; public class Test{ public static void main(String args[]){ MyFrame f=new MyFrame("Test"); f.setVisible(true); } } class MyFrame extends Frame{ Label red, green, blue; MyFrame(String s){ super(s); setSize(200,200); setLocation(100,150); setLayout(new FlowLayout(FlowLayout.CENTER)); add(red=new Label("■")); red.setForeground(Color.red); add(green=new Label("■")); green.setForeground(Color.green); add(blue=new Label("■")); blue.setForeground(Color.blue); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); } }

    • ベストアンサー
    • Java
  • AS3でのマウスイベント受け渡しについて

    Actionscript3についての質問です。 どちらもSpriteクラスの親オブジェクトと子オブジェクトがあり、 ・MOUSE_OVERとMOUSE_OUTは親オブジェクトのイベントリスナーに処理をさせたい(子のaddやremoveを行うので)。 ・CLICKは子オブジェクトのリスナーに処理させたい。 という場合、どのように記述すればよいのでしょうか。 今のところ、子はmouseEnabledをfalseにして、親のクリックイベント処理でマウス座標からどの子がクリックされたのか(子は複数あります)を切り分ける方法しか思いつきません。 しかし、子が単純な形ではないのでこの方法では厳しいです。 他に何か良い方法は無いでしょうか。

    • ベストアンサー
    • Flash

専門家に質問してみよう