プロが教えるわが家の防犯対策術!

 アプレットで描画してもウィンドウをリサイズすると、描画が消えてしまいます。
 これのどこにrepaint()、update()、paint()を入れてやれば良いのでしょうか。
 
 本格的にプログラムの勉強をしようと考えているのですが、大阪、京都付近でjava、cとかを(出来れば個人教授のような
感じで)教えてくれる、スクールをご存知でしたら是非教えて下さい。

____________________________________________________________

public class Q_Draw_Line extends Applet implements MouseListener , ActionListener
{
Graphics g;
Color col;
Button btnyellow;
int mode;
Button btncircle;
Button btndot;

public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}

public void init()
{
g = getGraphics();
btnyellow = new Button("黄");
this.add(btnyellow);
btnyellow.addActionListener(this);

btncircle = new Button("円");
this.add(btncircle);
btncircle.addActionListener(this);

btndot = new Button("点");
this.add(btndot);
btndot.addActionListener(this);

this.addMouseMotionListener
(
new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
int x = e.getX(); // X座標取得
int y = e.getY(); // Y座標取得
g.setColor(col);

switch(mode)
{
case 1 :
g.drawOval(x-20/2,y-20/2,20,20);break;
case 2 :
g.fillRect(x,y,5,5);break;
}
}
}
);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand() == "黄")
{
col = Color.yellow;
}
if (e.getActionCommand() == "円")
{
mode = 1;
}
if (e.getActionCommand() == "点")
{
mode = 2;
}
}
}

A 回答 (9件)

>________________________________________________


> public void mousePressed(mouseEvent e){
>x0=x=e.getX();
>y0=y=e.getY();
>repaint();
>}
>_________________________________________________
> これは、マウスをプレスして全く動かさなかったときには何も描かないと思うのですが、実際に実行してみると小さい点のような
>四角を描くのは何故でしょうか。
●サイズが1ピクセルの図形が描かれます。つまりそれは、“点”ですね。

>
> それと public void update(Graphics g)のメソッドの最後の行のdefault;はどのような意味でしょか。
●switch文は、case:の羅列の最後にdefault:を書くのが良いマナーです。このプログラムでは、default:の実行内容が何もありません。

> 試しにこれはコメントアウトしてやり、リサイズを実行すると小さい丸がwindow上に描けるだけです。
●default:の1行だけをコメントアウトしても、なにも変化はないはずですが…。たぶんそのときmodeが1になっていたのではないでしょうか。
    • good
    • 0
この回答へのお礼

 _ranco_さん、長々と丁重な回答、本当に有難う御座いました。
 何とかこのプログラムだけは理解することが出来ました。
 ところで、_ranco_さんの開設しているサイトはあるのでしょうか。
 あれば是非教えて下さい。

 この質問については、一区切りつけて締め切りにしたいと思います。
 ところで今後直接メールで色々と教えて頂くのは無理なのでしょうか。
 なんとかjavaの勉強は以後も続けて行きたいのですが。

お礼日時:2008/05/26 17:55

>  そもそも再描画のメカニズムが良く理解できていないのですが、リサイズされ


> た時には真っ白なキャンバスのようなものがwindowに描かれその上をpaintが絵
> を描いていくという方法ではないのでしょうか。
●プログラム中に白で塗りつぶしている箇所はありませんから、リサイズ後のアプレットの背景はデフォルトのバックグラウンドカラー、すなわちライトグレーです。リサイズ時には、まっさらな、なにもないウィンドウが描かれ、paint()が一度だけ呼ばれます。

>  リサイズのアクションがあった場合には、既に描かれている絵をイメージとし
> て記憶し、リサイズ後のwindowに再描画するという順序ではないのですか。
●そのとおりです。「記憶」はcomponentResized()メソッドの中でcimageの現内容を新たな大きなImageであるimgにコピーすることです。記憶は、自動的には行われません(この点が重要!)。あなたの最初のプログラムでは、記憶がないので、リサイズ後に元の描画は再現されません。paint()が新たに1回呼ばれて、円(など)が一つだけポツンと描かれます。paint()の中で描画をやっているからです。

>  他の本で調べるとどうもそのような記述があるのですが、
●どんな記述ですか?

