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

お世話になっています。
Java言語を始め、オブジェクト指向というなれない環境にいます。(今まではBASICを利用)

今回、jPanelなるものを使い、その中に四角形などを描画したいのですが、
うまくいきません。

public void paintComponent(){
Graphics pnl = panel.getGraphics();
pnl.setColor(new Color(0,0,255));
pnl.drawOval(100,100,50,50);
}

こういう関数を作り、プログラムから呼び出しています。(フレーム作成時には表示しない)
おそらくこの辺りがダメだと思うのですが、よくわかりません。

すいませんが、jPanelの使い方を詳しく教えていただけないでしょうか。
ゲームを作る課題なのですが、ここで詰まってしまい進めません。

ご存じの方がいらっしゃいましたら、ご教授ください。
よろしくお願い致します。

A 回答 (3件)

このクラスの定義をざっくり書くと、



class Frame extends JFrame{
 Jpanel panel = new Jpanel(); //描画領域
 Jpanel label = nel Jpanel("得点");
 JButton btnNewButton = new JButton("ヘルプ");

 public Frame(){
  いろいろコンポーネントを追加...
  btn.newActionListener(this);
  this.setVisible(true);★
 }

 actionPerformed(ActionEvent e){
  this.repaint(); //自身のインスタンス(フレームを再描画)
 }
}

と推測しました。★のタイミングでpaintComponent(Graphics g)が呼び出されます。引数Graphics ???(なんでもよい)は必要です。描画が必要なタイミングでpaintComponentメソッドを呼び出します。詳しくは後述。

>はよく見るカタチのサンプルですが、これは呼びださなくてもjFrameだけなら描画されていることがないですかね?^^;
回答はJPanelを想定しております。
JFrameに対して、setVisible(true)した段階では、JPanelのpaintComponentのことまで構っていないように感じられますが、きちんと伝搬されます。 contentPane.add によってJpanelをJFrameに追加しているためです。

描画の際は、描画対象となるオブジェクトの情報がGraphicsクラスに入っているため、Graphicsのインスタンスを参照します。Graphics gならば"g"がインスタンスにあたります。

>引数に何を渡しているのか、それはどうやって取得するのか……
paintComponentの引数は(Graphics g)が必須だったと思います。
"paintComponent Java" をキーワードとして検索します。JComponentのクラスに関するドキュメントが得られます。クラスドキュメントを参照する限りでは、引数Graphics gは必須です。その他の条件のpaintComponentメソッドがここに記載されていないためです。

http://docs.oracle.com/javase/jp/6/api/javax/swi …
Jpanelじゃないの?という疑問が生まれると思いますが、前提をお読みください。

java.lang.Object
 └java.awt.Component ◎
  └java.awt.Container
    └javax.swing.JComponent ★
      └javax.swing.JPanel ☆

(前提)
1)お示ししたURLは★のJComponentですが、☆のJPanelから上位のクラスで定義されているメソッドを参照することができます。今回は継承と呼びます。
2)定義済みのメソッドをプログラマ自身が書き換えることができます。これをオーバーライドと言います。
3)特に定義しなくても★のpaintメソッドでpaintComponent(Graphics g)を呼ぶよう定義されているため、プログラマは、paintComponent(Graphics g)を定義すればよいことになります。

(重要)
・paintComponent(Graphics g)が発生するのは、イベントが発生して、FrameやPanelに描画の必要が生じた時です。例えばフレームの表示、サイズの変更が挙げられます。他にもあるかもしれませんが全てを把握しておりません。
JFrame.setVisible(true)を強調しているのは、これが発行されるまでJFrameに配置したコンポーネントのpaintComponentが呼ばれることがないためです。

paintComponent()と定義することはできますが、Javaは、paintComponent(Graphics g)に対して呼び出しをかけるので、定義されたメソッドは呼び出されないことになります。

