Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

paint(Graphics g)の使われ方について

paint(Graphics g)の仕組みがいまいち理解できません
仕組みがわかりやすく解説されたウェブサイトやテキストはないでしょうか

理解できないのはpaintが具体的にどのように呼び出されているのかです
特に引数のgに何が入って呼び出されるのか教えて頂けないでしょうか
(具体的なpaint呼び出しのソースコードがあると嬉しいです)

調べているとうちに下記の質問を見つけました
http://www.javaroad.jp/bbs/answer.jsp?q_id=20100923220248513

この質問と近いことを疑問に思っているのですが上記のツリーでは話がずれていって知りたいことがわからずに終わってしまっていました

16

回答

7246

閲覧

16件の回答

評価

0

「話がずれていって」と感じているということは、君もその質問者と全く同じ状況なわけだ。
疑問がどうこうではなく、基礎ができてない、という意味でね。
例えば途中にあるサンプルコードはどう思うんだ。

評価

0

ありがとうございます

ちょっと質問を変えたいと思います
paintメソッドの引数gに入る具体的なGraphicsオブジェクトが確認できる呼び出し例はないでしょうか
一般的な話ではなくて具体的な一例が知りたいのです

> 例えば途中にあるサンプルコードはどう思うんだ。
途中にあるサンプルコードというのは抽象クラスのコードのことでしょか
その部分は理解できたと思います
例えばboolean equals(Object o) の話があったのですが
equalsの場合、解説本やサイトでは

String str1 = "abc";
String str2 = "cba";
str1.equals(str2)

のように呼び出し例もいっしょに解説してあるので
oに何が入るんだろうという疑問はないです
paintの場合は呼び出し例が見つからないのでgに何が入るんだろうと疑問に思います

上のequalsメソッドの呼び出し例のような
paintメソッドの呼び出し例を知りたいというのが質問です

評価

0

先のスレッドを、ちゃんと全部読んだのか?
「その時点での」実装クラスの確認方法なら2010-09-24 08:34:17にあるだろう。

断わっておくが、これはあくまで「その時点での」実装クラスだ。
インストール中のJREで実行する限り恐らく変わらないが、次のアップデート後に同じである保証はないし、別の環境に持って行って同じである保証もない。
同じく呼び出し側のコードが、ある環境でのある時点と同一である保証もない。
(オブジェクト指向において、それを保証する義務は誰にもない)

オブジェクト指向において重要なのは、「どのようなインターフェースであり、どんな機能か」ということだけだ。
逆に言えば、引数の実装クラスが気になるうちは、まともなプログラミングはできないということだ。
その感覚を身につけられるように、勉強する必要がある。

評価

0

つか、「質問を変えたい」と言ってる割には、実質何一つ変わってないな。

評価

0

ありがとうございます

> 「その時点での」実装クラスの確認方法なら2010-09-24 08:34:17にあるだろう。
getClass().getName()でわかるのは書かれている通りどの実装クラス(継承クラス?)のインスタンスかという情報でした
当たり前ですがどのような環境のどの時点でどういう風に生成されるのかはわかりませんでした

> 同じく呼び出し側のコードが、ある環境でのある時点と同一である保証もない。
すべての環境すべての時点の呼び出し側のコードが見たいのではなくて
あるひとつの具体例が知りたいのです

いろいろサイトを調べたり似たような質問の回答も見ましたが
引数のGraphicsオブジェクトがどう生成されているかわかるような
paintメソッドの具体的な呼び出し側のコード例は見つかりませんでした

すいません、自分の勉強の順番がまずかったのがわかりました
見方を変えてGraphicsの使い方を勉強したらなんとなく理解できたような気がします

getGraphicsというメソッドを使って描画したいオブジェクトのGraphicsオブジェクトを取得するのですね

aに線を描画したいときは
Graphics g = a.getGraphics();
g.drawLine(10,10,100,200);
という風にaのGraphicsオブジェクトを取得してそれに対してdrawLineを呼び出す

という流れがわかりました

ここからは想像なのですが
aオブジェクトに対するpaintメソッドの呼び出しは
Graphics g = a.getGraphics();
a.paint(g);
というようにa自身から取得されたGraphicsオブジェクトを引数にしてpaintが呼ばれるという理解であっているでしょうか

評価

0

Component#getGraphics()くらい見てみなさいって。
JDKならこの辺のソースは付いてるから。