> そもそもの再描画のメカニズムとはどのようなものでしょうか。
●リサイズされる時の再描画は、Javaが直接paint()を呼び出して行います。私が紹介した、Javaのpaintのメカニズムに関するドキュメンテーション(Amy Fowler著)を読めば、こんな基本的な質問をせずにすむはずです。再描画は、(1)システムが勝手に行うもの、と、(2)プログラムがrepaint()を呼び出してリクエストするもの、の2とおりあり、リサイズ時のウィンドウが徐々に拡大または縮小していく描画は(1)の部類です。

>  再描画を実行する場合のImageの役割のようなものが良く分かりません。
●Image cimageは、paint()の中でdrawImage()の引数になっているだけです。つまり上の(1)でも(2)でも、Image cimageは画面上に描画される内容そのものです。paint()が呼ばれればImage cimageの内容が表示される、それだけのことです。このプログラムにおけるImageの役割は、過去の描画の累積のメモリ(記憶装置)です。

> >そこで、昨日(5月16日)のプログラムでは、paint()の中での1回々々の
> 描画呼び
> >出し(drawOvalなど)をやめて、既製のイメージ(Imageオブジェクト)をdrawImage
> ()
> >で描画します。そして、図形の描画呼び出し(drawOvalなど)はそのイメージに
> 対し
> >て行います--update()の中でそれをやっています--。
> paintで実行する描画とdrawImageで実行する描画とはどう違うのでしょうか。
> drawImageでの描画のメリットはどのようなものでしょうか。
●paint()の中でdrawOval()等々で描画すると、「記憶」が残りません。update()をオーバライドして毎回のpaint()に際してのバックグラウンド塗りつぶしをやめさせ、残像を利用しても、リサイズ時にはフレッシュなウィンドウをシステムが描くので、その上には残像はありません。

>  update()の最後には、paint()文が書かれているので、毎回paint()が呼ば
> れてその都度描画していることにはならないのですか。
●repaint()から呼ばれるupdate()は、Imageの中に描画をして、最後にpaint()を呼び出します。paint()は、そのImageをdrawImage()するだけです。paint()の中には描画メソッドdrawOval()などの呼び出しは一切ありませんね。drawImage()のみです。

>  MouseDragged()の最後ではrepaint()が呼ばれていますが、そのあとupdate
> ()が呼ばれ描画しているのですか。
●update()は、必ずrepaint()から呼ばれて、いろいろ準備的なことをして、最後にpaint(g)を呼び出します。言い換えると、システムが自動的に行う再描画ではupdate()は呼ばれません。ですからリサイズ時にはpaint()だけが呼ばれるので、「記憶」がきわめて重要です。

>  リサイズ前の描画でも、repaint()から、update()、paint()が呼ばれて
> 描画しているのですか。
>  としたら、cimage=nullのときのcreateImageには何が入っているのですか。
●プログラムが行う再描画は、必ず、repaint()->update()->paint()の流れです。cimage==nullなら、cimageがまだ作られていないのでcreateImage()をコールして作ります(もちろん一回限りです)。createImage()は、まっさらのImageを作ります。
    • good
    • 0
この回答へのお礼

 _ranco_さん、丁重な回答有難う御座います。

 再度の質問ですが、
________________________________________________
 public void mousePressed(mouseEvent e){
x0=x=e.getX();
y0=y=e.getY();
repaint();
}
_________________________________________________
 これは、マウスをプレスして全く動かさなかったときには何も描かないと思うのですが、実際に実行してみると小さい点のような
四角を描くのは何故でしょうか。

 それと public void update(Graphics g)のメソッドの最後の行のdefault;はどのような意味でしょか。
 試しにこれはコメントアウトしてやり、リサイズを実行すると小さい丸がwindow上に描けるだけです。

 色々と他の本も読みましたが、この部分が理解出来ません、宜しくお願い致します。

お礼日時:2008/05/26 00:04

>  componentResized()は多分windowがリサイズされた時に呼ばれるのでしょう


> が、リサイズが元の画面より小さくなった時の
> if文の実行文が無いような気がするのですが、この時は何もしないでこのメッソ
> ドを抜けるということでしょうか。
>  それも解せないのですが。
●小さくなったときは、cimageに対して何もする必要がありません。cimageを小さくしたら、大きかったときの描画が削られてしまいます。

