• 締切済み

javaの描画関係のプログラムの考え方について

昔からあるJavaの基本的なグラフィックスのプログラム(下方のサンプル)の構造の基本についてお尋ねします。 プログラムの構成を言葉で言うなら、 1 クラスの設定 2 クラス内部のメソッドの作成(コンストラクタ、paint, main) (mainはメソッドとは言わないかもしれませんが、クラスの中の実働部隊のトップということでそういう位置づけにしました。) ここで疑問ですが、 疑問1 paintメソッドですが、どのようにして呼ばれていると考えるのでしょうか。プログラムの中で呼び出されていないように見えます。 mainの中のw.setVisible(true)とかw.show()が描画せよ、というトリガーだと思いますが、paintを動かせとはストレートには読めません。 w.paint() とかだとTestクラスのオブジェクトwのメソッドpaintを動かしているということが示されるわけですが。こういうのがないですね。 疑問2 mainの中のFrame w=new Test()はTest w=new Test()でも動作しますが、これはあまり気にしなくていいでしょうか。 ---- 以下はプログラムの構造です。--- import 適当に public class Test extends Frame{ public Test(){ クラスと同じ名前なのでコンストラクタですね。 setSize(300,300);ウィンドウのサイズ指定 addWindowListener() などいろいろウィンドウのセッティング ウィンドウの閉じ方とか 描画のためのキャンバスの用意 } public void paint(Graphics g){ g.drawLine(0,0,200,200); 描画本体 この部分をいろいろプログラミングする } public static void main(String[] args){ メインなのでここがスタートライン Frame w=new Test(); オブジェクトを作って // w.show(); w.setVisible(true); 描け } }

  • Java
  • 回答数4
  • ありがとう数3

みんなの回答

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.4

参考までに、描画するために特定のクラスを継承してメソッドをオーバーライドするという作法はJava独自のものではなく、よくあるスタイルです。 Qtというツールキットを例にします。 https://ja.wikipedia.org/wiki/Qt Qtではプログラミング言語として主にC++を使います。QWidget(またはその子クラス)を継承したクラスでvoid paintEvent(QPaintEvent*)というメソッドをオーバーライドして、その中に描画処理を記述します。

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.3

>そういう意味で予約語(システムに組み込まれていてユーザが変えられない名前)を事前に了解しておく必要もあると思いました。例えば、paintというメソッドは名前が変えられないということでしょうか。paintというメソッドがあるからそれに応じた見えない手続きが動作するということですが。 予約語と似てはいますが、予約語ではありません。 サンプルプログラムのTestクラスはFrameクラスを継承しています。「描画するにはpublic void paint(Graphics g) { 〜 }というメソッドを定義する」というのはFrameクラスの仕様です。もっと言えば、Frameクラスの親クラスであるWindowクラス、さらにその親クラスの…とたどっていって、最終的にはComponentクラスに行き着きます。 >それとも名前を変えたとしても、クラスに含まれているメソッドはすべて実行するということになっていてメソッドの名前は何でもいいということにはならないでしょうか。 メソッドの名前は何でもいいということにはなりません。引数や返り値の型まで含めて、この場合はpublic void paint(Graphics g) { 〜 }というメソッドを定義する(正確にはオーバーライドする)必要があります。paint()というメソッド名であっても、引数の型や数を変えてしまうとそのメソッドはAWTの仕組みからは自動的に呼ばれることはありません。 一方、Frameなどのクラスを継承せずにpublic void paint(Graphics g) { 〜 }というメソッドを定義したとしても、やはりAWTから自動的に呼ばれることはありません。 まとめると、既存のクラスを継承して利用する際にはそのクラスの仕様を理解する必要があるということです。

skmsk1941093
質問者

お礼

回答頂き、誠にありがとうございます。 クラスの継承とかオーバーロード、オーバーライド、同一名の関数とかメソッドでも引数が違うと違うものと見なされるなど様々な仕様があって整理できなくなりそうです。c++はどうだったっけ?など類似した言語の仕様とごっちゃになりそうですね。グラフィックスの処理に関する疑問だったのですが、ちゃんと理解するには言語の根幹的な仕様の知識も必要なように思いました。

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.2

>プログラマが呼び出さなくても、勝手に呼び出されるタイミングがわかるというところが手続き型のプログラミングとは違うということなのでしょうか。 質問者さんが書いたプログラム以外の部分に、「このような条件の時に描画部品のpaint()メソッドを呼ぶ」という手続きが予め実装されているだけです。Javaだって手続き型(+オブジェクト指向)のプログラミング言語です。 >勝手に動作するにしてもどれが先に出てくるかの問題はあるはずなので、プログラムの先に書いてある方ということでしょうか。 その辺もAWTの描画システムが適切に処理するのでユーザーが気にする必要はありません。paint()を呼ぶ順番はプログラムの中に書かれている順番ではなく、複数の描画部品の生成順序や重なり具合に基づいて決定されます。 どのように実装されているかが気になる場合は、java.awt.Frameクラスやその親クラスであるWindow、Containerなどのソースコードを読んでみてください。ソースコードは公開されています。

skmsk1941093
質問者

お礼

回答ありがとうございます。見えないところで手続きがしっかり組み込まれているということですね。 そういう意味で予約語(システムに組み込まれていてユーザが変えられない名前)を事前に了解しておく必要もあると思いました。例えば、paintというメソッドは名前が変えられないということでしょうか。paintというメソッドがあるからそれに応じた見えない手続きが動作するということですが。それとも名前を変えたとしても、クラスに含まれているメソッドはすべて実行するということになっていてメソッドの名前は何でもいいということにはならないでしょうか。プログラマがどこまで自由に名前を決めていいのかのラインという疑問が出てくるのですが。Javaの参考書を読むときにいつも疑問に思っていました。

  • _kappe_
  • ベストアンサー率68% (1522/2216)
回答No.1

1 AWTの描画システムがうまい具合にやってくれるのでどのように呼ばれるかは気にする必要はありません。ウィンドウの大きさをユーザーが変えたときなど、paint()メソッドは様々なタイミングで呼ばれます。 2 このプログラムではどちらを使っても構いません。 Frameクラスにないメソッド(仮にabc()とします)をTestクラスで実装してmain()からそのメソッドを呼びたい場合は、Frame w=new Test(); w.abc();ではコンパイルエラーになるので、Test w=new Test(); w.abc();とする必要があります。

skmsk1941093
質問者

お礼

回答ありがとうございました。プログラマが呼び出さなくても、勝手に呼び出されるタイミングがわかるというところが手続き型のプログラミングとは違うということなのでしょうか。確かにウィンドウサイズが変わったら、それに応じて描画しなおすのは当たり前だし、ウィンドウが指定されたら描画しなくてはならないのも当たり前なのでわざわざ呼びだされなくても出てくる、ということになるでしょうか。ただ、勝手に動作するにしてもどれが先に出てくるかの問題はあるはずなので、プログラムの先に書いてある方ということでしょうか。  私はこういうタイプのプログラミングに慣れておらず、今まで何万行のコード書いたとしても、それはすべて手続きであり、自分で紙と鉛筆と電卓でやっていることを超高速でやってもらっているだけ、という形にはなります。その辺とだいぶ違う感覚のようですが。

関連するQ&A

  • Javaプログラムの繋げ方について。

    Javaプログラムの繋げ方について。 今まで(1)のようなプログラムを書いていました。 作りたいものに向けて色々検索するとやりたいものに近い(2)のようなサンプルプログラムを見つけました。 しかし、Java初心者なもので混ぜ方(?)がわかりません。 現在の私の知識からいうと今までのはアプレットでフレーム使うのはアプリケーションなのかな?別物なのかな?そんな感じです。 もし、混ぜることができるなら何かアドバイスをお願いします。 (1)package test; import java.applet.* ; import java.awt.Label ; import java.awt.Font ; import static java.awt.Font.BOLD ; import java.util.*; import java.awt.Graphics; import java.awt.Image; import java.awt.*; public class test extends Applet{ public void paint(Graphics g){ g.setColor(Color.red); g.fillOval(320, 200, 100, 100); } public void init () { ~~~~~~~~~~~~~~~~ } public void start () { ------------ }}} (2)import java.awt.*; import java.awt.event.*; public class MouseEvent7 extends Frame { int posX = 50; int posY = 50; public static void main(String [] args){ new MouseEvent7(); } //コンストラクタ MouseEvent7(){ this.addWindowListener(new WinAdapter()); //ウィンドウリスナーの登録 this.setSize(200,200); this.setVisible(true); //MouseMotionListenerの登録 addMouseMotionListener( new MouseMotionAdapter(){ public void mouseMoved(MouseEvent e){ posX = e.getX(); posY = e.getY(); repaint(); //paintメソッドを実行 } } ); } public void paint(Graphics g){ g.drawOval(posX,posY,50,50); } } (1)の内容に本当に(2)のプログラムで出来るマウスの動きに合わせて円も動く+クリックしたらそこで止まるだけいいのですが。 出来たら止まった点の座標も取りたいですが、そこまではいってません;;

  • 他のクラスからフレームに追加で描画していく方法

    Javaで、他のクラスで作ったフレームに別のクラスから追加で描画をしていくプログラムを作りたいのですが、 ネット上のサンプルプログラムを見てもフレームを作成する時に描画内容を記述、もしくは描画内容のクラスを呼び出すというものばかりでした。 例:  class Frame{ static void frame(){ JFrame frame = new JFrame(); frame.setBounds(0,0,400,300); フレームへの描画内容 or 描画内容のクラス呼び出し; frame.setVisible(true); } } ↑のような例とは違い、先にフレームを作っておいて、その後に繰り返し文内の描画内容を同じフレームに追加で描画させていきたいと思っています。 繰り返し文内の描画内容はプログラム実行中の操作によって変化します。 メインメソッド{ フレーム作成; while (true){ 描画内容; } } ↑のようにしたいと思っています。 どのようにすれば先に作ったフレームに追加で描画ができるのでしょうか? よろしくお願いします。

  • javaのpaintについて

    public class Main extends JFrame{ public static void main(String args[]){ Main frame = new Main("test"); frame.setVisible(true); } Main(String title){ setTitle(title); setBounds(100, 100, 300, 250); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JMenuBar menubar = new JMenuBar(); JMenu menu1 = new JMenu("File"); menubar.add(menu1); JMenuItem menuitem1 = new JMenuItem("New"); menu1.add(menuitem1); setJMenuBar(menubar); } public void paint(Graphics g){ } } いまウィンドウにメニューバーを表示させようとして上のプログラムで実行させたんですが、画像のようにメニューバーが表示されません。 そこでpaintの引数を消してみたところ表示されます。 しかし、paint内で画像の表示の処理もしたいので引数がないといけません。 どうしたらいいでしょうか?

    • ベストアンサー
    • Java
  • Javaのマウスイベントについて

    閲覧ありがとうございます、Java初心者です。 現在Javaの勉強をしており、マウスの座標を取得しその座標に座標を描画 するプログラムを作っているのですが、どうしても上手くいきません・・・以下が ソースです↓ import java.awt.*; import java.awt.event.*; public class test01 extends Frame { int x, y; public static void main(String[] args) { new test01(); } test01() { super("FrameTest"); //フレーム名 setSize(300, 300); //サイズを設定 MyCanvas mc = new MyCanvas(); //グラフィック用メソッドをインスタンス化 add(mc); //フレームに描画 addMouseMotionListener(new getMouse_position()); System.out.println("(" + x + "," + y + ")"); setVisible(true); //フレームを表示 addWindowListener(new Close()); //クローズ処理 } /*** グラフィック描画用クラス ***/ public class MyCanvas extends Canvas { public void paint(Graphics g) { g.drawString("(" + x+ "," + y + ")", x, y); } } /*** マウス操作用クラス ***/ public class getMouse_position extends MouseAdapter { public void mouseMoved(MouseEvent ev) { x = getX(); //マウスのx座標を取得 y = getY(); //マウスのy座標を取得 repaint(); } } } /*** クローズ用クラス ***/ class Close extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } これを実行すると、ずっと(0, 0)のままでマウスの座標を読み取ってくれません・・・何故なんで でしょうか?

    • ベストアンサー
    • Java
  • java アプリケーションをjava アプレットに

    java超初学者です。詳しいかたご教授願います。 java アプリケーションをjava アプレットに書き換えたいのですが、具体的にはどう書き換えを行ったらいいのか修正をお願いします。 (文字制限があるので、14個あるクラスファイルの中で(内1つはhtmlファイル)、メインメソッドを持つ実行クラスだけのせています。) Appletを継承させる、属性をメインクラスとコンストラクタはpublic にする、 mainメソッドを削除し、initメソッドへ書き換える、サイズ指定は<applet>タグで指定する。等調べましたが 具体的にわかりません。特にコンストラクタとメインメソッドの部分のアプレットへの書き換えがわかりませんでした。 宜しくお願い致します。 //実行クラスです。 import java.awt.*; import java.awt.event.*; /** *ゲームクラス(ここから始まる)<p> *画面の作成 */ public class Game extends Frame { /** * メインクラス */ public static void main(String args[]) { //フレームの作成 new Game(); } /** * 引数なしのコンストラクタ */ Game() { //*** ウィンドウの初期化 //タイトル super("Shooting Game"); //クローズボタンによる終了処理の実装 addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); setSize(500, 500); //ウィンドウのサイズ //*** キャンバスの初期化 MyCanvas mc = new MyCanvas(); add(mc); //フレームにキャンバスを追加 setVisible(true); //ウィンドウの表示 //ゲームデータの初期化 mc.init(); //スレッドを作成 mc.initThread(); } }

  • 「継承されたメソッドの可視性を下げることは出来ません。」というエラーの

    「継承されたメソッドの可視性を下げることは出来ません。」というエラーの意味がわかりません。  JAVA初心者です、宜しくお願いします。  下のようなコードを書きましたが、"void paint(Graphics g)"の箇所で 「Canvasから継承されたメソッドの可視性を下げることは出来ません。」 とのエラーメッセジが出ました。  "public void paint(Graphics g)"とかくと、エラーは消えました。  何故"public"をつける必要があるのでしょうか。  また、クラス自身には、publicをつけない場合には、publicと見なされると本で読みましたが  メッソドにはこのようなルールはないのでしょうか。 ======================================= public class Canvas_test extends Canvas { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setTitle("Canvas_test"); frame.setBounds(0,0,480,380); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); frame.setLayout(null); JPanel cp = new JPanel(); cp.setLayout(null); frame.add(cp); cp.setBounds(38,20,400,300); Canvas canvas = new Canvas_test(); cp.add(canvas); canvas.setBounds(0,0,400,300); frame.setVisible(true); } void paint(Graphics g) { g.drawString("aaaa",40,40); } } ========================================

    • ベストアンサー
    • Java
  • JAVAプログラムの基本的な書き方

    JAVAを始めて数日の者です。 クラス、メソッド、コンストラクタ、インターフェイスなど初心者にはかなりキツイです! どうも理解できません。 プログラムを書くとき、クラス定義したらその度にnew演算子を使うのでしょうか? メソッドとは処理する内容を記述するものなのでしょうか? メインは最後に記述するのでしょうか? 最初に呼び出されるのはメインですか? プログラムを書くとき、頭の中で流れを考えながら英語みたいに組み立てていくのでしょうか? 訳のわからない質問ですが、プログラムを書くときの基本的な注意点を教えてください!

  • Javaアプレットで描画の中断がしたい

    Java初心者です。学校の課題で数学シュミレーションの結果を Javaアプレットで表示するプログラムを作成しています。 この課題のJavaアプレットでは 複素平面のシュミレーション(計算結果を色のグラデーションで表示する)なのですが、 チョイスやボタン、マウスクリックなどによって、 初期条件や、描画方式、表示範囲などを指定することができます。 とりあえず、シュミレーション結果の描画は 試行錯誤の結果表示ができるようになりました。 paint(Graphics g)メソッドで数値計算、及び描画をしています。 (ちなみに余談かもしれませんがダブルバッファリングをしていて、 描画内容をImageとして書き込んでおいて描画するというかたちです。) 「計算途中(計算には結構時間がかかる)に 新たにボタンなどで指定条件が変更された場合、 現在の描画を中断して次の計算と描画を開始できるように プログラムを改良しなさい」というのが今回の課題です。 つまり、「プログラム的にはpaintメソッドが実行されている途中に 特定のイベントが発生したらpaintメソッドを中断し、 もういちど呼びなおしなさい」ということかと思われます。 スレッドを作り、そのスレッドを中断するなども考えました。 インターネットで検索もしてみましたが、 なかなか情報を見つけられず困っています。 学生が作るプログラムなのでそんなに難しいことではないのだと思うのですが 解決できませんでした。 どうぞよろしくお願いします。

  • Javaでウィンドウ作成について

    下記のJavaのプログラムについて質問です。 ウィンドウを表示するプログラムで、本に書いてあるのを参考にしました。 しかしウィンドウを表示されません。 どうしたらウィンドウを表示できるようになりますか?。 ちなみにコメントアウトしている部分を有効にするとウィンドウが表示されます。 開発環境はEclipse3.4で、Eclipse3.4から実行しています。 もう一点、コメントアウトしているsuper()を有効にすると Eclipse3.4から下記のエラーがでます。 本に書いてある通りにしているつもりですが、これについても教えて下さい。 ”コンストラクター呼び出しは、コンストラクター内の最初のステートメントである必要があります” 以上、よろしくお願いします。 ackage test; import java.awt.Frame; public class P155 extends Frame{ public void P155(){ //super(); this.setSize(300,200); this.setVisible(true); } public static void main(String[] args) { new P155(); // Frame f= new Frame(); // f.setSize(300,200); // f.setVisible(true); } }

    • ベストアンサー
    • Java
  • javaプログラムの問題です

    1このプログラムの全てのインスタンス変数について、変数名と大まかな役割を書いてください。 c MyCanvasを呼び出す t71 Test71を呼び出す f フレームを呼び出す br 文字列を読み込み bw 文字列を書き込む これであっているかをお願いします。 2全てのメソッド名と大まかな役割を書いてください。 メソッド名 main javaの基本(どのプログラムでも使う) windowClosing ウィンドウを閉じる doEvent 送られてきた処理により何かをする こちらもあっているかをお願いします。 間違っているなら何が違うかを教えてください。 プログラム始めたばかりの初心者ですみません。 よろしくお願いします。 1: import java.awt.event.*; 2: import java.awt.*; 3: import java.io.*; 4: import java.net.*; 5: 6: public class Test71 { 7: private MyCanvas c; 8: public static void main( String[] args ) { 9: Test71 t71 = new Test71(); 10: t71.doEvent(); 11: } 12: 13: Test71() { 14: Frame f = new Frame( "Test71" ); 15: f.setSize( 640, 480 ); 16: f.addWindowListener( new WindowAdapter() { 17: @Override public void windowClosing( WindowEvent e ) { 18: System.exit( 0 ); 19: } 20: }); 21: c = new MyCanvas(); 22: f.add( c ); 23: f.setVisible( true ); 24: } 25: 26: public void doEvent(){ 27: try{ 28: ServerSocket ss = new ServerSocket( 8000 ); 29: while( true ) { 30: Socket socket = ss.accept(); 31: BufferedReader br = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); 32: BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) ); 33: while( true ) { 34: String command = br.readLine(); 35: String[] words = command.split( " " ); 36: System.out.println( command ); 37: if( words[0].equalsIgnoreCase( "setOval" ) ) { 38: try { 39: c.setPoint( Integer.parseInt( words[1] ), Integer.parseInt( words[2] ) ); 40: } catch( Exception e ) {} 41: } else if( words[0].equalsIgnoreCase( "changeMode" ) ) { 42: //描画方式を変更する処理 43: } 44: else if( words[0].equalsIgnoreCase( "quit" ) ) { 45: break; 46: } 47: } 48: bw.close(); 43 49: br.close(); 50: socket.close(); 51: } 52: } catch( Exception e ) { 53: e.printStackTrace(); 54: } 55: } 56: }

    • ベストアンサー
    • Java

専門家に質問してみよう