応用プログラミング 第4回


この授業の目的

 この授業では,アプレットでのグラフィック描画とイメージ描画の方法について学びます.


出席メール

出席メールで「授業中の課題の実施」を確認します.メールを出した時刻,PCの場所(アドレス)を確認します.

to:jhoshino@esys.tsukuba.ac.jp
subject: 応用プログラミング 第4回.氏名,学籍番号
本文: なし(書かなくて結構です)


理論

アプレットの作成

Javaでは主にApplicationとAppletの2種類の動作の形態がとれます.

Javaプログラムの構造はアプリケーションとアプレットによって違う。 アプリケーションはロードされたときに,「mainメソッド」が最初に呼び出されて実行される。従って,アプリケーションには必ずmainメソッドが必要である。

 アプレットはjava.appletパッケージに含まれている「Appletクラス」を継承して拡張する。Appletクラスには「init,start,paint,stop,destroy」というメソッドがあらかじめ定義されており,ブラウザをこの順に従ってメソッドを順次呼び出して実行していく。従ってユーザが作成するアプレットは,必要に応じてこれらのメソッドの機能を拡張する形で記述していく。

  1. init(){
    ブラウザがアプレットを読み込んだとき一番最初に呼ばれるメソッドで,初期設定を記述する。
  2. start(){
    アプレットの実行を開始するときに呼ばれるメソッドで,マルチスレッドのスレッド生成などを記述する。
  3. paint(){
    画面を表示するときに呼ばれるメソッドで,通常ここに画面への処理を記述する。画面のサイズが変更されたときや,repaint( ),update( ) メソッドなどにより呼び出される。
  4. stop(){
    アプレットの終了時に呼ばれるメソッド。
  5. destroy(){
    アプレットを解放するときに呼ばれるメソッド。

 さらに,このアプレットをブラウザで実行できるようにするには,Webページ上にアプレットを呼び出すHTMLコードを追加しなければならない。

・アプレット呼び出しコード
      <applet  code= "ファイル名.class"  width=横サイズ  height=縦サイズ></applet>

 

JAVAプログラム作成の基本

Javaでプログラムを作るには既存のクラスを利用し,それを継承して新しいクラスを作成することになる。既存のクラスは「クラスライブラリー」として提供されるので,継承されるスーパークラスが含まれているパッケージを最初にロードする。

・既存クラスのロード
      import  パッケージ名.クラス名;
          または(*はすべてのクラス)
      import  パッケージ名.*;
パッケージ名 機能・含まれるクラス
java.applet アプレット関係。Applet,AudioClipなど
java.awt.image 描画・GUI部品関係。Graphics,Image,Buttonなど
java.awt.peer ピア関係。ComponentPeer,DialogPeerなど
java.io ファイル入出力関係。InputStream,RandomAccessFileなど
java.lang 型・スレッド関係。Thread,Integerなど
java.net ネットワーク関係。InetAddress,Socketなど
java.util 日付などのユーティリティ関係。Date,Randomなど

 なお,明示的に継承するクラスを示さない場合は,java.langパッケージのObjectクラスを継承したことになる。

 

簡単な図形の描画

JAVAではプログラムの冒頭に "import java.awt.*;"と書き加えるだけで,簡単にグラフィクス機能を使うことができます.awtとはabstract window toolkitの略で,windowの描画や,ボタンの作成など,便利なツールが揃ったライブラリだと考えれば良いでしょう.下のサンプルプログラムで,g.drawOvalのようにg.####と記述されたコマンドが多く出てきますが,これがawtのライブラリ(正確にはクラスawtのメソッド)を呼び出すことを意味しています.

// HelloWorld.java 

import java.awt.Graphics;
import java.applet.Applet;
public class HelloWorldApplet extends Applet {
  public void paint(Graphics g) {  
    g.drawString("Hello world!", 50, 25);  
  }
}

Appletの特徴は2行目のextends Appletで始まっているところです。これはAppletの性質を受け継いでいるという宣言です.

これまでは,public void mainというメソッドが最初に呼び出されていまたが,appletの描画ではpaintメソッドが呼び出されます.

4行目にあるpublic void paint(Graphics g)というメソッドは g.drawString("Hello world!", 50, 25);という命令を持ちます。

Graphics gというのは現在のAppletの描画可能領域を示すものです。 (50,25)の位置から文字(Hello world!")を書けと命令をしています。

 


//図形の描画
import java.applet.*;
import java.awt.*;
/*
  < applet code = "DrawMethod" width = 640 height = 480>
  </applet>
*/
public class DrawMethod extends Applet{
  public void paint(Graphics g){
    g.setColor(Color.blue);
    //x,yは座標,wは幅,hは高さでint型
    g.drawLine(50,50,150,150);  //線を描画(x1,y1,x2,y2)
    g.drawRect(180,50,140,100); //長方形を描画(x,y,w,h)
    g.drawRoundRect(190,60,120,80,30,30); //面取り長方形を描画(x,y,w,h,arcW,arcH)
    g.drawOval(350,50,100,100); //楕円を描画(x,y,w,h)
    g.drawArc(500,50,90,90,50,235); //楕円弧を描画(x,y,w,h,startAngle,arcAngle)
    g.drawOval(20,250,160,100);
    g.drawArc(220,250,160,100,30,250);
    int x[] = {580,450,550,580};
    int y[] = {220,350,300,220};
    g.drawPolygon(x,y,4);//配列点で折れ線を描く
  }
}

//いろいろな図形の塗りこみ
import java.applet.*;
import java.awt.*;
/*
  <applet code = "DrawMethod" width = 640 height = 480>
  </applet>
*/
public class FillMethod extends Applet{
  public void paint(Graphics g){
    g.setColor(Color.green);
    //x,yは座標,wは幅,hは高さでint型
    g.fillRect(50,50,50,100);  //長方形を描画(x,y,w,h)
    g.fill3DRect(150,50,50,100,true); //3次元長方形を描画(x,y,w,h,boolean raised)
    g.fillRoundRect(250,50,50,100,30,30); //面取り長方形を描画(x,y,w,h,arcW,arcH)
    g.fillOval(350,50,100,100); //楕円を描画(x,y,w,h)
    g.fillArc(500,50,90,90,50,235); //楕円弧を描画(x,y,w,h,startAngle,arcAngle)
    g.fillOval(20,250,160,100);
    g.fillArc(220,250,160,100,30,250);
    int x[] = {580,450,550,580};
    int y[] = {220,350,300,220};
    g.fillPolygon(x,y,4);//配列点で折れ線を描く
  }
}

 


//Fontオブジェクト
import java.applet.*;
import java.awt.*;
/*
  <applet code = "DrawMethod" width = 640 height = 480>
  </applet>
*/
public class FontObject extends Applet{
  public void paint(Graphics g){
    char c[] = {'J','a','v','a'};
    String s = "Graphics Programming";
    Font f1 = new Font("Serif",Font.ITALIC | Font.BOLD,30);
    Font f2 = new Font("SansSerif",Font.BOLD,35);
    Font f3 = new Font("Monospaced",Font.ITALIC,40);
    Font f4 = new Font("Dialog",Font.PLAIN,40);

    //(data[],offset,length,x,y) 開始点を(x,y)として,data配列のoffset番目からlength個の文字を描画
    g.drawChars(c,0,4,100,50);
    g.drawChars(c,1,3,100,70);
    g.drawChars(c,2,2,100,90);
    g.drawChars(c,0,2,100,110);
    g.setColor(Color.blue);
    g.drawString(s,100,150);  //(string,x,y)開始点を(x,y)として文字列stringを描画
    g.setFont(f1);  //フォントを設定
    g.setColor(Color.red);
    g.drawString(s,100,200);
    g.setFont(f2);
    g.setColor(Color.green);
    g.drawString(s,100,250);
    g.setFont(f3);
    g.setColor(Color.blue);
    g.drawString(s,100,300);
    g.setFont(f4);
    g.setColor(Color.magenta);
    g.drawString(s,100,350);
  }
}
 
実習
1)アプレットの作成

// HelloWorldApplet.java 

import java.awt.Graphics;
import java.applet.Applet;
public class HelloWorldApplet extends Applet {
  public void paint(Graphics g) {  
    g.drawString("Hello world!", 50, 25);  
  }
}

 

 

appletは以下のようにHTMLファイルからappletタグを利用して呼び出されます。

<HTML><HEAD><TITLE>HelloWorldApplet.java</TITLE></HEAD>
<BODY><H1>HelloWorldApplet.javaのテスト</H1><HR>
<APPLET CODE="HelloWorldApplet" WIDTH=200 HEIGHT=30></APPLET>
</BODY></HTML>

実行方法:

  1. javaのソースをコンパイルしてclassファイルを作成する
    % javac HelloWorldApplet.java
  2. appletを呼び出すhtmlのファイルを作る
  3. HelloWorldApplet.classとHelloWorld.htmlが同じディレクトリにあることを確認して
    appletviewer HelloWorld.html と入力するか,もしくは Appletの実行できるブラウザでHTMLファイルを開く

2)配列を使った図形の描画

次は配列を使って描画をしてみます.配列の定義は第1回目の授業でやったようにint x[] = new int[N]のように書きます.

/* DrawPolygonApplet.java ポリゴンを描画するプログラム */
import java.applet.Applet;
import java.awt.*;

/*
<applet code = "DrawPolygonApplet" width = 300 height = 200> 
</applet>
*/

public class DrawPolygonApplet extends Applet{
public void paint(Graphics g){
  int N = 3;
  int x[] = new int[N];
  int y[] = new int[N];
  x[0] = 40;
  y[0] = 80;
  x[1] = 80;
  y[1] = 50;
  x[2] = 120;
  y[2] = 80;
  g.setColor(Color.blue);
  g.fillPolygon(x,y,N);  //多角形の内部を塗りつぶす
  for(int i=0;i<N;i++) y[i]+=50;
  g.setColor(Color.red);
  for(int i=0;i<N;i++){
    g.fillPolygon(x,y,N);
    for(int j=0;j<N;j++){
      x[j] += 80;
    }
  }
 }
}

3)アプレットでのイメージの描画

JAVAではクラスライブラリを使うことで,jpeg,gif,pngなどの各種の画像の読み込みと表示を簡単に行うことができます.例えば,ゲームを作るときにキャラクタの画像(例:enemy.gif)を表示するときにも使っています.

/*
  DrawImageApplet.java  イメージの描画
*/
import java.applet.*;
import java.awt.*;

public class DrawImageApplet extends Applet{
  Image img;                     //Imageデータ型
  public void init(){
    img = getImage(getDocumentBase(),"test.jpg");	//画像読み込み
  }
  public void paint(Graphics g){
    g.drawImage(img,0,0,this);            //画像表示
  }
}

テスト画像は次のリンクからダウンロードして下さい:test.jpg

アプレットサイズはwidth = 300 height = 300で良いと思います.

この例では画像ファイルをクラスファイルと同じディレクトリに置く必要があります.
imageディレクトリに画像ファイルを置いてある時は
img = getImage(getDocumentBase(),"./image/test.jpg");
のように書きます.

上の例では飛行機の背景が黒くなっていますが,透過GIFと透過PNGを使うと背景が透けて見えるようになります. テスト画像は次のリンクからダウンロードして下さい:test.gif test.png
練習課題

各種の描画ライブラリとfor文を組み合わせて各自好きな図形を描画して下さい.

提出先のアドレスはjhoshino@esys.tsukuba.ac.jpです.Subject欄に「応用プログラミング 第4回課題,氏名,学籍番号」を書いて下さい.本文にソースコード,実行結果,考察を記載して下さい.

締め切りは次の授業の開始時まで.ソースコードはメール本文へのコピーあるいは添付どちらでも結構です.


付録

Frameを使った表示

"Hello World"と表示するサンプルです。 サンプルはGUIの部品上に表示をします。 簡単な説明をつけます。

// HelloWorld.java
import java.awt.Graphics;
import java.awt.Frame;
public class HelloWorld extends Frame {
   public HelloWorld(){
        setSize(100,100);
   }
  public void paint(Graphics g) {
      g.drawString("Hello world!", 10, 50);
   }
   public static void main(String[] args) {
      HelloWorld f = new HelloWorld();
      f.show();
   }
 }

実行方法:

  1. javaのソースをコンパイルしてclassファイルを作成する
    % javac HelloWorld.java
  2. HelloWorld.classができているのを確認して
    % java HelloWorld

このプログラムは一枚ウインドウを表示し、その中にHello world!と表示しま す。

まず、描画に使用するjava.awt.Graphicsクラスとウインドウを開くため のjava.awt.Frameクラスをimport宣言しておきます。これはC言語の#include 文と似た働きをします。

このプログラムではHelloWorldというクラスの中に2つのメソッドと1つのコンストラクタがあります。

アプリケーションではpublic static main(String[] args)のメソッドがC言語 のmain関数に相当します。そのため% java HelloWorldを実行 するとこのメソッドが呼び出されます。 そしてmainのメソッドではこのHelloWorldのコンストラクタが呼ばれます。

このコンストラクタはFrameを継承しているのでまず、Frameの大きさを (100,100)にセットします。そして可視の状態にします。

そして残りのメソッドpaintではこのFrameの10,50の位置に文字を書くように 要求します。

上には書いていませんが setSize(100,100); の下に
addWindowListener(new WindowAdapter(){
  public void windowClosing(WindowEvent e){
   System.exit(0);
 }
});
を書いて、ファイルの冒頭にimport java.awt.event.*;を加えることで、フレームの右上にできる×印で終了処理を行うことができるようになります.