>  また、「if(newimg)」というような表記の仕方はあるのでしょうか、これは
> 何をチェックしているのでしょうか。
>  newimg==trueならという意味でしょうか。
●if(newimg)のような書き方は、Javaではふつうです。if (expr)のexprの値はbooleanタイプの値(つまりtrueまたはfalse)であれば何でもOKです。もちろん、関係演算子==, !=や、booleanを返すメソッドの呼び出しの結果も、booleanなのでif()の中に書けます。

>  ここでのiamgeの内容はリサイズ前の描画結果をcimageに保存ということでし
> ょうか。
>  全体の処理を見るとリサイズ後の真っ白いwindowというようにも思えるのです
> が。(resize後のgetBoundsの値をgetしているので)
●コメントで説明しましょう:
 public void componentResized(ComponentEvent e){
  int w, h;
  Image img;
  boolean newimg = false;

  //より大きなImageを作るべきか?
  Rectangle rec = getBounds(); //リサイズ後の現在サイズを取得します
  w = rec.width;
  h = rec.height;

  if (w > maxw){ //現在サイズの幅がそれまでの最大幅(maxw)より大きければ
   maxw = w; //maxwの値を更新し
   newimg = true; //フラグをtrueにセットします
  }
  if (h > maxh){ //現在サイズの高さがそれまでの最大高(maxh)より大きければ
   maxh = h; //maxhの値を更新し
   newimg = true; //フラグをtrueにセットします
  }
  if (newimg){ //(1)フラグがtrueなら、
   img = createImage(maxw, maxh); //新たに大きなImageを作り
   //(2)現在のImage(cimage)の内容を新たなImageへコピーし
   img.getGraphics().drawImage(cimage, 0, 0, this);
   cimage = img; //(3)cimageを新たなImageへと更新します
   /*以上は実際はif (w > maxw || h > maxh)とすればフラグなんか
   使わずに済みそうですが、maxwやmaxhの更新を分かりやすく書く
   ために、あえてフラグを使いました。
   */
   //この時点では、大きくなったcimageによるpaintは行われていないので
   //画面上にあるものは、もとの描画(リサイズ時にはpaint()が自動的に
   //呼ばれるので)+大きくなった部分のバックグラウンドだけです。
   //だれも、白い塗りつぶし + repaint()コールなどはやっていませんから、
   //真っ白になることはありえません。
  }
 }


>  次のupdate()メソッドは誰からどのような時に呼ばれるのですか。リサイズ
> が終わったら自動的に呼ばれるのですか。
●update()メソッドは、次回に呼ばれるrepaint()が呼び出します。repaint()以外のものがupdate()を呼び出すことはありえません。くどいようですが、私が紹介したAmy Fowler著のドキュメンテーションには、これらのことが明快に書かれています。Javaプログラミングでは、ドキュメンテーションの読破がきわめて重要です。読まないでこうやって質問ばかりしていると、質問への回答もよく理解できないでしょう。それは、悪循環です。
 次のupdate呼び出し時には画面だけでなくcimageも…componentResized()によって…リサイズされているので、マウスを使って、大きくなった部分への描画ができます。

>  Eventを引数にとってはいないようですが。
update()とEventはまったく無関係です。update()はrepaint()から呼ばれて、いろんな準備作業をして、最後にpaint(g)を呼び出すだけです。

>  また、getWidth、getHeightはローカル変数になっていますが、どこの座標値
> をとっているのですか。
>  リサイズ後のwindowサイズでしょうか。
●無修飾のメソッド呼び出しや変数アクセスは、暗黙に、this.で修飾されています。update()は必ずrepaint()が呼び出していて、しかもこのプログラムではrepaint()はマウスイベントを扱うメソッドだけが呼び出しています。ということは、マウスが次にpress/dragされるときには、すでにリサイズが終わっている==サイズはリサイズ後のサイズである、ことに気づいてください。

>  setColorの前にGraphics grをとっていますが、これは何故でしょうか。
●grは、ImageオブジェクトcimageのGraphicsです(この点を誤解しないように!)。ここではImageオブジェクトに対して描画するためにgr.setColor()やgr.drawLine()等々を呼び出します。そしてpaint()の内容は、単純にdrawImage(cimage)だけです。

>  actionPerformed()ではGraphicsをとっていないのですが、この違いはどう
> いう理由でしょうか。
●actionPerformed()はパラメータcolやmodeの値を変えているだけですから、それだけが仕事ですから、Graphicsを持っているオブジェクトはどこにもありませんし要りませんね。ここで行われたcolやmodeの値の変化は、次のrepaint()呼び出し->update()->paint()の実行により、実際に画面に反映します。


