double d=Double.parseDouble("1.32");
->
double d=new Double("1.32").doubleValue();
をあげたが,他に,Randomクラスの引数付きのnextIntメソッドがない点.
Random r=new Random(); int j=r.nextInt(10); -> Random r=new Random(); int j=Math.abs(r.nextInt())%10;やVector クラスにcontainsAll, removeAll等がない点(自分でメソッドを書く必要あり) なども見つかった.気になる人は,JDK1.1 Java API パッケージを見て,確認するように.
今回の課題に関しての質問です。 appletではイメージの読み込みの際に Toolkit.getDefaultToolkit().getImage() という方法は使えないということなのですが、Canvasにイメージを 読み込みたい時にはどうすればよいのでしょうか? 授業でやったのはinitのなかでAppletクラスのgetImageメソッド を使うということだったのですが、Canvasのクラスを別につくって いる場合どうすればいいのかよくわかりません。
良い質問ですね.Appletクラス以外はgetImageメソッドを呼べないわけです
が,Canvasの中でイメージを使いたいということであれば,いくつか方法があ
ります.
(1) CanvasのサブクラスのコンストラクタをImage型の引数を取って,インス
タンス変数に代入するように定義しておいて,Appletの initの中でgetImage
したものを渡してCanvasのコンストラクタを呼び出す.
-> 実装は簡単ですが最初に必要なイメージをすべてgetImageしておく必要が
あります.
(2) CanvasのサブクラスのコンストラクタをApplet型の引数を取ってインスタ
ンス変数に代入するように定義しておいて,Appletの initの中で自分を渡し
てCanvasのコンストラクタを呼び出す.Canvasの中でgetImageしたくなったら,
インスタンス変数のgetImageを呼び出す(publicなメソッドなので他のクラス
のメソッドからでも呼べます).
-> 必要に応じてgetImageできます.
(1),(2)に対応するサンプルを載せるので参考にしてください( (2)の方は,
paintが5回呼ばれてはじめて絵がでます.).
----------------------------------------------------------------------
// <applet code=TestApplet width=100 height=100>&;lt/applet>
import java.awt.*;
import java.applet.*;
class MyCanvas extends Canvas{
Image myImage;
MyCanvas(Image im){
myImage=im;
setSize(100,100);
}
public void paint(Graphics g){
g.drawImage(myImage,0,0,this);
}
}
public class TestApplet extends Applet{
public void init(){
setLayout(new FlowLayout());
Canvas c=new MyCanvas(getImage(getCodeBase(),"test.gif"));
add(c);
}
}
----------------------------------------------------------------------
// <applet code=TestApplet1 width=100 height=100></applet>
import java.awt.*;
import java.applet.*;
class MyCanvas1 extends Canvas{
Image myImage;
Applet baseApplet;
int count=0;
MyCanvas1(Applet ap){
setSize(100,100);
baseApplet=ap;
}
public void paint(Graphics g){
System.out.println("count="+count);
count++;
if(count>5 && myImage==null){
myImage=baseApplet.getImage(baseApplet.getCodeBase(),"test.gif");
}
g.drawImage(myImage,0,0,this);
}
}
public class TestApplet1 extends Applet{
public void init(){
setLayout(new FlowLayout());
Canvas c=new MyCanvas1(this);
add(c);
}
}
ファイルからイメージをロードして、そのイメージのうえにマウスが動く
通りに線か書けるように、円を連続して書いてそれが線になるように
次のようなプログラミングを作ったのですが、線は書けず、円だけに
なってしまいます。線を書くにはどうしたらよいのですか?
また、qをおしても終了になりません。さらに、画面が2つ出てきてしまいます。
どうしたらよいでしょうか?
// appletを使うため
import java.applet.*;
// AWTを使うため,
import java.awt.*;
// イベント駆動関係のクラスを用いるため
import java.awt.event.*;
// Vectorクラスを用いるため
import java.util.*;
//円のクラスを定義する。
class Center{
//円の中心の x座標, y座標を intで保持する。
public int x,y;
//Centerのコンストラクタ
public Center(int x1,int x2){
x=x1;
y=x2;
}
}
//外側のFrameに直接paintするのではなく、お絵書き領域を作る。
class En extends Frame implements KeyListener, MouseMotionListener{
//Centerの配列を保持するVectorクラスの変数 circleの宣言。
Vector circle;
//円の半径を2とする
int r=2;
//Image型の変数 bgの宣言
Image bg;
//表示する色を保持する変数を宣言 円の色は黒に。
Color circleColor=Color.black;
// コンストラクタの宣言
public En(){
super();
circle =new Vector();
// GUI部品と,Event Listenerを関連づける
setSize(300,300);
addKeyListener(this);
addMouseMotionListener(this);
}
Image offScreenImage;
Graphics offScreenGraphics;
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=createImage(600,450);
// オフスクリーンイメージを600x450のサイズで作成
offScreenGraphics=offScreenImage.getGraphics();
// オフスクリーンイメージに描画するための Graphics オブジェクト
}
// 次の画面のイメージを作る.
paint(offScreenGraphics);
// イメージを本物のスクリーンに書き込む
g.drawImage(offScreenImage,0,0,this);
}
// offScreenImageの書き直しをする際に呼ばれる
public void paint(Graphics g){
int i;
//イメージ bg を (100,100)を左上にして表示する。
g.drawImage(bg,100,100,this);
// 色を設定
g.setColor(circleColor);
int size=circle.size();
for(i=0;i< size;i++){
Center c=(Center)circle.elementAt(i);
g.fillOval(c.x-r,c.y-r,2*r,2*r);
}
}
// 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){}
// MouseMotionListenerを実装するためのメソッド
public void mouseDragged(MouseEvent e){
// マウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
// デバッグ用の表示
System.out.println("mouseDrag("+e+","+mx+","+my+")");
circle.addElement(new Center(mx,my));
repaint();
}
public void mouseMoved(MouseEvent e){}
}
//アプレットはpublicでなければならない
public class Sen extends Applet{
En frame;
public void init(){
frame=new En();
frame.bg=getImage(getCodeBase(),"test.gif");
}
public void start(){
frame.setVisible(true);
// frame.start();
}
public void stop(){
frame.setVisible(false);
//frame.stop();
}
}
田中哲朗です. > ファイルからイメージをロードして、そのイメージのうえにマウスが動く > 通りに線か書けるように、円を連続して書いてそれが線になるように > 次のようなプログラミングを作ったのですが、線は書けず、円だけに > なってしまいます。線を書くにはどうしたらよいのですか? センターのUnix環境の appletviewer で実行する場合の動作だと思いますが, オフスクリーンイメージを使うとpaintに時間がかかるため,次の mouseDrag が呼ばれるまでの間にマウス座標が激しく動いてしまうということのようです. 対策はいろいろあります. ・ オフスクリーンイメージをやめる.もしくは,クリッピングにより書き換 え領域を減らす. ・ とびとびの座標になった場合は,paintの中で間を補間してcircleの要素が ないところにも円を描く.一番簡単なのは1次補間(線分で結ぶ)だが,スプラ イン曲線で補間する方法もいろいろある. > また、qをおしても終了になりません。さらに、画面が2つ出てきてしまいます。 > どうしたらよいでしょうか? Appletの中では System.exit を実行しても無視されます(厳密には security violationの例外が発生する).終了したように見せたい場合は, setVisible(false) をする位でしょうか. 画面が2つ出るというのはわかりません.appletviewer を終了しないうちに, 別の appletviewer を起動してしまった場合はそうなりますが.
12月4日の課題を今週の火曜日に一応提出したのですが、 もう少し直そうと思って提出方法のところを読むと、 ”アプレットとjavaソースプログラム(リンクも可),アプレットで使われるイメージファイルを含んだ説明用のHTMLファイルをUnixシステム上(「file:/home/ユー ザ名/...」でアクセス)かセンターのユーザ情報発信WWWサーバ上 (「http://user.ecc.u-tokyo.ac.jp/~ユーザ名/...」でアクセス)に作成” とあるのですが、”説明用htmlファイル”というのは通常のhtmlファイルとは違うのですか?
通常のhtmlファイルです.内容として説明も含めてくださいという意味です. 現在提出されているものでも条件は満たすが,もう少し説明は多めの方がよかっ たと思います(再提出の必要はありません).
説明やソースへのリンクがないものは減点する.この場合も,締切りまでに 再提出すれば良い.
締切りは今日の 21:00.
/home/ktanaka/bin/report1218 file:/home/ktanaka/kadai1220/index.htmlのように実行する。このコマンドは1月20日21時までに実行すること。それまで は何度実行してもかまわない.