• ベストアンサー

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

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

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

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

  • ベストアンサー
  • kacchann
  • ベストアンサー率58% (347/594)
回答No.4

#3です。 こういうコーディングならいけますが…  Button _btn;//計算ボタン    public void itemStateChanged(ItemEvent e) {    clearListners();//計算ボタンに登録されてるリスナーを全削除   String s = ((Checkbox)e.getItemSelectable()).getLabel();      //ラジオボタンに対応したリスナーを、計算ボタンに登録   if ("正方形".equals(s)) {    _btn.addActionListener(new CalcA());   } else if ("長方形".equals(s)) {    _btn.addActionListener(new CalcB());   }  }    void clearListners() {   ActionListener[] arr = (ActionListener[])_btn.getListeners(ActionListener.class);   for (int i = 0; i < arr.length; i++) {    _btn.removeActionListener(arr[i]);   }  }      class CalcA implements ActionListener {   public void actionPerformed(ActionEvent e) {    System.out.println("正方形の計算");   }  }    class CalcB implements ActionListener {   public void actionPerformed(ActionEvent e) {    System.out.println("長方形の計算");   }  }

hiroshi2
質問者

お礼

 アドバイス誠にありがとうございました。私がこの1ヶ月余りかけて10冊以上の本を読み、サイトの過去ログなどを見せて頂いたりして解決できなかった問題が一気に解決いたしました。お礼の言葉もありません。 1 「質問者の望んでいるコーディングはおそらく不可能」というお言葉に目が覚めました。イベント処理というものの性質を理解していなかったことがよくわかりました。 「ラジオボタンの押下後フラグ値をセットし~」のところは今のところ理解できませんが 2 NO4でご指摘いただいた点についてはそのまま参考にさせていただきました。というよりも私のコーディングにそのまま追加させて頂いたら、すぐに結果が得られました。 (1)「計算ボタンに登録されているリスナーを全削除」とか (2)「ラジオボタンに対応したリスナーを計算ボタンに登録する」 などということは、私には思いもよらない手法でした。私も随分本を読みましたが書いてある本はなかったと思います。  世の中にはすごい方がおられるのだと改めて思いました。 取り急ぎご報告かたがたお礼申し上げます。

その他の回答 (3)

  • kacchann
  • ベストアンサー率58% (347/594)
回答No.3

質問者さんが望んでいるコーディングは おそらく不可能。 --- 仮に 「ラジオボタンが押された時」 を考えてみる。 人間がラジオボタンが押すと、 ただちにitemStateChanged()が呼ばれ、 ただちにそこに記述された処理をする。 ・・・だけ。 これ以外の処理はなんら行われない。 つまり public void itemStateChanged(ItemEvent e) {  do1();  do2();  new SomeClass();   } と書いてあれば、 ラジオボタンクリック後は、 単純にこの3行が、きわめて忠実に純粋に「実行」されて すぐにこのメソッドを終了する(抜ける)だけ。 つまりこのイベントハンドラitemStateChanged()内でどうやって 「次の『計算ボタン』が押下されたかどうかを『検知するしくみ』」 を記述しようというのか。 もしくは、仮にそれをやりたいなら、 このハンドラ内に、 「無限ループを使って、 常時イベントキューを監視する(イベント発生を検知する)ようなコード」 を自前で書くほかないのでは? つまり次のような擬似コード public void itemStateChanged(ItemEvent e) {  while(true) {   if (/*計算ボタン押下イベントが存在するなら*/) {    Event ee = getEvent();    actionPerformed(ee);    break;   }  } } みたいな…。 (※こんなJavaのソースコード見たことないけど) --- 普通は 前もってフラグを用意して ラジオボタン押下後、フラグ値をセットし これを以降の処理の分岐に利用する ようなソースコード書きますが… (または「stateパターン」)

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.2

すみません、質問だけでは状況がわからないので…。 何が問題になっているのか。文法か、AWTの仕様のことか…。 気になったのですが、 「リスナーの中の内部クラスで定義された別のリスナー」 とあるのですが、 これは内部クラスである必要があるのでしょうか?

hiroshi2
質問者

補足

 ご回答ありがとうございます。お時間を割いてくださいましたこと感謝いたします。 私が理解できていないのは、多分「AWTの仕様」のことだと思います。 「リスナーの中の内部クラスで定義された別のリスナー」の問題ですが、メソッドの中にイベントハンドラを置く試みもしてみたのですが、だめらしいのです。 つまり、イベントハンドはクラスの中にしか置けないと、私は理解しているのです。 本当は、プログラムをご覧頂けると早いのですが、短くしたつもりですが、100ステップ余りとなってしまいますのでここに提示することは許されないと思っています。 プログラムの概要は、run34rickyさんへの「補足」で述べましたので、ご覧いただけるとありがたいです。 再度のご支援をお願いいたします。

回答No.1