>  そして最後にpaint(g)でcimageを描画しているのですか。
●そうです。そうするのは、cimageの中に描画結果を保存して、リサイズ後の自動paint()によっても過去の描画を正しく表示するためです。以前のプログラムでは、リサイズ後の自動paint()では新たに図形が1個描かれるだけでしたね。
    • good
    • 0
この回答へのお礼

 _ranco_さん、再度の質問です、宜しくお願いします。

 そもそも再描画のメカニズムが良く理解できていないのですが、リサイズされた時には真っ白なキャンバスのようなものがwindowに描かれその上をpaintが絵を描いていくという方法ではないのでしょうか。

 リサイズのアクションがあった場合には、既に描かれている絵をイメージとして記憶し、リサイズ後のwindowに再描画するという順序ではないのですか。
 他の本で調べるとどうもそのような記述があるのですが、そもそもの再描画のメカニズムとはどのようなものでしょうか。
 再描画を実行する場合のImageの役割のようなものが良く分かりません。

>そこで、昨日(5月16日)のプログラムでは、paint()の中での1回々々の描画呼び
>出し(drawOvalなど)をやめて、既製のイメージ(Imageオブジェクト)をdrawImage()
>で描画します。そして、図形の描画呼び出し(drawOvalなど)はそのイメージに対し
>て行います--update()の中でそれをやっています--。

paintで実行する描画とdrawImageで実行する描画とはどう違うのでしょうか。
drawImageでの描画のメリットはどのようなものでしょうか。

 update()の最後には、paint()文が書かれているので、毎回paint()が呼ばれてその都度描画していることにはならないのですか。
 MouseDragged()の最後ではrepaint()が呼ばれていますが、そのあとupdate()が呼ばれ描画しているのですか。

 リサイズ前の描画でも、repaint()から、update()、paint()が呼ばれて描画しているのですか。
 としたら、cimage=nullのときのcreateImageには何が入っているのですか。

お礼日時:2008/05/22 00:10

> 私の場合はその都度drawOval、fillRectを呼んでるからでしょうか、


お答えはyesですが、しかしこの方法(getGraphics()からGraphicsオブジェクトを得るやり方)は、コンポーネント上の描画に関しては原則としてご法度です。この優れたFAQのQ3.4を読んでみてください(Javaはこのように、ネット上のドキュメンテーションが非常に充実しています)。http://homepage1.nifty.com/algafield/JavaGUIFaq1 …

> 最後には必ずrepaint()が必要なのですか。
paint()やpaintComponent()をオーバライドしている正しいプログラムでは、repaint()を呼び出して、コンポーネントに対して「あなたのpaint()やpaintComponent()を呼び出してください」とリクエストする必要があります。paint()やpaintComponent()はいわゆるコールバック(Java自身が呼び出すメソッド)なので、プログラムが直接呼び出してはいけません。

> 線の色、形状の選択していますが、次のステップでは何故
> paint()が呼ばれることになるのでしょうか、
actionPerformed()の中にはrepaint()の呼び出しがありませんから、次のステップでpaint()は呼ばれません。描画用のパラメータの値を変えているだけです。マウス関連のメソッドの中でrepaint()が呼ばれたときにやっと、色や形状の変更が画面に反映されます。

> どのコマンドがpaint()を呼んでいるのでしょうか。
マウスメソッドの中のrepaint()です。

> プログラム全体の流れがどうしてこの流れになるのかが分かりません。
でもこれは、あなたご自身が書いた流れですよ!。しかも正しいと思います。actionPerformed()の中でもrepaint()を呼んだらどんな結果になるか、実験してみてください。

> componentResizedの中のnewimgは何をするものですか、また、最初
> は何故falseでtrueに変わるのでしょうか。
newimgは、その名のとおり、「新しいImageを作らなければいけない」というサインです。このサインは、リサイズによってコンポーネントのサイズが前より大きくなっていたときだけ、trueにされます。デフォルトの状態はfalseです。

> この辺の所を詳しく解説している本がなく、理解に苦しんでいます。
さきに挙げたAmy Fowler女史の記事と、今回ご紹介したFAQを完全に読んでください。
paintの仕組みそのものは単純ですから、ぜひ、単純にすっきりと理解してください。
    • good
    • 0
