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

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

0

コンポーネントとグラフィクスの共存について

こんにちは。
この度は、レイヤードペインを用いて
パネルA,パネルB,パネルBに乗ったボタンを用意しました。
(パネルAよりもパネルBの方が深度が浅い)
そしてパネルAに
Graphics g = panelA.getGraphics();
g.drawImage(img , 0 , 0 , this);
のように画像を張り付けたところ、
パネルBの方が画像に隠れてしまったのです。
なお、上記の処理をしない場合はパネルA,Bは期待通りの
描画となりました。

実現したいのはこのように画像を張り付けても
コンポーネントとグラフィクスが共存できることです。

足りない要素があれば追記いたします。
何卒よろしくお願いします。

10

回答

6654

閲覧

10件の回答

評価

0

質問者です。
LabelとImageIconを用いることで
共存はできました。

直接パネルのグラフィックにImageを張り付けるのは
Javaとしては想定外なのでしょうか。

評価

10

「想定外」というのが何を意味してるかなんだけど。
ImageIconクラスでできて、自作クラスでできないのは何
でか、と考えてみる。
最終的には、画像はすべてGraphics経由で描画されている
はずだ。

評価

30

ImageIcon とおっしゃってますから Swing を想定して回答します。
JComponent のサブクラスでの getGraphics が想定外です。
paintComponent が呼び出された時その中で描画して下さい。

評価

10

swingでの描画の作法は基本的なところは同じだと思い
ます。

1)そのコンポーネント内に描画すべきものを
 コンポーネントに覚えさせる

2)描画がいつ必要なのかはswingのメカニズムの中で
 考えてくれて、さて必要となるとそのコンポーネント
 の描画メソッドを自動的に呼び出してくれる。
 よっていつ実際に描画すべきかをプログラマーが
 意識すべきでない。

3)実際の描画はswingのコンポーネントであれば
  paintComponentをオーバーライドしてそこに
  1)でコンポーネントに覚えさせている描画すべき
 もの(テキストなりイメージなり何なりと)を
 描画する処理を記述する。
 基本的な描画要素(線とか多角形とか文字列とか
 イメージとか)を描画するにはGraphicsオブジェクト
 に対して描画指示をだすが、paintComponentなど
 描画用のメソッドにはGraphicsが引数として
 わたってきているはずなのでそれをそのまま
 使えばよい。そのGraphicsは当該コンポーネント
 の描画を行うために最低限必要な状態に
 自動的にセットアップされています。
 例えばその時点のコンポーネントの大きさと位置に
 従い、コンポーネント領域外に描画しないように
 適切にクリッピングされています。

4)そのコンポーネントに描画させるべきものが
 変化したときは再描画が必要になったことを、
  repaintメソッドを呼び出すことで宣言する。

この作法はswingでGUIを実装するにあたり把握していな
いと色々とおかしな動きをするコードができてしまいま
す。GUIを初めようとする方はこのあたりの考え方を最
初に学ぶとよいと思います。
暇なのでちょっとだけ詳しい説明を記してみました。
GUIをやり始めた方の参考になれば幸いです。

評価

0

こんばんは、質問者です。
皆さんご回答有難うございました。
随分と返信が遅くなり申し訳ありません。
結局、間にJLabelを挟み、ImageをImageIconにしてラベルに張る形で現在対処しています。

皆さんのご回答を拝見し、誤解を招いてしまったのかと思いましたので先にお詫びを。
私がJPanelに描画を試みているのは
JPanelとレイヤードペインを用いて
描画領域を制限し新しい画面として考える
ということを試みているからです。
私が、無駄な要素を省ききれなかったせいかと思います。
申し訳ありませんでした。

>匿名さん
 想定外とはこの場合、swing使用者(私)が書くべきでないコードを書いているのではないか。ということです。

>仙人さん
 なるほどパネルは土台の板というイメージがあったのでこのようなコードを書いてみたのですが、想定外でありましたか。
paintComponentだと画面全体で1枚の描画先?になりませんか?
私がやりたかったのはJPanelによって画面を複数作れないか?ということだったのです。

>KSwordOfHasteさん
 仙人さんへの返信にも書きましたが、JPanelによって画面を複数作れないかという考えだったのです。

逆に私が誤解しているとお考えの方は、是非仰ってください。
私はJavaを初めてまだ日も浅く、GUIに至っては完全にド素人です。
SwingとAWTってなんだっけ?と調べながら皆さんのご回答を眺めていたほどです。

ご返信ありましたら、ぜひよろしくお願いします。

 

評価

30

Swing でのスーパークラスとしての「コンポーネント」は 
JComponent ですが、特殊な事を考えていなければ自前の
コンポーネントは JPanel でいいはずです。

paintComponent だと画面全体って、そうではありません。
JPanel 派生クラスの全体なだけです。
当然 JPanel の中に いくつもの JPanel 派生クラス を
レイアウトマネージャーで配置出来ます。

思い通りのレイアウトマネージャーがない場合は自前で作るか
null にしといて位置をほかの方法で設定でしょう。
ただ、その場合、もし画像をそのまま表示なら自前の
JPanel 派生クラスより JLabel の方がいいかもしれません。

評価

30

>仙人さんへの返信にも書きましたが、JPanelによって画
面を複数作れないかという考えだったのです。
>誤解を招いてしまったのかと思いましたので...
>JPanelとレイヤードペインを用いて描画領域を制限し新
しい画面として考えるということを試みているからです。

大丈夫、誤解はしていないと思います。しかし私の説明が
下手だったため仙人さんの金言を補足しようとした意図は
不発に終わったようですorz

仙人さんの金言とは「描画はpaintComponentでする」でし
てこの言葉を守っていれば物事は単純に進みます。守らな
いと最初の質問にあったようなおかしなことが起こりま
す。

評価

0

お二方、ご返信有難うございます。

つまり、使用するパネルの分だけ
JPanelを継承したクラスを作成し、
その作成されたクラスで[paintComponent]を各自オーバーライドする。
結果的にその描画領域が確立される?
ということですか?

(ほぼ勘の返信で申し訳ない)

評価

30

そう考えてかまいません。正確には JPanel のスーパークラス
JComponent を継承したクラスをいくつも用意すればいいのですが
JPanel に用意された機能が結構便利なためそのサブクラスでも
いいと思います。
ただ、無駄を究極に省きたいなら自前の JComponent のサブクラスを
用意して、そこにあなたに必要な共通機能を埋め込んで、その
サブクラスをたくさん作るという手もあります。

評価

0

こんにちは。質問者です。
皆さま、ご回答有難うございます。

>仙人さん
 おかげ様で、解りました。
 ここまでの詳しいご説明を有難うございました。
 
皆様のおかげで、Javaの考え方が増えて大変良い機会になりました。
これにて解決とさせていただきます。
本当にありがとうございました。

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