プログラム上の処理が発生して、再描画が必要であれば、そのコンポーネントに対して、repaint()を起こすことになります。その延長でpaintComponent(Graphics g)が呼び出されます。repaintは◎で定義されているメソッドです。前提1に基づいて呼び出し可能となります。

>(※1)System.out.printlnでnullpointerが返ってきていないのでそう判断
これは再上位から「標準出力」をとっているだけなので、NullPointerは返りません。ハンドル(Javaではインスタンス)が取得できていることにはなりません。

>Javaにはデバイスコンテキストという概念が表に出ていないと聴きました。
インスタンスという概念で特定をします。
例えば、paintComponent(Graphics g)の場合、

paintComponentメソッドは、Graphicsクラスの gインスタンス(変数)を引数に持つ。という意味になります。デバイスハンドラやデバイスコンテキストはインスタンスになっているという認識で私はいます。
また、paintComponent()としてしまうと、引数を持たないpaintComponentメソットとなります。同時に定義することができる全く違うメソッドになってしまうので注意が必要です(多相性といいます)。
    • good
    • 0
この回答へのお礼

遅くなりました!
ありがとうございます!!
何とか課題を提出するところまで持って行けました!!

手続き型でやってきたので、なかなか慣れることが難しかったので、本当に助かりました。

お礼日時:2013/06/03 16:46

public void paintComponent(Graphics g){


 g.setColor(new Color(0,0,255));
 g.drawOval(100,100,50,50);
}
ではダメでしょうか?

以下ご参考です。
http://oshiete.goo.ne.jp/qa/810010.html
    • good
    • 0
この回答へのお礼

御回答有り難うございます。

それはやってみたのですが、全く描画されずここに質問させていただいております。
取り敢えず参考ページの方を拝見させて頂きます。


個人的意見
public void paintComponent(Graphics g){
 g.setColor(new Color(0,0,255));
 g.drawOval(100,100,50,50);
}
はよく見るカタチのサンプルですが、これは呼びださなくてもjFrameだけなら描画されていることがないですかね?^^;
引数に何を渡しているのか、それはどうやって取得するのか……
その辺りもまだわかっていません。

5年間手続き型を触ってきたので、いまいち慣れていなくて……

お礼日時:2013/05/10 15:17

プログラム全体はどうなっていて, そしてなにがどう「うまくいかない」のですか?

この回答への補足

「何がうまくいかないのか」という点については、ハンドルの取得についてです。
オブジェクト指向ではインスタンスというのでしょうか。

jPanelと言うものは私の中では「ウインドウ」の一部だと思っています。
つまり、生成された時に何らかのアドレス(ハンドル)が生成されていると考えています。

そのハンドルを取得できている(※1)にもかかわらず、なぜ線が描画されないかということがわかりません。
(※1)System.out.printlnでnullpointerが返ってきていないのでそう判断


Javaにはデバイスコンテキストという概念が表に出ていないと聴きました。
では、どのように画像や線を描画し、アニメーションさせるのかを今しらべています。
申し訳ありませんが、ご教授の方お願い致します。

補足日時:2013/05/10 15:14
    • good
    • 0
この回答へのお礼

御回答有り難うございます。

プログラム全体はあまり公開したくないので、一部だけですが。
コンストラクタで画面を定義します。
setResizable(false);
setTitle("課題");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);

//jPanel
panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBounds(5, 5, 600, 520);
contentPane.add(panel);

//得点表示(jLabel)
JLabel label = new JLabel("得点");
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setVerticalAlignment(SwingConstants.TOP);
label.setBounds(616, 16, 178, 178);
contentPane.add(label);

//お助けボタン(jButton)
JButton btnNewButton = new JButton("ヘルプ");
btnNewButton.setBounds(631, 460, 152, 70);
contentPane.add(btnNewButton);


こういった感じの、jPanel上に線を引きそこをゲーム板としたいのです。
よろしくお願いします

お礼日時:2013/05/10 15:08

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