この回答へのお礼

 _ranco_さん、相変わらずコードをながめています。

 componentResized()は多分windowがリサイズされた時に呼ばれるのでしょうが、リサイズが元の画面より小さくなった時の
if文の実行文が無いような気がするのですが、この時は何もしないでこのメッソドを抜けるということでしょうか。
 それも解せないのですが。

 また、「if(newimg)」というような表記の仕方はあるのでしょうか、これは何をチェックしているのでしょうか。
 newimg==trueならという意味でしょうか。
 
 ここでのiamgeの内容はリサイズ前の描画結果をcimageに保存ということでしょうか。
 全体の処理を見るとリサイズ後の真っ白いwindowというようにも思えるのですが。(resize後のgetBoundsの値をgetしているので)

 次のupdate()メソッドは誰からどのような時に呼ばれるのですか。リサイズが終わったら自動的に呼ばれるのですか。
 Eventを引数にとってはいないようですが。
 また、getWidth、getHeightはローカル変数になっていますが、どこの座標値をとっているのですか。
 リサイズ後のwindowサイズでしょうか。
 setColorの前にGraphics grをとっていますが、これは何故でしょうか。
 actionPerformed()ではGraphicsをとっていないのですが、この違いはどういう理由でしょうか。
 そして最後にpaint(g)でcimageを描画しているのですか。

 以上宜しくお願いします。

お礼日時:2008/05/20 01:48

> _ranco_さん、有難う御座いました、今日も本屋で色々とそれらしき本を探しましたが、全く見当たりません。

基本的な内容を書いている本は山ほど有るのですが、もっと踏み込んだ内容を、網羅している本がないのが不思議です。
●Javaのドキュメンテーションは、日本語の本よりもネット上の英語の記事が役に立ちます。JavaのGUIコンポーネントのpaintの仕組みは、前回の回答で示したURLにあるAmy Fowler氏(女性)の記事を読めばよく理解できます。

> もっと不思議なのは、もっと難しいプログラムを他の人はどのようにして勉強しているのかが全く不明です。(プロシジャ型のプログラム?なら何千行というプログラムも書いたことがあるのですが。。。)千差万別のアルゴリズム、プログラムをライブラリ、APIを参考にするだけで、Package、Interfaceを使いこなしているのですかね。
●Javaはとくにそうですが、最近の開発は、投じる時間とエネルギーの半分はドキュメンテーションを読むことに費やされるでしょう。昔と違って、高レベルなAPIをたくさん使いこなさないといけないからです。

> プログラムの基本、オブジェクト指向の基本を理解して、後はライブラリ、APIだけを参考にしてjavaが描けるとは、全く羨ましい限りです。(一体自分には何が足りないのか。。。)
●ほとんどの場合、足りないものはドキュメンテーション(および、既存の優れたサンプルコード)の読破経験です。つまり、頭の中の情報の在庫が足りない。

> ところで、もうひとつの質問ですが、同じようなプログラムを作っているのですが、そのプログラムは何故か、Windowをリサイズしても作図した絵は消えません、これは何故なんでしょうか。一体どこの書き方がどのように違うのか、全く理解出来ません。ということは、同じような書き方をすれば、リサイズしても消えないだろうと色々と比較しながら見てもそれさえもさっぱり分かりません。
●リサイズして消えるのは、update()をオーバライドして前回の描画結果を残像として残している場合です。このプログラムでも、単純にpaint(g)だけを呼ぶ(新規の背景塗りつぶしをしない)update()を書き加えて、コンパイル、実行(マウスをあちこちでクリックしてからリサイズする)してみてください。この実験は、そのことを理解できる良いチャンスですね。

 //これを新たに書き加えてみてください
 public void update(Graphics g){
  paint(g);
 }

(前回私が示したドキュメンテーションをよく読んでいれば、この疑問も、ひとに聞く前にご自分で答えが分かったはずです。Java==非常に充実した技術ドキュメンテーション群!!)
    • good
    • 0
この回答へのお礼

_ranco_さん、有難う御座います。
プログラムの内容について質問です。
mousePressed()とmouseDragged()についてはわかるのですが、このメッソドの最後には必ずrepaint()が必要なのですか。
私の描いたプログラムではwindow座標値をとってもrepaint()をとっていません、が走っています。
この辺の所を詳しく解説している本がなく、理解に苦しんでいます。
私の場合はその都度drawOval、fillRectを呼んでるからでしょうか、何故、必要、不必要なのでしょうか。