評価

0

つーか Swing なら普通 paintComponent 使うし、paint 使ってるってことは AWT 使ってるの?
さすがに今AWTやる意味はどこにもないぞ…

評価

0

ありがとうございます

> Component#getGraphics()くらい見てみなさいって。

確認しました
残念ながらpaintメソッドの呼び出し例はありませんでしたが自分の理解があっていそうなことが確認できました

> つーか Swing なら普通 paintComponent 使うし、paint 使ってるってことは AWT 使ってるの?

参考にしているサイト(JavaDrive)でアプレットのプログラムの説明にpaintがでてきました
Appletのpaintなのでjava.awt.Containerのpaintです

paintを使っている側のソースコードを探し回った結果やっと見つけることができました

[javax.swing.JComponent]
    g = safelyGetGraphics(paintingComponent, c)
    paintingComponent.paint(g);

というような呼び出し例が見つかりました

このサイトで調べると一発でさがせました
http://grepcode.com

私の疑問だった引数のgに何が入ってpaintメソッドが呼び出されるかがわかる具体的なpaint呼び出しのソースコードが見つかりました

どうしてgに対してdrawLineをしたらそのアプレットに描画されるのか、その橋渡しの部分(gはアプレットから生成される)がわかりました

頂いた返信もヒントになり、これで私が抱いていた疑問は解消されましたので、この質問は終わりにしたいと思います

ありがとうございました

評価

0

>自分の理解があっていそうなことが確認できました
え、本当に…?

>paintを使っている側のソースコードを探し回った結果やっと見つけることができました
これはSwingのコンポーネントだ。
直接答えになってないぞ…。

それに、単にpaint()を「呼び出している」箇所であって、具体的に何が入るのかはここでは分からんだろう。
質問にあるスレッドでの、Listを使ったサンプルと何ら変わらないじゃないか。

>どうしてgに対してdrawLineをしたらそのアプレットに描画されるのか
先のスレッドと同じだが、この疑問は、そもそもオブジェクト指向が理解できていないことによって生じる。
その概念が掴めなければ、イベントハンドラ全てについて同様の疑問が生じるだろう。

評価

0

私の質問はpaintの具体的な呼び出され方とそのときのgに何が入っているかがわかる具体的な呼び出しのソースコードでした

具体的なpaintメソッドの呼び出しコード
  paintingComponent.paint(g);
で、gに入るオブジェクトがどう作られているか
    g = safelyGetGraphics(paintingComponent, c)
がわかるようなソースコードが見つかったので質問の直接の答えになっていると考えました

この例の場合は、具体的にpaintingComponentオブジェクトから作られたGraphicsオブジェクトがgに入ります
どうしてgに対してdrawLineをしたらpaintingComponentオブジェクトに描画されるのかというと
そのgはpaintingComponentオブジェクトから生成されたpaintingComponentオブジェクトの座標などの情報をもったGraphicsオブジェクトだから
という意味でpaintメソッドの仕組みが理解できたと思っています

ちょっと不安になってきたんですがこの理解でまちがっているのでしょうか

先のスレッドの質問者さんのことはわかりませんが私はあのListを使ったサンプルは理解できてると思います
しかしそれはpaintメソッドの仕組みの理解とは関係ないと思いました

評価

0

>それはpaintメソッドの仕組みの理解とは関係ないと思いました
ListでもGraphicsでも同じことなのに、それを読み取るだけの理解ができていないということだ。

評価

0

> ListでもGraphicsでも同じことなのに、それを読み取るだけの理解ができていないということだ。

同じことなのは抽象クラスを引数にしたメソッドという部分だと思いますが、私がわからなかったのはそのメソッドの使い方(具体的な呼び出し方)でした

あの質問のb(List a)の例では具体的にList a = new ArrayList()を作ってからb(a)を呼び出している例がありますが、paint(Graphics g)では具体的なgを作ってからpaint(g)をしている例がないのでわからなかったのです(今は具体例を見つけたので理解できてます)

すいません、読み返してみて1つわからないところがありました
> これはSwingのコンポーネントだ。
> 直接答えになってないぞ…。
Swingのコンポーネントだと何故答えにならないんでしょうか

評価

0

