- ベストアンサー
JavaでjPanelに描画する方法
- Java言語でjPanelを使用して図形を描画する方法について教えてください。
- jPanelを使ってプログラム内から図形を描画するための関数を作成しましたが、うまくいきません。
- ゲーム作成の課題で詰まっているので、jPanelの使い方について詳しく教えていただけませんか。
- みんなの回答 (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/swing/JComponent.html#paintComponent(java.awt.Graphics) 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メソットとなります。同時に定義することができる全く違うメソッドになってしまうので注意が必要です(多相性といいます)。
その他の回答 (2)
- hirotn
- ベストアンサー率59% (147/246)
public void paintComponent(Graphics g){ g.setColor(new Color(0,0,255)); g.drawOval(100,100,50,50); } ではダメでしょうか? 以下ご参考です。 http://okwave.jp/qa/q810010.html
お礼
御回答有り難うございます。 それはやってみたのですが、全く描画されずここに質問させていただいております。 取り敢えず参考ページの方を拝見させて頂きます。 個人的意見 public void paintComponent(Graphics g){ g.setColor(new Color(0,0,255)); g.drawOval(100,100,50,50); } はよく見るカタチのサンプルですが、これは呼びださなくてもjFrameだけなら描画されていることがないですかね?^^; 引数に何を渡しているのか、それはどうやって取得するのか…… その辺りもまだわかっていません。 5年間手続き型を触ってきたので、いまいち慣れていなくて……
- Tacosan
- ベストアンサー率23% (3656/15482)
プログラム全体はどうなっていて, そしてなにがどう「うまくいかない」のですか?
お礼
御回答有り難うございます。 プログラム全体はあまり公開したくないので、一部だけですが。 コンストラクタで画面を定義します。 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上に線を引きそこをゲーム板としたいのです。 よろしくお願いします
補足
「何がうまくいかないのか」という点については、ハンドルの取得についてです。 オブジェクト指向ではインスタンスというのでしょうか。 jPanelと言うものは私の中では「ウインドウ」の一部だと思っています。 つまり、生成された時に何らかのアドレス(ハンドル)が生成されていると考えています。 そのハンドルを取得できている(※1)にもかかわらず、なぜ線が描画されないかということがわかりません。 (※1)System.out.printlnでnullpointerが返ってきていないのでそう判断 Javaにはデバイスコンテキストという概念が表に出ていないと聴きました。 では、どのように画像や線を描画し、アニメーションさせるのかを今しらべています。 申し訳ありませんが、ご教授の方お願い致します。
お礼
遅くなりました! ありがとうございます!! 何とか課題を提出するところまで持って行けました!! 手続き型でやってきたので、なかなか慣れることが難しかったので、本当に助かりました。