その後、_ranco_さんのプログラムでは、mousePressed()とmouseDragged()でイベントを呼び、actionPerformedで線の色、形状の選択していますが、次のステップでは何故paint()が呼ばれることになるのでしょうか、プログラム全体の流れがどうしてこの流れになるのかが分かりません。
どのコマンドがpaint()を呼んでいるのでしょうか。

componentResizedの中のnewimgは何をするものですか、また、最初は何故falseでtrueに変わるのでしょうか。 

お礼日時:2008/05/19 00:37

最初の回答で挙げた参考URLがGUI入門に関してはベストでしょう。


そのほか、Sunのサイトには多数の技術記事があります。
paintに関しては:http://java.sun.com/products/jfc/tsc/articles/pa …

> 内容は全くチンプンカンプンです
私の最初のプログラムでは、paint()の中でたった一度の描画をしているだけです。しかし、update()をオーバライドして、デフォルトのupdate()がやっている、バックグラウンドカラーによる毎回の塗りつぶしをやらないようにしているので、前回のpaint()の結果が次回もそのまま表示されます。そのため、連続描画が可能です。

ところが、リサイズをすると、新たなサイズのコンポーネントが新規に描画されるので、それまでの描画結果は当然残りません。新たなサイズのコンポーネントをpaint()したときの最初の円などだけが表示されます。

そこで、昨日(5月16日)のプログラムでは、paint()の中での1回々々の描画呼び出し(drawOvalなど)をやめて、既製のイメージ(Imageオブジェクト)をdrawImage()で描画します。そして、図形の描画呼び出し(drawOvalなど)はそのイメージに対して行います--update()の中でそれをやっています--。

そして、コンポーネントがより大きくリサイズされたら、Imageのサイズも大きくする必要があるので、それをcomponentResized()メソッドの中で行っています。--新たな大きなImageの中に、それまで使っていたImageの内容(=それまでの描画結果)をコピーしています。

以上の説明で、お分かりいただけたでしょうか?

この回答への補足

 _ranco_さん、有難う御座いました、今日も本屋で色々とそれらしき本を探しましたが、全く見当たりません。
 基本的な内容を書いている本は山ほど有るのですが、もっと踏み込んだ内容を、網羅している本がないのが不思議です。

 もっと不思議なのは、もっと難しいプログラムを他の人はどのようにして勉強しているのかが全く不明です。
(プロシジャ型のプログラム?なら何千行というプログラムも書いたことがあるのですが。。。)
 千差万別のアルゴリズム、プログラムをライブラリ、APIを参考にするだけで、Package、Interfaceを
使いこなしているのですかね。

 プログラムの基本、オブジェクト指向の基本を理解して、後はライブラリ、APIだけを参考にしてjavaが
描けるとは、全く羨ましい限りです。(一体自分には何が足りないのか。。。)

 ところで、もうひとつの質問ですが、同じようなプログラムを作っているのですが、そのプログラムは何故か、
Windowをリサイズしても作図した絵は消えません、これは何故なんでしょうか。

 一体どこの書き方がどのように違うのか、全く理解出来ません。
 ということは、同じような書き方をすれば、リサイズしても消えないだろうと色々と比較しながら見ても
それさえもさっぱり分かりません。

 宜しくお願いします。
_____________________________________________________
public class Applet_Demo_1 extends Applet implements MouseListener , ActionListener
{
int x1 ;
int y1 ;
int xh = 50 ;
int yv = 50 ;

Button bt1 ;
Button bt2 ;

public void actionPerformed(ActionEvent ae){}

public void init()
{
setBackground(Color.yellow);

addMouseListener(this);

bt1 = new Button("push");
bt1.setFont(new Font("SansSerif", Font.BOLD, 20));
bt1.setBackground(Color.black);
bt1.setForeground(Color.lightGray);
add(bt1);
bt1.addActionListener(this);

bt2 = new Button("change_circle");
add(bt2);
bt2.addActionListener(this);

}

public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}