>gに入るオブジェクトがどう作られているか
だから、その疑問が出ることこそが、そもそも感覚が間違っていると何度も書かれている。
それは、paint()の実装者には関係のない話だというのに。
paint()は「どんなGraphicsの実装クラスが渡されても」、きちんと動作するように書くことだけを考えるんだよ。

>例がありますが
違う。見るべき点はそこではない。
あのサンプルのポイントは、ArrayListと、LinkedList、2つの具象クラスを用いた呼び出しがあるところだ。

あのサンプルを、メソッド側でadd()して、戻ったらSystem.out.println()するように変えてみる。
それなら今回同様、メソッドにとっては「引数のListにadd()したものが画面にprintされる」となるだろう。
渡される具象クラスが何だろうと同じようにprintされる。
それは各具象クラスが、それぞれの役割を果たすように実装しているからであり、その限りにおいて、具体的にどのような実装だろうと他には関係がない。

呼び出し前のどこかで、何らかの「メソッドを呼ばれれば実際の描画機能へ橋渡ししてくれる具象クラス」がnewされている、それだけでいいんだよ。

これが分からなければ、本当にこれから先やっていけないだろう。

評価

0

ありがとうございます

すいません、質問の仕方が悪かったと思っています
先の質問の質問者と似たような疑問と書いてしまったのがまずかったです
クラスの継承やオーバーライド等の話はわかっているつもりです
私が疑問だったのはもっと具体的なpaintメソッドのみに関する部分でした

a.equal(b)でaとbが等しいかどうか判定するという使い方をします
それがわかった上でequalメソッドの実装を書きます?
c.paint(g)の場合cとgという言葉を使って使い方の説明がなかったので疑問に思いました

> paint()は「どんなGraphicsの実装クラスが渡されても」、きちんと動作するように書くことだけを考えるんだよ。

それはそうなんですが、c.paint(g)と呼び出されたときにcと無関係のgが渡されることはないですよね

> 呼び出し前のどこかで、何らかの「メソッドを呼ばれれば実際の描画機能へ橋渡ししてくれる具象クラス」がnewされている、それだけでいいんだよ。

はい、まさにその通りです
ただ「実際の描画機能」というのが、どういう経緯でc.paint(g)のときの「cへの描画機能」となるのかが分からなかったのです(今は分かっています)
Graphicsオブジェクトgがどう作られるのかわからないので、なぜ無関係に見えるgに描画したらpaintメソッドが定義されているクラスのオブジェクトに描画されるのかが疑問でした

たぶん私の学ぶ順番が間違っていて、先にpaintとは別にGraphicsの使い方を学んで

Graphics g = this.getGraphics();
g.drawLine(10,10,10,10);
g.drawLine(20,20,20,20);

というように描画するという基本的な描画のやり方がわかった上で
後半部分をメソッドでまとめて

paint(Graphics g){
  g.drawLine(10,10,10,10);
  g.drawLine(20,20,20,20);
}

そのメソッドを使って

Graphics g = this.getGraphics();
paint(g);

となる
という勉強の順番だったら疑問は生じなかったと思います
この例だったらthisと結びついているgだから意味がわかりますし
描画が必要になったとき、同様にそのアプレットからgを作ってpaint(g)が呼び出されるのだろうなということが理解できたと思います

評価

0

>それがわかった上でequalメソッドの実装を書きます?
この?は文字化けだろうか。
equals()はそういう使い方をされると分かった上で実装するものだが。

>というように描画するという基本的な描画のやり方がわかった上で
つまり、「Graphics」がどういうクラスなのかを、とくに調べることなくpaint()の質問していたんだろうか?
であれば、やはり概念の有無に思えるな。

「クラスの継承やオーバーライド等の話はわかっているつもり」

が本当に「つもり」ということだが。
オブジェクト、I/Fという意識が薄いことで、継承やオーバーライドがそれを実現するための仕組みという捉え方をしていないので、クラスではなくメソッドに拘泥しているんじゃないのか。

評価

0

はい、その点は申し訳ないです
私が参考にしていた入門サイトではいきなり(Graphicsを使った基本的な描画のやり方の前に)paint(Graphics g)が出てきて、Graphicsはなんかうまいこと描画してくれる便利なものという説明で、よく仕組みがわからないまま話が進んでいくので質問した次第です

参考にしていたのはJavaDriveの「Applet入門」ですが
例えばCodeZineの「グラフィックの描画」のような説明を先に読んでおくべきでした

ありがとうございました

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。