- 締切済み
【java applet】他のクラスを呼び出して図形を描写するには
はじめまして。 非常に簡単なことで、申し訳ないのですが質問させていただきます。 アプレットをextendsしたAppクラスで 他のMakeImgクラスのインスタンス(mi)を 作成し、MakeImgクラスのペイントメソッドを 実行して、図形を描写したいのですが、 下記のプログラムではコンパイルできても 図形が描写されません。 ペイントメソッドは明示的に呼び出さなくても 呼ばれるはずなので図形を描いてくれてもよさそうなのですが。。。 どなたか詳しい方、同じような問題を経験した方がいらっしゃったらぜひ回答していただければと思います。 それではよろしくお願い致します。 ////////////////////////////////////////////// import java.applet.Applet; import java.awt.*; /* <applet code="App.class" width="300"height="300"> </applet> */ public class App extends Applet { MakeImg mi; public void init() { mi = new MakeImg(); } } class MakeImg { public void paint(Graphics g) { g.setColor(Color.white); g.fillRect(0 , 0 , 300 , 300); g.setColor(Color.black); g.drawString("test",40,30); } }
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- hrm_mmm
- ベストアンサー率63% (292/459)
java SDKがインストールされているなら、demo appletsのソースも入っているはずなので demo\applets\ArcTest\ArcTest.java ソースをじっくりと読まれることをお薦めします。 描画用クラスと、コントロールボタン用クラスが別になってます。
- kacchann
- ベストアンサー率58% (347/594)
こういうことは、できるわけです。 import java.awt.*; import java.awt.event.*; import java.applet.*; public class Demo extends Applet implements ActionListener{ int count;String s="";int x,y;A a=new A(); public void init(){ setLayout(new BorderLayout()); Button btn=new Button("start"); add(btn,"South"); btn.addActionListener(this); } public void update(Graphics g){paint(g);} public void paint(Graphics g){g.drawString(s,x,y);} public void actionPerformed(ActionEvent ae){ a.myPaint(""+count++,count*10,count*10); } class A{ /** *指定の位置に指定の文字を描画するメソッド */ public void myPaint(String ps,int px,int py){ s=ps;x=px;y=py;repaint(); } } }
- freedom560
- ベストアンサー率46% (80/173)
>Appletを実装したクラスから、図を描くためのクラスを必要に応じて呼び出すようなものにしたかったのです。 なるほど。本文からはちょっとわかりませんでしたが、題名まで読むとそんな感じですね。どうもすみません。 >Appクラス(Appならpaintできる)の中に入れてやっても画像は表示されません。 Appクラスの中にクラスを作ると、MakeImg.classというクラスファイルがApp$MakeImg.classというクラスファイルに変更するのですが、だからと言ってApp$MakeImgクラスがAppletをextendsするわけではないことに変わりはありません。というわけで、画像は表示されません。 >キャンバスを継承したオブジェクトを複数回呼んだ場合、呼んだ数だけ描写される訳ではないようです。 どんなコードを書いたのでしょうか?「オブジェクトを呼ぶ」とはオブジェクトをnewすること?それともオブジェクトのメソッドをcallすること?その辺りがちょっとよくわかりません・・
- hrm_mmm
- ベストアンサー率63% (292/459)
#1へのお礼 での、paintの挙動について http://wisdom.sakura.ne.jp/system/java/swing/swing8.html より引用 |描画する度に背景色でクリアするという仕様 なので、毎回0から書き直しと同じ状態になります。 java.awt.Imageかjava.awt.image.BufferedImageを用意して、こちらに描いてから、paint()では、このImageを表示用画面にコピーという方式をとる必要があります。
- freedom560
- ベストアンサー率46% (80/173)
MakeImgのpaintが呼ばれない理由はNo.1さんが書いているので・・ Applet(のサブクラス)のpaintが呼ばれるのはApplet(のサブクラス)自身のpaintメソッドです。決して、Applet(のサブクラス)が所有しているオブジェクトのpaintメソッドではありません。(もちろんサブクラスのpaintメソッドの中でオブジェクトのpaintを呼び出すという手はありますが) というわけで、Appクラスの中でpaintを実装しましょう。これでいけるはずです。(白と黒は面白くないので変えました) import java.applet.Applet; import java.awt.*; /* <applet code="App.class" width="300"height="300"> </applet> */ public class App extends Applet { App mi; public void init() { mi = new App(); } public void paint(Graphics g) { g.setColor(Color.cyan); g.fillRect(0 , 0 , 100 , 100); g.setColor(Color.red); g.drawString("test",40,30); } }
補足
アドバイスありがとうございます。 ですがこれですとAppはAppletをextensしていますので、paintは当然実行されます。 説明不足で大変申し訳なかったのですが、 「他のクラス(内部クラスでもOK)を呼び出して」 というのがやりたいことでして、 Appletを実装したクラスから、図を描くためのクラスを必要に応じて呼び出すようなものにしたかったのです。 No1さんのご指摘されたように、 MakeImgがpaintを実行するコンポーネントを 実装していないのが問題のようです。 例えば、 //////////////////////////////////////// import java.applet.Applet; import java.awt.*; /* <applet code="App.class" width="300"height="300"> </applet> */ public class App extends Applet { MakeImg mi; public void init() { mi = new MakeImg(); } class MakeImg { public void paint(Graphics g) { g.setColor(Color.white); g.fillRect(0 , 0 , 300 , 300); g.setColor(Color.black); g.drawString("test",40,30); } } } /////////////////////////////////////////// というように、Appクラス(Appならpaintできる) の中に入れてやっても画像は表示されません。 やはりMakeImgがCanvasなどをextendsしないと だめなのでしょうか。 勉強不足で申し訳ございませんが、 もしアドバイスがございましたら 頂ければと思います。
MakeImgは、何も継承していない(Object継承)のですか。ならば、何も表示されないと思いますが・・・。 少し勘違いされているようですが、paintメソッドが明示的に呼び出さなくても呼び出されるのは、そのクラスが「必要に応じてpaintメソッドを呼び出すことで描画を行う」という機能を備えていれば、です。そのためには、少なくともjava.awt.Componentを継承している必要があります。 MakeImgは何も継承していませんから、paintメソッドは呼ばれません。クラスにpaintメソッドを置けば勝手に描画してくれるわけではありません。「AWTのコンポーネントとして定義されていて、画面に表示されるコンテナに配置されて表示可能な状態になっていれば、AWTのシステムによって再描画の処理が行われるようになる」ということです。 とりあえず、以下の点についてどうすればいいか調べてみましょう。 ・MakeImgをCanvasかPanel継承クラスに変更する。(Canvas、Panelについて調べてみる) ・Appでは、new MakeImgした後、addでアプレットに組み込む。(addについて調べてみる) ・そのままではおそらく小さい部品として組み込まれてしまうので、Appのレイアウトマネージャを変更する。(レイアウトマネージャについて調べてみる)
お礼
アドバイスありがとうございます。 キャンバスをextendsする場合、 下記のような具合でやると描写されました。 ただひとつ(分からないことだらけですが) 質問なのですが、 キャンバスを継承したオブジェクトを複数回呼んだ場合、呼んだ数だけ描写される訳ではないようです。 (下記のプログラムに修正を加え、 2回MakeImgを呼んで、それぞれ違う引数を渡して 描写させても一つしか表示されなかったのです。) 例えば何個も図形をオブジェクトで描きたい場合も (1つのオブジェクトで1つの四角を描く、 座標は引数で渡すという具合) キャンバスで実行できるのでしょうか。 また何かよいアドバイスがございましたら ぜひよろしくお願いします。 ///////////////////////////////////////// import java.applet.Applet; import java.awt.*; /* <applet code="App.class" width="300"height="300"> </applet> */ public class App extends Applet { public void init() { MakeImg mk = new MakeImg(); mk.setSize(300,300); add(mk); } } class MakeImg extends Canvas { public void paint(Graphics g) { g.setColor(Color.blue); g.fillRect(0 , 0 , 100 , 100); g.setColor(Color.black); g.drawString("test",40,30); } }
お礼
返答が送れて申し訳ありません。 No.1さんのところにも書いた ソースとほとんど同じですが、 Canvasのインスタンスをmk1,mk2というふうに2つ 作っても、描かれるのは1つということです。 ただ書いていて思ったのですが、 同じサイズにセットしているので 上書きされてしまうからかもしれません。 勉強不足で問題点が共有できないところもありますが、 もう少し頑張ってみたいと思います。 色々ありがとうございました。 また何かいい方法があればよろしくお願い致します。 ///////////////////////////////////////// import java.applet.Applet; import java.awt.*; /* <applet code="App.class" width="300"height="300"> </applet> */ public class App extends Applet { public void init() { MakeImg mk1 = new MakeImg(); mk1.setSize(300,300); add(mk1); MakeImg mk2 = new MakeImg(); mk2.setSize(300,300); add(mk2); } } class MakeImg extends Canvas { public void paint(Graphics g) { g.setColor(Color.blue); g.fillRect(0 , 0 , 100 , 100); g.setColor(Color.black); g.drawString("test",40,30); } }