public void mousePressed(MouseEvent e)
{
x1 = e.getX();
y1 = e.getY();
xh = e.getX();
yv = e.getY();

repaint();
}
/*
public void change_cod()
{
x1 = 400 ;
y1 = 400 ;
xh = x1/200 ;
yv = y1/200 ;

repaint() ;
}
*/
public void paint(Graphics g)
{
g.setColor(Color.red);
g.setFont(new Font("Serif",Font.BOLD,24));
g.drawString("Hello Applet World ! !" , 50 , 50);

g.setColor(Color.blue);
g.drawLine( 100 , 100 , 500 , 500);

g.setColor(Color.cyan);
g.fillOval( x1 , y1 , xh , yv);

g.setColor(Color.magenta);
g.fillRect( xh , yv, x1/10 , y1/10 );

}
}

補足日時:2008/05/18 00:28
    • good
    • 0

> Window画面をリサイズさせると、1個の○か1個の■しか残りません。


そうか。ごめんなさい、質問の真意を誤解してました。リサイズされたコンポーネントは、まったく新規に描かれたコンポーネントなので、表示されるのは最初のrepaint()の結果のみですね。残像は残りません。

リサイズ対策は、(1)Imageに描画結果を保存する(残像に頼らない) + (2)ComponentListener.componentResized()メソッドを実装する、という二面対策でかためてください。

その例が、以下のコードです:
----------------------------------------------------
/* rev 080516 */
/* > appletviewer QDrawLine.java */
/*
  <applet code="QDrawLine" width="600" height="600"></applet>
  */
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class QDrawLine extends Applet
implements MouseListener, MouseMotionListener,
       ActionListener, ComponentListener{
 Color col;
 Button btnyellow, btncircle, btndot;
 int mode, x0, y0, x, y, maxw, maxh;
 Image cimage;

 public void init(){
  col = Color.blue;

  btnyellow = new Button("黄");
  add(btnyellow);
  btnyellow.addActionListener(this);

  btncircle = new Button("円");
  add(btncircle);
  btncircle.addActionListener(this);

  btndot = new Button("点");
  add(btndot);
  btndot.addActionListener(this);

  addMouseListener(this);
  addMouseMotionListener(this);
  addComponentListener(this);

  Rectangle rec = getBounds();
  maxw = rec.width;
  maxh = rec.height;
 }

 public void mouseDragged(MouseEvent e){
  x0 = x;
  y0 = y;
  x = e.getX();
  y = e.getY();
  repaint();
 }

 public void mousePressed(MouseEvent e){
  x0 = x = e.getX();
  y0 = y = e.getY();
  repaint();
 }

 public void componentResized(ComponentEvent e){
  int w, h;
  Image img;
  boolean newimg = false;

  //より大きなImageを作るべきか?
  Rectangle rec = getBounds();
  w = rec.width;
  h = rec.height;

  if (w > maxw){
   maxw = w;
   newimg = true;
  }
  if (h > maxh){
   maxh = h;
   newimg = true;
  }
  if (newimg){
   img = createImage(maxw, maxh);
   img.getGraphics().drawImage(cimage, 0, 0, this);
   cimage = img;
  }
 }

 public void actionPerformed(ActionEvent e){
  Object o = e.getSource();

  if (o == btnyellow){
   if (col == Color.blue){
    col = Color.yellow;
   }
   else{
    col = Color.blue;
   }
  }
  else if (o == btncircle){
   mode = 1;
  }
  else if (o == btndot){
   if (mode == 2){
    mode = 0;
   }
   else{
    mode = 2;
   }
  }
 }

 public void mouseClicked(MouseEvent e){}
 public void mouseEntered(MouseEvent e){}
 public void mouseExited(MouseEvent e){}
 public void mouseReleased(MouseEvent e){}
 public void mouseMoved(MouseEvent e){}
 public void componentHidden(ComponentEvent e){}
 public void componentMoved(ComponentEvent e){}
 public void componentShown(ComponentEvent e){}

 public void update(Graphics g){
  int w = getWidth();
  int h = getHeight();
  if (cimage == null){
   cimage = createImage(w, h);
  }
  Graphics gr = cimage.getGraphics();
  gr.setColor(col);
  switch(mode){
   case 0:
    gr.drawLine(x0, y0, x, y);
    break;
   case 1 :
    gr.drawOval(x - 10, y - 10, 20, 20);
    break;
   case 2 :
    gr.fillRect(x , y, 5, 5);
    break;
   default:
  }
  paint(g);
 }

 public void paint(Graphics g){
  g.drawImage(cimage, 0, 0, this);
 }
}
-------------------------------------------------
    • good
    • 0
