// <applet code=AppTest width=600 height=450></applet>
// アプレットを使うため
import java.applet.*;
// AWTを使うため,
import java.awt.*;
// イベント駆動関係のクラスを用いるため
import java.awt.event.*;
// Vectorクラスを用いるため
import java.util.*;
// 線分のクラスを定義する.
class Line{
// 始点,終点のX座標,Y座標を int で保持する.
public int start_x,start_y,end_x,end_y;
// Lineのコンストラクタ
public Line(int x1,int x2,int x3,int x4){
start_x=x1;
start_y=x2;
end_x=x3;
end_y=x4;
}
}
// 外側のFrameに直接 paintするのではなく, お絵書き領域を作る.
class MyCanvas extends Canvas implements KeyListener, MouseListener, MouseMotionListener{
// Lineの配列を保持するVectorクラスの変数 lineArrayの宣言
Vector lineArray;
// マウスをドラッグ中かどうかを示す boolean型(真偽値)の変数draggingの宣言
boolean dragging;
// 表示する色を保持する変数
Color lineColor;
// コンストラクタの宣言
public MyCanvas(){
super();
lineArray=new Vector();
// ドラッグ中ではない
dragging=false;
// 線の色は黒に
lineColor=Color.black;
// GUI部品と,Event Listenerを関連づける
setSize(600,400);
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
Image offScreenImage;
Graphics offScreenGraphics;
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=createImage(600,400); // オフスクリーンイメージを600x400のサイズで作成
offScreenGraphics=offScreenImage.getGraphics(); // オフスクリーンイメージに描画するための Graphics オブジェクト
}
paint(offScreenGraphics); // 次の画面のイメージを作る.
g.drawImage(offScreenImage,0,0,this); // イメージを本物のスクリーンに書き込む
}
// offScreenImageの書き直しをする際に呼ばれる
public void paint(Graphics g){
int i;
// 白で(0,0)-(600,400)を塗り潰す
g.setColor(Color.white);
g.fillRect(0,0,600,400);
// 色を設定
g.setColor(lineColor);
int size=lineArray.size();
if(dragging) size--;
for(i=0;i< size;i++){
Line l=(Line)lineArray.elementAt(i);
g.drawLine(l.start_x,l.start_y,l.end_x,l.end_y);
}
// マウスをドラッグ中の時は
if(dragging){
// 赤い色で
g.setColor(Color.red);
// lines[lineCount] を描画する.
Line l=(Line)lineArray.elementAt(i);
g.drawLine(l.start_x,l.start_y,l.end_x,l.end_y);
}
}
// KeyListenerを実装するためのメソッド
public void keyPressed(KeyEvent e){
// イベントからキーのコードを取り出す
int key=e.getKeyChar();
// デバッグ用の表示
System.out.println("keyPressed("+e+","+key+")");
// 入力が 'q'の時は終了する
if(key=='q') System.exit(0);
}
// 要らないイベントに対応するメソッドも中身は空で書いておく必要がある.
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
// MouseListenerを実装するためのメソッド
public void mousePressed(MouseEvent e){
// 押された時のマウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
// デバッグ用の表示
System.out.println("mousePressed("+e+","+mx+","+my+")");
// 配列linesのlineCount番目に線分を登録
lineArray.addElement(new Line(mx,my,mx,my));
// ドラッグ中であることを示す
dragging=true;
// 再表示をおこなう
repaint();
}
// マウスのボタンが離された時のイベント
public void mouseReleased(MouseEvent e){
// マウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
// デバッグ用の表示
System.out.println("mouseUp("+e+","+mx+","+my+")");
// 配列linesのlineCount番目の始点を変更
Line l=(Line)lineArray.elementAt(lineArray.size()-1);
l.end_x=mx;
l.end_y=my;
dragging=false;
// 再表示をおこなう
repaint();
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
// MouseMotionListenerを実装するためのメソッド
public void mouseDragged(MouseEvent e){
// マウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
// デバッグ用の表示
System.out.println("mouseDrag("+e+","+mx+","+my+")");
// 配列linesのlineCount番目の始点を変更
Line l=(Line)lineArray.elementAt(lineArray.size()-1);
l.end_x=mx;
l.end_y=my;
// 再表示をおこなう
repaint();
}
public void mouseMoved(MouseEvent e){}
// Delete ボタンが押された時の処理
public void deleteLine(){
int size;
if((size=lineArray.size())>0){
lineArray.removeElementAt(size-1);
repaint();
}
}
// Clear ボタンが押された時の処理
public void clearLine(){
lineArray.removeAllElements();
repaint();
}
}
// アプレットはpublicである必要
public class AppTest extends Applet implements ActionListener{
MyCanvas myCanvas;
Button deleteButton,clearButton;
// コンストラクタは書かない.アプレット作成時に initが呼ばれる.
// メニューバーは使えない
public void init(){
// パネル(ボタンなどを配置するための入れ物)部分を作成する.
Panel panel=new Panel();
panel.setLayout(new FlowLayout());
panel.add(deleteButton=new Button("Delete"));
deleteButton.addActionListener(this);
panel.add(clearButton=new Button("Clear"));
clearButton.addActionListener(this);
// BorderLayoutを用いる.
setLayout(new BorderLayout());
// 上部に Panel
add(panel,"North");
// 下部に MyCanbasを配置する.
add(myCanvas=new MyCanvas(),"South");
// 部品をおさめるのに適当と思われるサイズにする.
setSize(getPreferredSize());
setVisible(true);
}
public void actionPerformed(ActionEvent e){
System.out.println(e);
Object source=e.getSource();
// Deleteボタンが押された時
if(source.equals(deleteButton)){
myCanvas.deleteLine();
}
// Clearボタンが押された時
else if(source.equals(clearButton)){
myCanvas.clearLine();
}
}
}
ほとんど変更がなく書けるのが分かるだろう.これを実行するには,このソー
スファイルをjavac でコンパイルしてクラスファイルを作成した上で,
apptest.htmlという
<applet code="AppTest" width=600 height=450> </applet>といったファイルを同じディレクトリに作って,
appletviewer apptest.htmlを実行する.あるいは,WWWブラウザでこのファイルをアクセスすると良い( apptest.html ).
先ほどのファイルのように,先頭にコメントで
// <applet code=AppTest width=600 height=450> </applet>のように書いて置くと, appletviewer AppTest.javaでアプレットを実行できる.ただし,WWWブラウザでアクセスするときは拡張 子をチェックするため,別に apptest.html が必要になる. |
initの中で,
frame=new DrawImage();
frame.image=getImage(getCodeBase(),"test.gif");
のように使う.
「Shift+再読み込み」で新しいプログラムがロードされることもあるようだが, 確実な方法は,同じプログラムを別のURLでアクセスさせることによりWWWブラ ウザのキャッシュを無効にする方法である.
たとえば,「file:/home/ktanaka/java/canvastest.html」というhtmlファイ ルの中で同じディレクトリの,CanvasTestというAppletを使っていたとする. これを編集してコンパイルして, 「file:/home/ktanaka/java/canvastest.html」を再読み込みしても新しいプ ログラムが実行されない時は,
cd /home/ktanaka ln -s java java1のようにシンボリックリンクを作成すると,同じファイルが 「file:/home/ktanaka/java1/canvastest.html」というURLで参照できるよう になる.こちらのURLで参照すると新たにプログラムが読み込まれる.次に編 集したら,今度は
cd /home/ktanaka ln -s java java2のようにする.これを繰り返すことによって,何度も繰り返すことができる.