うーんと、 (1)→(2)はどうしたいのですか? ラジオボタンと入力欄は同じ画面にあるのですか?タブやカードレイアウトなどで別画面にあるのですか? 同じ画面ならば、ラジオの選択によって、入力欄の有効/無効を切り替えたいのですか? (3)の「促す」とは、なんですか? 「処理をしたい手順」の各項目の詳細を書いて頂けませんか?

hiroshi2
質問者

補足

 ご回答ありがとうございます。一緒に考えてくださる方がおられることで心が救われます。  作りたいプログラムはとても簡単なものですが、イベント処理の問題として捉えようとすると私には作れないのです。 (1) したい処理は(a)正方形と(b)長方形 の面積を求めることです。これをラジオボタンで選択したいのです。これにはイベントハンドラとしてitemStateChangedが必要になるのでしょう。 (2) この段階では(a)データの入力を実行するとともに、(b)対応する面積の計算をし、(c)結果をテキストエリアに表示する。 (2)の処理のきっかけとし,ボタンを使うことにします。このときイベントハンドラとして actionPerformed が必要になるものと理解しています。  私のプログラムは次のように作っています。  たとえば、正方形の面積を求めるという一連の処理は「正方形のラジオボタンを選択」したという処理の中で、(a)データの入力、(b)面積の計算、(c)結果の表示 という過程を経ます。この部分の処理は内部クラスを定義し、その中で actionPerformed によってボタンがクリックされたことを認識します。  ところがこのように処理すると actionPerformed の中で書かれた命令は実行されずに素通りしているようなのです。このことは、リスナーの中にリスナーを入れることはできないということを意味するのでしょうか、それともリスナーの実行のためのメソッドが不適切なのでしょうか。 ラジオボタン、テキストフィールド、テキストエリアは同一画面に置き、入力欄の有効/無効は切り替えたいと思います。 質問の(3)の「促す」の意味は(2)と(3)を一緒にして「実行する」の意味とご理解ください。 再度のご支援をお願いします。くれぐれも初心者ですのでよろしくお願いします。