この回答へのお礼

 ranco_さん、有難う御座いました。

 しかし、内容は全くチンプンカンプンです、この内容が分かるサイト、解説をしているテキストなどはあるのでしょうか。

 もうかれこれ2年以上勉強していますが、所詮は本に書かれている内容をチマチマやっているだけで、このような
応用問題には全く歯が立ちません。

 実はスクールにも行きましたが、この手の高度?な内容にはのらりくらりの回答で全くラチがあきません。

 もっと踏みこんだ内容を習得したいのですが。。。。

お礼日時:2008/05/17 00:46

あ、もうひとつ、


JavaのStringを==や!=で比較してはいけません。

if (e.getActionCommand().equals("黄")){

のように書いてください。

実際には、アクションコマンドを明示的にセットしているアプリケーションもあるから、ボタンの上の文字列はその文字列を直接調べるのが、より正しいやり方です。アクションコマンド==ボタンの文字列であるのは、あくまでも、デフォルトのケースのみ。

(まあ、相当ひどい本を読んでんね、あなたは!)
    • good
    • 0

あなたは今、相当古くて、しかも内容の悪いJavaの本を読んでいますね。

関西のスクールについては知りませんが、Sunのチュートリアルをこつこつやっていくのが、ベストだと思いますよ。

以下、正しいコードの例です:
--------------------------------------------------
全角スペース->半角スペース2にしてください
/*
<applet code="QDrawLine" width="600" height="600"></applet>
*/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class QDrawLine extends Applet implements MouseListener , ActionListener{
 Graphics g;
 Color col;
 Button btnyellow;
 int mode, x0, y0, x, y;
 Button btncircle;
 Button btndot;

 public void mouseClicked(MouseEvent e){}
 public void mouseEntered(MouseEvent e){}
 public void mouseExited(MouseEvent e){}
 public void mouseReleased(MouseEvent e){}

 public void init(){
  // g = getGraphics(); // getGraphics()の使用は絶対に不可!
  btnyellow = new Button("黄");
  //this.add(btnyellow); // thisの中だからいちいちthisは要らん!
  add(btnyellow);
  btnyellow.addActionListener(this);

  btncircle = new Button("円");
  add(btncircle);
  btncircle.addActionListener(this);

  btndot = new Button("点");
  add(btndot);
  btndot.addActionListener(this);

  col = Color.blue;

  addMouseListener(this);
  addMouseMotionListener(new MouseMotionAdapter(){
   public void mouseDragged(MouseEvent e){
    x0 = x;
    y0 = y;
    x = e.getX(); // X座標取得
    y = e.getY(); // Y座標取得
    repaint();
   }
  });
 }

 public void mousePressed(MouseEvent e){
  x0 = x = e.getX();
  y0 = y = e.getY();
  repaint();
 }

 public void actionPerformed(ActionEvent e){
  if (e.getActionCommand() == "黄"){
   if (col == Color.blue){
    col = Color.yellow;
   }
   else{
    col = Color.blue;
   }
  }
  if (e.getActionCommand() == "円"){
   mode = 1;
  }
  if (e.getActionCommand() == "点"){
   if (mode == 2){
    mode = 0;
   }
   else{
    mode = 2;
   }
  }
 }

 //毎回の新規塗り替えを防ぐ==連続描画をする
 public void update(Graphics g){
  paint(g);
 }

 public void paint(Graphics g){
  g.setColor(col);

  switch(mode){
   case 0:
    g.drawLine(x0, y0, x, y);
    break;
   case 1 :
    g.drawOval(x - 10, y - 10, 20, 20);
    break;
   case 2 :
    g.fillRect(x , y, 5, 5);
    break;
   default:
  }
 }
}
------------------------------------

参考URL:http://java.sun.com/docs/books/tutorial/index.ht … http://java.sun.com/docs/books/tutorial/uiswing/ …
    • good
    • 0
この回答へのお礼

 ranco_さん、早速のレス有難う御座います。

 早速走らせてみましたが、Window画面をリサイズさせると、1個の○か1個の■しか残りません。

 Window画面に書かれたオブジェクトをリサイズ後もそのまま残すのは、難しいのでしょうか。
 どうもUpdate、Repaintを一体どこに書いてやればよいのか、どのような考えで挿入するのかがさっぱり分かりません。
 色々な本の読んではみるのですが、解説している本は見当たりません。
 宜しくお願いします。

お礼日時:2008/05/15 21:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!