• ベストアンサー

AppletのTextFieldとButton

TextFieldに値を入力して、Buttonをクリックするとその値が変数nに代入されるというソースを、どなたか教えていただけませんでしょうか? public void ABC extends Applet{ int n = 0; public void init(){ TextField tf = new TextField("0",5); Button btn = new Button("click!"); this.add(tf); this.add(btn); この後、actionなんちゃらメソッドやらクラスやらでどうにか値をnに入れた結果を実行させたいのですが、よくわかりません。よろしくお願いします。

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

  • ベストアンサー
  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.1

 Javaのイベントモデルはその原理さえわかってしまえば、意外と単純です。  たとえば、ボタンのActionEventを処理する場合は、まず、 1.ボタンにActionListenerインターフェースを装備したオブジェクトを登録する。 2.ボタンコンポーネントにActionEvent発生。 3.ボタンはActionListenerとして登録されているオブジェクトのactionPerformedメソッドを呼び出す。  これだけです。  登録するのはActionListenerインターフェースを装備したオブジェクトなら、何でいいです。  ActionListenerインターフェースを装備しているということは、actionPerformedメソッドを持っているということが保障されているので、ボタンは安心して、ただ、actionPerformedメソッドを呼べばよいというわけです。  やり方としては、大きくわけで、内部クラス使う場合とFrameやAppletを継承したクラスにActionListenerを装備させるという二つの方法があるように思います。  サンプルを作ってみましたが、コードをちょっと変更してボタンも二つにしてみました。 (コンパイルするときは全角スペースを半角スペースに変換してからにしてください。)  内部クラスを使う場合は、こんな感じ。↓ import java.applet.*; import java.awt.*; import java.awt.event.*; public class ABC extends Applet{   int n = 0;   int m = 0;      //↓コンポーネントはメンバ変数として保持しておくほうが後からアクセスしやすい。   TextField tf;   Button btnN;   Button btnM;   Label label;      public void init(){     tf = new TextField("0",5);          btnN = new Button("nに代入");     btnN.addActionListener(new BtnN_Clicked());          btnM = new Button("mに代入");     btnM.addActionListener(new BtnM_Clicked());          label = new Label("整数値を入れてください。");          this.add(tf);     this.add(btnN);     this.add(btnM);     this.add(label);   }      //イベントハンドラ用の内部クラス   private class BtnN_Clicked implements ActionListener {     public void actionPerformed(ActionEvent e) {       try {         String numString = tf.getText();         n = Integer.parseInt(numString);         label.setText("n = " + Integer.toString(n));       }       catch (NumberFormatException ex) {         tf.setText("0");         label.setText("整数値ではありません。");       }     }   }      private class BtnM_Clicked implements ActionListener {     public void actionPerformed(ActionEvent e) {       try {         String numString = tf.getText();         m = Integer.parseInt(numString);         label.setText("m = " + Integer.toString(m));       }       catch (NumberFormatException ex) {         tf.setText("0");         label.setText("整数値ではありません。");       }     }   } }  FramやAppletにActionListenerを装備させる方法はこんな感じでしょうか。↓ import java.applet.*; import java.awt.*; import java.awt.event.*; public class ABC extends Applet implements ActionListener {   int n = 0;   int m = 0;      //↓コンポーネントはメンバ変数として保持しておくほうが後からアクセスしやすい。   TextField tf;   Button btnN;   Button btnM;   Label label;      public void init(){     tf = new TextField("0",5);          btnN = new Button("nに代入");     btnN.addActionListener(this);          btnM = new Button("mに代入");     btnM.addActionListener(this);          label = new Label("整数値を入れてください。");          this.add(tf);     this.add(btnN);     this.add(btnM);     this.add(label);   }      public void actionPerformed(ActionEvent e) {     //二つのボタンが一つのメソッドを共有するので、場合わけが必要     Object source = e.getSource();     if (source == btnN) {       try {         String numString = tf.getText();         n = Integer.parseInt(numString);         label.setText("n = " + Integer.toString(n));       }       catch (NumberFormatException ex) {         tf.setText("0");         label.setText("整数値ではありません。");       }     }     else if (source == btnM) {       try {         String numString = tf.getText();         m = Integer.parseInt(numString);         label.setText("m = " + Integer.toString(m));       }       catch (NumberFormatException ex) {         tf.setText("0");         label.setText("整数値ではありません。");       }     }   } }

seagoo
質問者

お礼

 回答ありがとうございます!  内部クラスを使う方法でやってみたのですが、この場合paintメソッドはどこに置けばよいのでしょうか?  例えば、変数nの値をテキストフィールドから入力してボタンを押した後、drawLineで短線をnの数だけ書くというとき、 public void paint(Graphics g){ int i; for(i=0; i<n; i++){ g.drawLine(i, 0, i+0.5, 0); } } はPecoPlusさんのソースのどこに加えたらよいのでしょうか?BtnM_Clickedクラスのあとにポンと置いても、nの初期値にしか反応せず、テキストフィールドに3とか4とか入れてボタンを押しても変化が見られないのでまた困ってしまいました。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.3

 #1です。 >public void paint(Graphics g){ >  int i; >  for(i=0; i<n; i++){ >    g.drawLine(i, 0, i+0.5, 0); >  } >}  んー、このコードには間違いがありますねぇ。  コンパイルエラーが出るはずですが、どこが間違っているか探してみてください。  それと、yの値が0だと線が引かれても目立ちにくいので、とりあえずもうちょっとと下のほうがよいかと。  さて、コードを改良したとして、paintメソッドはどこにおいたらよいのでしょうか。  ここでは、アプレットの画面に描きたいのですから、Appletクラスを継承しているABCクラスに実装しなくてはいけません。  initメソッドと同じような形で書きます。  ここで、理解しておかないといけないのは、「ABCクラスにpaintメソッドを追加しているのではなく、上書き(オーバーライド)している」ということです。  ABCクラスにはAppletクラスから継承したpaintメソッドをもともと持っているということです。  Appletクラスのドキュメントを見てみると、 http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/applet/Applet.html  コンテナから継承しているpaintメソッドをそのまま使っているようです。  見てみると、 http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/awt/Container.html#paint(java.awt.Graphics) >軽量コンポーネントが正しく描画されるように >super.paint(g) を呼び出さなければなりません。  今回、軽量コンポーネントは使っていないようですが、これはつけておいたほうがよさそうです。  では、無事にpaintメソッドの改良とオーバーライドができたとします。  「これでバッチリ」と思ってボタンをクリックしても、線は描かれません。  「おかしいな」と思ってウィンドウのサイズを変更したり、最小化して元に戻したりすると、あら、今頃になって線が出てきました。  そもそもpaintメソッドはコンポーネントを描画する必要があるときにシステムによって呼び出されるメソッドです。  逆に言うとその必要があるまで、呼び出されません。  ウィンドウのサイズ変更や最小化から元に戻るときに再描画が必要となり、そこで初めて新しい画面に更新されたわけです。  しかし、そんな悠長なことを言っていられないので、ボタンを押したらすぐに再描画をしてほしいわけです。  そんなときは、repaintメソッドを使います。  どこで、どのオブジェクトのrepaintメソッドを呼べばよいかはもうおわかりですね。

seagoo
質問者

お礼

お蔭様で出来ました。 本当にありがとうございました。

すると、全ての回答が全文表示されます。
  • Bonjin
  • ベストアンサー率43% (418/971)
回答No.2

改造すると以下のようになります。(エラー処理はしてません) public void ABC extends Applet implements ActionListener{ int n = 0; TextField tf; Button btn; public void init(){ tf = new TextField("0",5); btn = new Button("click!"); btn.addActionListener(this); this.add(tf); this.add(btn); } public void actionPerformed(ActionEvent evt){ if(evt.getSource() == btn){ n = Integer.parseInt(tf.getText()); } } ちなみにちゃんと勉強する気があるのなら本の1冊や2冊は読んだ方が良いですよ。

seagoo
質問者

お礼

 回答ありがとうございました!  JAVAの入門書は一冊終わらしたのですが、AWTまで行ってなかったので(-.-;)これからもう一冊買うつもりです。

すると、全ての回答が全文表示されます。

関連するQ&A