関連するQ&A

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

    まだまだ勉強したての超初心者で拙い質問ですが、宜しくお願い致します。 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
  • アクションリスナー(初心者です)

    JAVAでボタンが押されたらすでに描かれている線に さらに線が加わって描かれるというプログラムを作ろうとしているのですが、アクションリスナーを受け取ったメソッドの中身をどうしたらいいのか行き詰まりました・・・作りかけのプログラムを載せてみますので アドバイスいただければと思います よろしくお願いします import java.applet.Applet; import java.awt.Graphics.*; import java.awt.event.*; import java.awt.*; public class file928 extends Applet implements ActionListener { Button botan; public void init() { botan=new Button("選択"); add(botan); botan.addActionListener(this); } public void paint(Graphics g) { g.drawString("L.A.Airport",100,300);           ~中略~ g.drawLine(405,420,655,240); } public void actionPerformed(ActionEvent x) { ーここをどうしたらいいかわかりません・・・ー } }

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

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

    • ベストアンサー
    • Java
  • JavaAppletのイベントの強制発生方法

    JavaAppletのイベント処理についてお伺いしたい事があります。 Appletで作成した画面にボタンAを設置し、 actionPerformedのイベントを作成しました。 private void ボタンA_actionPerformed (java.awt.event.ActionEvent ae) {   //処理内容 } ボタンAを押下すると上記のイベントが呼ばれ正常に動作するのですが、このイベント処理をボタンAを押下する以外の方法で呼び出す事は可能なのでしょうか? 下記内容は例として、ボタンBで[F1]が押されたらボタンAの押下処理を呼び出そうとしております。 private void ボタンB_keyPressed (java.awt.event.KeyEvent ke) {   java.awt.event.ActionEvent ae;   ae = ○○○○○○;   if (e.getKeyCode() == java.awt.event.KeyEvent.VK_F1) {     ボタンA_actionPerformed(ae);   } } java.awt.event.ActionEventで定義した変数aeの中身の所でつまづいております。 ご存知の方おりましたらご指導願います。

  • awtでGUIを作成しているのですがイベントリスナーのことで

    こんばんは。今awtでGUIを作成しています。 テキストフィールドを作成し、入力したあとエンタ―ボタンを押したら桁数チェックなどを行い、妥当な入力であればカーソルを次のテキストフィールドに移動させ、妥当でなければ警告のダイアログボックスをだすアクションリスナーをaddActionListenerで作っていたのですが、 入力を確定させるのは何もエンターキーだけではなく、人によってはタブキーとか次のテキストボックスを選択して確定する人もいるだろうと思い、addFocuslistenerも加えました。以下がその部分です。 field1.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent ae){ String gt_field1=field1.getText(); if(gt_field1.length()==5){keycheck();} else{Tyuui("無効な入力です","5桁の文字を入力してください。");} } } ); field1.addFocusListener( new FocusListener(){ public void focusLost(FocusEvent e){ String gt_field1=field1.getText(); if(gt_field1.length()==5){keycheck();} else{Tyuui("無効な入力です","5桁の文字を入力してください。");} } } ); しかしこのようにしたら、エンターキーを押した時、妥当な入力だったら次のテキストフィールドに移動させるようにしているので、Focuslistenerも反応し、もう一度同じ処理をしてしまいました。妥当な入力でないときは警告のダイアログが2回でてきました。 そこでaddActionListenerのほうにはなにも調べさせず、フォーカスをはずすだけにしたらどうかと思ったのですが、requestFocus()もありますが他のテキストフィールドにフォーカスを当てたらまたおかしな事になりそうなのでただフォーカスをはずし、どこにもフォーカスがあっていない状態にしたいのですが、いい方法とかございましたら教えてはいただけませんか。 またEnterキーを押しただけでなく、Tabキーを押したり、マウスで別のところをクリックしてフォーカスが外れた時も桁チェックなどを行い、妥当な桁なら次のテキストフィールドにフォーカスをあてるいい方法などございましたらアドバイスの方、おねがいします。

    • ベストアンサー
    • Java
  • JButton配列でのイベント処理

    JAVA初心者です。 ある、画面にボタン50個を作成しました。(JButtonの配列で作成しました。) そこで質問です。下記のコールバックメソッド(?)btnActionPerformedを50個分作成するのは 煩雑なので1つで処理しようと考えております。 for (int cnt=0; cnt<50; cnt++) { ... JButtonのインスタンス生成処理等 ... btn[cnt-1].addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnActionPerformed(evt); } }); } ... ... ... private void btnActionPerformed(java.awt.event.ActionEvent evt) { ... } btnActionPerformedで受け取ったevtパラメータから押されたボタンのプロパティ等 が判別つくのでしょうか?ActionEventクラスのヘルプを参照しましたが、 いまひとつ良くわかりません。 また、このevtパラメータを使う方法以外で、この様な事が実現できる方法が あれば教えてください。よろしくお願いします。

    • ベストアンサー
    • Java
  • Javaにおけるイベント処理

    JFrame  SpritPanel   SpritPanel    JPanel     JButton A     JButton B     JButton C    JList A   SpritPanel    JList B    JTable C という構成で、JButton A をクリックしたらJList AにJButton A用のなんらかのリストを表示し、JButton BをクリックしたらJList BにJButton B用のなんらかのリストを表示し、・・・ と1つGUI部品で発生するイベントで1つまたは複数のGUI部品の更新処理を行いたいのですが、イベントリスナをどこに実装させて、どこに更新処理を書くかで迷います。 例えば、押されるJButton Aにイベントリスナーのメソッドを実装し、そこで処理を書く場合はJList Aをこのメソッド内から見えるようにしなけなくて、それをするためにインスタンスを渡したりするのが面倒に感じています。 様々なGUI部品やパネルで構成され、イベントが起きたら複数のGUI部品が更新が必要となるようなGUIアプリケーションを作る場合、どのようにイベントを処理させるのが王道なのでしょうか。 うまく質問できないので、質問内容に不明な点があれば補足いたします。

    • ベストアンサー
    • Java
  • AWT Frameを利用するプログラムのmainメソッドを含むクラスについて

    AWTのFrameを継承してWindowプログラムを作成する際に、どんな書籍のサンプルプログラムを見ても、メインクラスがFrameを継承し、その中にmainメソッドが有って、そのmainメソッド内で自分自身のクラスのインスタンスを作成してshowする、といった事を定石のように行っています。 しかし私が思うに、mainメソッドなど含まずFrameを継承してWindow周りの処理を純粋に行うクラスを作成し、プログラムのメインとなるクラス内のmainメソッドからFrameを継承した別クラスのインスタンスを作成・showする方が、よほどスッキリして理解し易いような気がするのですが、どうなんでしょ? そういったサンプルプログラムを作成してみましたが問題なく動作します。ただそういう事をやっている他のサンプルソースが見当たらないので、何となく不安です(笑)

    • ベストアンサー
    • Java
  • 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
  • vb プログラムの起動と例外処理

    はじめまして プログラムの実行と例外処理に関して質問させていただきます。 現在,visual basic2005でプログラム(A)からvbで作成した別のプログラム(B)に引数を指定してから起動し,別のプログラム(B)が例外処理に関する方法を調べています。 プログラム(B)起動時に例外処理を用い,以下のようなエラーメッセージを表示させるにはどういった処理を構成すればよいでしょうか。 パス名が設定されていない場合,”ファイルのパス名が見つかりませんでした” 引数が指定されていない場合,”引数が指定されておりません” 原因が特定できないエラーが発生した場合,”原因不明のエラーが発生しました” プログラムの実行にはShellメソッドとSystem.Diagnostics.ProcessクラスのStartメソッドがあるという事がわかりましたが,上記2つのメソッドが自分の意図したい操作に適しているかまでは理解におよんでおりません。 まだプログラミングを始めたばかりという事もあり,右も左もわかりませんが,ご教授お願い致します。

専門家に質問してみよう