問題のポイント
- GUI部品のレイアウトの設定
- GUI部品のイベントの処理を適切におこなえるか
解答例(1)
/*********************************************************************
月と雪だるま XXXXXXG XXXX
マウスをクリックすると雪の画像を配置します。
ドラッグすることで配置する画像のサイズを変更できます。
雪の画像のサイズを決めるときに、雪の結晶の見た目の半径が
ドラッグ開始点からドラッグ終了点までの距離になるよう工夫しました。
EyeSwitchをONにすると雪だるまの目がマウスカーソルを追うようになります。
以下のボタンを付け加えました。
・ランダムでいくつかの雪の画像を配置するボタン
・直前に配置した雪の画像をひとつ消すボタン
・配置した雪の画像をすべて消すボタン
・雪だるまの目がマウスカーソルの方向を見るスイッチのボタン
・ウィンドウを閉じるボタン
ボタンと同じ機能を持つメニューを付け加えました。
ランダム配置する画像の数を変更できるスクロールバーを付け加えました。
**********************************************************************/
import java.awt.*; //AWTを使うためにインポート
import java.awt.event.*; //イベント用にインポート
import java.util.*; //乱数、Vectorのためにインポート
class Snow{
//ドラッグの始点、終点のX、Y座標を保持
public int snowX, snowY, snowSizeX, snowSizeY;
//Snowのコンストラクタ
public Snow(int x1,int x2,int x3,int x4){
snowX = x1;
snowY = x2;
snowSizeX = x3;
snowSizeY = x4;
}
}
class MyCanvas extends Canvas
implements KeyListener, MouseListener, MouseMotionListener{
Vector snowArray; //snowの配列を保持する変数を宣言する
Image snow, backImage, offScreenImage; //Imageクラスの変数を宣言する
Graphics offScreenGraphics;
boolean eyeSwitch;
int leftEyeDirection, rightEyeDirection, mouseX, mouseY;
int snowAmount = 10; //ランダム配置する雪の数
Random r=new Random();
public MyCanvas(){
super();
snowArray = new Vector();
snow=Toolkit.getDefaultToolkit().getImage("snow.GIF");
eyeSwitch = false; //eyeSwitch OFF
setSize(400,450);
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=createImage(400,400); //offScreenImageを400x400のサイズで作成
offScreenGraphics=offScreenImage.getGraphics(); //offScreenImageに描画するための Graphics オブジェクト
}
paint(offScreenGraphics); //次の画面のイメージを作る
g.drawImage(offScreenImage,0,0,this); //イメージを本物のスクリーンに書き込む
}
public void paint(Graphics g){
if(backImage==null){ //400x400のサイズの背景用イメージを作成
backImage=createImage(400,400);
Graphics g1=backImage.getGraphics();
g1.setColor(Color.black); //黒色
g1.fillRect(0,0,400,400); //全体を塗り潰す
//月の描画
g1.setColor(new Color(220,220,100)); //薄い黄色
g1.fillOval(75,75,50,50);
g1.setColor(Color.black);
g1.fillOval(100,100,30,30);
//雪原(背面)の描画
for (int i=0;i<200;i++){
g1.setColor(new Color(i+55,i+55,i+55)); //グラデーション
g1.drawLine(0,i+200,400,i+200);
}
//雪だるま下の描画
for (int i=1;i<=20;i++){
g1.setColor(new Color(i*3+195, i*3+195, i*3+195)); //グラデーション
g1.fillOval(200-(int)((25-i)*2.5*.8), 300-(int)((25-i)*2.5*.8), (int)((25-i)*2.5*2), (int)((25-i)*2.5*2));
}
//雪だるま上の描画
for (int i=1;i<=20;i++){
g1.setColor(new Color(i*3+195, i*3+195, i*3+195)); //グラデーション
g1.fillOval(200-(int)((25-i)*2*.8), 220-(int)((25-i)*2*.8), (int)((25-i)*2*2), (int)((25-i)*2*2));
}
//顔の描画
g1.setColor(new Color(250,200,150)); //オレンジ
int[] xs={170,195,200,202,200,195};
int[] ys={241,231,234,241,249,252};
g1.fillPolygon(xs,ys,6); //鼻の描画
g1.setColor(Color.black); //黒色
}
g.drawImage(backImage,0,0,this);
if(eyeSwitch){
//目の中心としたマウスカーソルの直交座標を極座標に変換し
//それぞれの目から見たマウスカーソルの位置を角度で表す
leftEyeDirection = (int)(Math.atan2(-(mouseY-220), mouseX-185)/Math.PI*180);
rightEyeDirection = (int)(Math.atan2(-(mouseY-220), mouseX-215)/Math.PI*180);
}
g.fillArc(180,210,10,20,leftEyeDirection+20,320); //左目の描画
g.fillArc(210,210,10,20,rightEyeDirection+20,320); //右目の描画
int size=snowArray.size();
for(int i=0;i< size;i++){
Snow s=(Snow)snowArray.elementAt(i);
//ドラッグ開始点から終了点までの距離を求めて雪の結晶の見た目の半径にする
int snowSize = (int)Math.sqrt(Math.pow(s.snowX-s.snowSizeX,2)+Math.pow(s.snowY-s.snowSizeY,2))+1;
//雪の画像のサイズを上で求めた半径の2倍にして
//ドラッグ開始点が中心になるように画像を配置する
g.drawImage(snow, s.snowX-snowSize, s.snowY-snowSize, snowSize*2, snowSize*2, this);
}
}
//--------- Key event ----------------------------------------
public void keyPressed(KeyEvent e){
int key=e.getKeyChar();
if(key=='q') System.exit(0); //qを押したら終了
}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
//------------------------------------------------------------
//--------- Mouse event --------------------------------------
public void mousePressed(MouseEvent e){
int mx=e.getX(); //マウスのX座標を得る
int my=e.getY(); //マウスのY座標を得る
snowArray.addElement(new Snow(mx,my,mx,my)); //配列SnowsのsnowCount番目に登録
repaint(); //再表示をおこなう
}
public void mouseReleased(MouseEvent e){
int mx=e.getX(); //マウスのX座標を得る
int my=e.getY(); //マウスのY座標を得る
Snow s=(Snow)snowArray.elementAt(snowArray.size()-1);
s.snowSizeX = mx;
s.snowSizeY = my;
repaint(); //再表示をおこなう
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseDragged(MouseEvent e){
int mx=e.getX(); //マウスのX座標を得る
int my=e.getY(); //マウスのY座標を得る
Snow s=(Snow)snowArray.elementAt(snowArray.size()-1);
s.snowSizeX = mx;
s.snowSizeY = my;
repaint(); //再表示をおこなう
}
public void mouseMoved(MouseEvent e){
if(eyeSwitch){
int mx=e.getX(); //マウスのX座標を得る
int my=e.getY(); //マウスのY座標を得る
mouseX = mx;
mouseY = my;
repaint(); //再表示をおこなう
}
}
//------------------------------------------------------------
//Delete処理
public void deleteSnow(){
int size;
if((size=snowArray.size())>0){
snowArray.removeElementAt(size-1);
repaint();
}
}
//Clear処理
public void clearSnow(){
snowArray.removeAllElements();
repaint();
}
//RandomSnow処理
public void randomSnow(){
for(int i=0; i < snowAmount; i++){
int snowX=r.nextInt(400);
int snowY=r.nextInt(400);
int snowR=r.nextInt(5)+3;
snowArray.addElement(new Snow(snowX,snowY,snowX+snowR,snowY));
}
repaint();
}
}
class Kadai1202 extends Frame implements ActionListener, AdjustmentListener{
MenuBar menuBar;
Menu fileMenu, snowMenu, eyeMenu;
MyCanvas myCanvas;
Button randomButton, deleteButton, clearButton, eyeButton, exitButton;
Scrollbar snowAmountBar;
Kadai1202(){
super("Kadai1202");
//メニューバーを作成する
menuBar=new MenuBar();
//Fileメニュー
fileMenu=new Menu("File");
fileMenu.add("Exit"); //fileMenuにExitメニューを加える
fileMenu.addActionListener(this); //メニュー選択時にKadai1202がイベントを受け取る
menuBar.add(fileMenu); //メニューバーにfileMenuを加える
//Snowメニュー
snowMenu=new Menu("Snow");
snowMenu.add("Clear");
snowMenu.add("Delete");
snowMenu.add("Random");
snowMenu.addActionListener(this);
menuBar.add(snowMenu);
//Eyeメニュー
eyeMenu=new Menu("Eye");
eyeMenu.add("Switch");
eyeMenu.addActionListener(this);
menuBar.add(eyeMenu);
//Frameにメニューバーを付け加える
setMenuBar(menuBar);
Panel panel=new Panel(); //パネル部分を作成する
panel.setLayout(new FlowLayout());
panel.add(randomButton=new Button("Snow * 10 "));
randomButton.addActionListener(this);
panel.add(snowAmountBar=new Scrollbar(Scrollbar.HORIZONTAL, 10, 10, 0, 110));
snowAmountBar.addAdjustmentListener(this);
panel.add(deleteButton=new Button("Delete"));
deleteButton.addActionListener(this);
panel.add(clearButton=new Button("Clear"));
clearButton.addActionListener(this);
panel.add(eyeButton=new Button("EyeSwitch:OFF"));
eyeButton.addActionListener(this);
panel.add(exitButton=new Button("X"));
exitButton.addActionListener(this);
setLayout(new BorderLayout()); //BorderLayoutを用いる
add(panel,"South"); //下部にPanelを配置
add(myCanvas=new MyCanvas(),"North"); //上部にMyCanbasを配置
//キー入力がbuttonに横取りされないようにするため
deleteButton.addKeyListener(myCanvas);
clearButton.addKeyListener(myCanvas);
setSize(getPreferredSize());
setVisible(true);
}
public void actionPerformed(ActionEvent e){
Object source=e.getSource();
if(source.equals(randomButton)){ //RandomSnowボタン
myCanvas.randomSnow();
} else if(source.equals(deleteButton)){//Deleteボタン
myCanvas.deleteSnow();
} else if(source.equals(clearButton)){ //Clearボタン
myCanvas.clearSnow();
} else if(source.equals(eyeButton)){ //Eyeボタン
if(myCanvas.eyeSwitch){
myCanvas.eyeSwitch=false;
eyeButton.setLabel("EyeSwitch:OFF");
} else {
myCanvas.eyeSwitch=true;
eyeButton.setLabel("EyeSwitch:ON");
}
} else if(source.equals(exitButton)){ //Exitボタン
System.exit(0);
}
else if(source.equals(fileMenu)){ //[File]メニュー
String command=e.getActionCommand();
if(command.equals("Exit")){ //Exitメニュー
System.exit(0);
}
} else if(source.equals(snowMenu)){ //[Snow]メニュー
String command=e.getActionCommand();
if(command.equals("Delete")){ //Delete メニュー
myCanvas.deleteSnow();
} else if(command.equals("Clear")){ //Clear メニュー
myCanvas.clearSnow();
} else if(command.equals("Random")){ //Random メニュー
myCanvas.randomSnow();
}
} else if(source.equals(eyeMenu)){ //[Eye]メニュー
String command=e.getActionCommand();
if(command.equals("Switch")){ //Switchメニュー
if(myCanvas.eyeSwitch){ //eye switchがONのときOFFに
myCanvas.eyeSwitch=false;
eyeButton.setLabel("EyeSwitch : OFF");
} else { //eye switchがOFFのときONに
myCanvas.eyeSwitch=true;
eyeButton.setLabel("EyeSwitch : ON");
}
}
}
}
//雪のランダム配置数用スクロールバーの値が変化したときの処理
public void adjustmentValueChanged(AdjustmentEvent e){
//スクロールバーの値を画像配置数にする
myCanvas.snowAmount=snowAmountBar.getValue();
//ランダム配置用ボタンのラベルを変える
randomButton.setLabel("snow * "+myCanvas.snowAmount);
}
public static void main(String args[]) {
//Kadai1202のインスタンスを作成 frameに代入
Kadai1202 frame=new Kadai1202();
}
}
コメント
解答例(2)
// XXXXXX XXXX
// 12/2の課題 雪だるまと月(改改)
//
// ---------葉の色をRGBで指定できるようにした。--------
// ほんとうはスクロールバー付近に色見本を置きたかったが、
// やり方がわからなかったので断念。
// 各コンポーネントに対し、setSize,setLocationで大きさ・位置を指定しようとしたが、
// うまくいかなかったのでJComponentのsetPreferredSizeでごまかしたが、
// 非常に野暮ったい配置になってしまった。
//
// -----------描いた木を削除できるようにした。---------
// 奥から何番目に挿入したかを保存する配列を用意し、描いた順に消えるようにした。
//
// ----------------------その他------------------------
// ウィンドウが何かで隠れ、再び表に出たときの再描画を高速化した。
import java.awt.*;// AWTを使うため
import java.awt.geom.*; // Graphics2を用いるため
import java.awt.event.*; // イベント駆動関係のクラスを用いるため
import java.awt.image.*; // イメージを使うため
import java.util.*; // random,Vectorを使うため
import javax.swing.*; // (1)
import javax.swing.event.*; // (2)
// 木描画クラス
class Tree{
// x,y座標および高さの値をintで保持する
public int x,y,h;
// Treeのコンストラクタ
public Tree(int n1,int n2,int n3){
x=n1;
y=n2;
h=n3;
}
}
// Canvasクラスのサブクラス、MyCanvas
// KeyListener,MouseListenerをインプリメント
class MyCanvas extends Canvas implements KeyListener, MouseListener{
// イメージを表す Image クラスの変数 image の宣言
Image image,showImage;
// Vectorクラスの変数 treeArray,addNumArrayの宣言
Vector treeArray;
int[] addNum;
int arraySize;
// 木の高さ決定用ランダム
Random ran=new Random();
// 月描画用変数の宣言
int moonX,moonY;
// コンストラクタの宣言
public MyCanvas(){
super();
// 月画像読込
image=Toolkit.getDefaultToolkit().getImage("moon.png");
// treeArrayのインスタンスを作成
treeArray=new Vector();
addNum=new int[10];
arraySize=0;
// サイズは600*600
setSize(600,600);
// 月の初期位置は550
rotateImage(550);
// EventListnerを関連づける
addKeyListener(this);
addMouseListener(this);
}
// KeyListenerを実装するためのメソッド
public void keyPressed(KeyEvent e){
// イベントからキーのコードを取り出す
int key=e.getKeyChar();
// デバッグ用の表示
System.out.println("keyPressed("+e+","+key+")");
// 入力が 'q'の時は終了する
if(key=='q') System.exit(0);
}
// その他Keyイベント
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
// MouseListenerを実装するためのメソッド
// マウスのボタンを押した際に発生するイベントを以下のメソッドで捕まえる.
public void mousePressed(MouseEvent e){
if(e.getY()>300&&e.getX()<600){
// 下半分をクリックした時は、奥から順に木を追加する
Tree t;
// 描いた順を保存する配列が少ない時は倍にする
if (arraySize>=addNum.length){
int[] newaddNum=new int[arraySize*2];
System.arraycopy(addNum,0,newaddNum,0,arraySize);
addNum=newaddNum;
}
for(addNum[arraySize]=0;addNum[arraySize]< arraySize;addNum[arraySize]++){
t=(Tree)treeArray.elementAt(addNum[arraySize]);
if(t.y>e.getY())break;
}
treeArray.add(addNum[arraySize],new Tree(e.getX(),e.getY(),
// 木の高さは、奥行きに応じた標準サイズに対し標準偏差6.7%で分布
(int)((e.getY()*4/3-350)*(ran.nextGaussian()+15)/15)));
arraySize++;
repaint();
}else if(e.getX()>35&&e.getX()<565){
// 上半分をクリックした時は、そのx座標に月を回転移動する
rotateImage(e.getX());
repaint();
}
}
// その他Mouseイベント
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
// "木を1本削除"ボタンが押された時の処理
public void deleteTree(){
if(arraySize>=0){
treeArray.removeElementAt(addNum[arraySize-1]);
arraySize--;
repaint();
}
}
// "木を全部削除"ボタンが押された時の処理
public void clearTree(){
treeArray.removeAllElements();
arraySize=0;
repaint();
}
// オフスクリーン描画用変数の宣言
Image offScreenImage;
Graphics offScreenGraphics;
// updateメソッド
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=createImage(600,600);
offScreenGraphics=offScreenImage.getGraphics();
}
paint(offScreenGraphics);
g.drawImage(offScreenImage,0,0,this);
}
// paintメソッド
public void paint(Graphics g){
if(g.equals(offScreenGraphics)){
// 木の追加・削除等でoffScreenを描き直すとき
// Grapchis2Dを保存
Graphics2D g2=(Graphics2D)g;
// アンチエイリアスを効かせる
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
// 背景塗りつぶし
g2.setColor(new Color(30,20,90));
g2.fillRect(0,0,600,300);
g2.setColor(new Color(90,110,150));
g2.fillRect(0,300,600,600);
// 月描画
g2.drawImage(showImage,moonX,moonY,this);
// 木描画
drawTrees(g2);
// 雪だるま2体描画
drawSnowmans(g2);
g2.setColor(new Color(160,165,170));
g2.fillRect(600,0,150,600);
}else if(offScreenImage==null){
//最初はこちら
update(g);
}else{
//単なる再描画のときはこちら
g.drawImage(offScreenImage,0,0,this);
}
}
// 月回転メソッド
void rotateImage(int pressedX){
// 画像情報を入出力する配列の宣言
int[] pixels = new int[101*101];
int[] showPixels = new int[71*71];
// 月の横位置から角度angleを宣言・代入
double angle=Math.acos(pressedX/300.0-1.0);
// angleのcos,sinを宣言・代入
double sin=Math.sin(angle),cos=Math.cos(angle);
// 新しい座標とその小数点以下の変数の宣言
double newx,newy,dx,dy;
// 各チャンネル値データを入れる計算用変数の宣言
double pix;
// 月の位置を決定
moonX=pressedX-35;
moonY=(int)(365-300*sin);
// imageからpixelsにgrabするためのオブジェクトを生成する
PixelGrabber pg = new PixelGrabber(image, 0, 0, 101, 101, pixels, 0, 101);
try {
// grabを開始する.
pg.grabPixels();
} catch (InterruptedException ie) {
System.err.println("interrupted waiting for pixels!");
System.exit(1);
}
// 失敗したかどうか?
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("image fetch aborted or errored");
return;
}
// 補完処理を働かせた回転処理
for (int i=0;i<71;i++){
for (int j=0;j<71;j++){
newx=(j-35)*cos-(i-35)*sin+50;
newy=(j-35)*sin+(i-35)*cos+50;
dx=newx-(int)newx;
dy=newy-(int)newy;
showPixels[i*71+j]=0;
for (int m=0;m<4;m++){// alpha,r,g,b各チャンネルのループ
pix=0;
for (int k=0;k<2;k++){ // 参照するy座標のループ
for (int l=0;l<2;l++){ // 参照するx座標のループ
// dx,dyに応じて、参照するピクセルの値をどれくらい加重するか決める
pix=pix+((1-l)+(2*l-1)*dx)*((1-k)+(2*k-1)*dy)*
// 参照するピクセルでの、現在のチャンネルの値を取り出す
((pixels[(int)(newy+k)*101+(int)(newx+l)]>>(8*m)) & 0xff);
}
}
// 現在のチャンネルの値を、表示するピクセルに入れる
showPixels[i*71+j]+=(int)pix<<(8*m);
}
}
}
// 表示する月のImageを作る
showImage=createImage(new MemoryImageSource(71,71,showPixels,0,71));
}
// 雪だるまリフレクト描画用変数・メソッドの宣言
int r;
float x(float xx){
return r*xx + 355f;
}
int ix(float xx){
return (int)x(xx);
}
// 雪だるま描画メソッド
void drawSnowmans(Graphics2D g2){
for(r=-1;r<=1;r=r+2){
// ボディ
g2.setColor(Color.white);
g2.fillOval(ix(100)-75,428,150,150);
g2.fillOval(ix(100)-60,338,120,120);
// 腕
GeneralPath arm = new GeneralPath();
arm.moveTo(x(0),447.7f);
arm.lineTo(x(50.2f),472.3f);
arm.lineTo(x(45.5f),481.8f);
arm.lineTo(x(-4.6f),457.2f);
arm.closePath();
g2.setColor(new Color(130,80,40));
g2.fill(arm);
// 鼻
GeneralPath nose = new GeneralPath();
nose.moveTo(x(30.0f),374.9f);
nose.lineTo(x(42.7f),384.9f);
nose.lineTo(x(46.1f),373.6f);
nose.closePath();
g2.setColor(Color.black);
g2.fill(nose);
// 目
GeneralPath eye = new GeneralPath();
eye.moveTo(x(62.3789f),371.4912f);
eye.curveTo(x(61.3252f),374.6484f,x(58.9043f),376.6846f,x(56.9736f),376.04f);
eye.curveTo(x(55.0439f),375.3955f,x(54.333f),372.3125f,x(55.3877f),369.1563f);
eye.curveTo(x(56.4414f),366f,x(58.8623f),363.9639f,x(60.792f),364.6094f);
eye.curveTo(x(62.7227f),365.2529f,x(63.4336f),368.3359f,x(62.3789f),371.4912f);
eye.closePath();
g2.setColor(Color.black);
g2.fill(eye);
// バケツここから
// 側面
GeneralPath bucket1 = new GeneralPath();
bucket1.moveTo(x(114.6f),308.8f);
bucket1.lineTo(x(156.1f),327.0f);
bucket1.lineTo(x(150.1f),364.8f);
bucket1.lineTo(x(90.8f),338.7f);
bucket1.closePath();
g2.setColor(new Color(80-r*70,10,80+r*70));
g2.fill(bucket1);
// 上面
GeneralPath bucket2 = new GeneralPath();
bucket2.moveTo(x(149.9395f),365.3574f);
bucket2.curveTo(x(148.2129f),369.291f,x(133.5107f),366.6367f,x(117.1035f),359.4307f);
bucket2.curveTo(x(100.6963f),352.2246f,x(88.7959f),333.1953f,x(90.5225f),339.2637f);
bucket2.curveTo(x(92.25f),335.3291f,x(106.9512f),337.9834f,x(123.3604f),345.1885f);
bucket2.curveTo(x(139.7666f),352.3945f,x(151.668f),361.4238f,x(149.9395f),365.3574f);
bucket2.closePath();
g2.setColor(new Color(80-r*70,10,80+r*70));
g2.fill(bucket2);
// 下面
GeneralPath bucket3 = new GeneralPath();
bucket3.moveTo(x(156.0068f),327.3721f);
bucket3.curveTo(x(157.2334f),324.5791f,x(148.9102f),318.2256f,x(137.418f),313.1777f);
bucket3.curveTo(x(125.9238f),308.1299f,x(115.6133f),306.2998f,x(114.3867f),309.0938f);
bucket3.curveTo(x(113.1602f),311.8857f,x(121.4814f),318.2412f,x(132.9775f),323.2891f);
bucket3.curveTo(x(144.4697f),328.3369f,x(154.7813f),330.165f,x(156.0068f),327.3721f);
bucket3.closePath();
g2.setColor(new Color(80-r*70,10,80+r*70));
g2.fill(bucket3);
// バケツここまで
}
}
public Color treeColor=new Color(26,120,29);
// trees 描画メソッド
void drawTrees(Graphics2D g2){
Tree t;
for(int i=0;i< arraySize;i++){
t=(Tree)treeArray.elementAt(i);
// 幹の描画
g2.setColor(new Color(120,87,26));
g2.fillRect(t.x-(int)(t.h*0.03),t.y-(int)(t.h*0.24),(int)(t.h*0.06),(int)(t.h*0.24));
// 葉の描画
GeneralPath leaves = new GeneralPath();
leaves.moveTo(t.x,(float)(t.y-1*t.h));
leaves.lineTo((float)(t.x-0.14*t.h),(float)(t.y-t.h*0.67));
leaves.lineTo((float)(t.x-0.05*t.h),(float)(t.y-t.h*0.70));
leaves.lineTo((float)(t.x-0.17*t.h),(float)(t.y-t.h*0.42));
leaves.lineTo((float)(t.x-0.08*t.h),(float)(t.y-t.h*0.45));
leaves.lineTo((float)(t.x-0.2*t.h),(float)(t.y-t.h*0.16));
leaves.lineTo(t.x,(float)(t.y-t.h*0.22));
leaves.lineTo((float)(t.x+0.2*t.h),(float)(t.y-t.h*0.16));
leaves.lineTo((float)(t.x+0.08*t.h),(float)(t.y-t.h*0.45));
leaves.lineTo((float)(t.x+0.17*t.h),(float)(t.y-t.h*0.42));
leaves.lineTo((float)(t.x+0.05*t.h),(float)(t.y-t.h*0.70));
leaves.lineTo((float)(t.x+0.14*t.h),(float)(t.y-t.h*0.67));
leaves.closePath();
g2.setColor(treeColor);
g2.fill(leaves);
}
}
}
class Kadai1202 extends Frame implements ActionListener{
// 各コンポーネントの宣言
MyCanvas myCanvas;
ColorCanvas colorCanvas;
Button changeButton,deleteButton,clearButton,quitButton;
public JScrollBar[] colorBar=new JScrollBar[3];
public int[] setcolors=new int[3];
JLabel[] colorLabel=new JLabel[3];
// 各コンポーネントはBOXに収納
Box bigBox,colorBox,treeBox;
Kadai1202(){
super("Kadai1202");
// 各コンポーネントの初期化
add(myCanvas=new MyCanvas());
// スクロールバーの初期値は描画初期値と同じ
setcolors[0]=myCanvas.treeColor.getRed();
setcolors[1]=myCanvas.treeColor.getGreen();
setcolors[2]=myCanvas.treeColor.getBlue();
bigBox=new Box(BoxLayout.Y_AXIS);
treeBox=new Box(BoxLayout.Y_AXIS);
colorBox=new Box(BoxLayout.Y_AXIS);
// 右側に寄せるのでBorderLayout
setLayout(new BorderLayout());
// Scrollbar,Label
String[] colorName={"Red","Green","Blue"};
for(int i=0;i<3;i++){
colorLabel[i]=new JLabel(colorName[i]);
colorBox.add(colorLabel[i]);
colorBar[i]=new JScrollBar(Scrollbar.HORIZONTAL, 0, 9, 0, 255);
colorBar[i].setPreferredSize(new Dimension(105,20));
colorBar[i].setValue(setcolors[i]);
colorBar[i].addKeyListener(myCanvas);
colorBox.add(colorBar[i]);
}
bigBox.add(colorBox);
// Button類
changeButton=new Button("葉の色を変える");
deleteButton=new Button("木を一本削除");
clearButton=new Button("木を全て削除");
quitButton=new Button("終了");
bigBox.add(changeButton);
treeBox.add(deleteButton);
treeBox.add(clearButton);
treeBox.add(quitButton);
changeButton.addActionListener(this);
quitButton.addActionListener(this);
deleteButton.addActionListener(this);
clearButton.addActionListener(this);
changeButton.addKeyListener(myCanvas);
quitButton.addKeyListener(myCanvas);
deleteButton.addKeyListener(myCanvas);
clearButton.addKeyListener(myCanvas);
bigBox.add(treeBox);
// bigBoxをframeに追加
add(bigBox,BorderLayout.EAST);
setSize(750,600);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
Object source=e.getSource();
if(source.equals(deleteButton)){
myCanvas.deleteTree();
}else if (source.equals(clearButton)){
myCanvas.clearTree();
}else if (source.equals(quitButton)){
System.exit(0);
}else if (source.equals(changeButton)){
// 色を変えるボタンを押したときは、myCanvasのtreeColorを変更し、update
myCanvas.treeColor=new Color(colorBar[0].getValue(),colorBar[1].getValue(),colorBar[2].getValue());
myCanvas.update(myCanvas.getGraphics());
}
}
public static void main(String args[]){
Kadai1202 frame=new Kadai1202();
}
}
コメント
解答例(3)
//名前:XXXXX
//学生証番号:XXXXX
/*説明:まず、これまでのKadai1125をFrameクラスのサブクラスではなくCanvasクラスのサブクラスにする。名前もCanvas1202とした。
また、Canvas1202にquitLineなどといったメソッドを作っておきそれぞれのアクションに対しての反応を登録しておく。
Kadai1202はFrameクラスのサブクラスにしてGUI部品の配置をしてそれぞれの反応をquitLineなどに送る。*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class Moon{
public int xm,ym;
public Moon(int x1,int x2){
xm=x1;
ym=x2;
}
}
class Canvas1202 extends Canvas implements KeyListener, MouseListener, MouseMotionListener{
Vector moonArray;
int n=0;
public Canvas1202(){
super();
moonArray=new Vector();
moonArray.addElement(new Moon(60,60));
setSize(400,450);
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
Image offScreenImage;
Graphics offScreenGraphics;
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=createImage(400,400);
offScreenGraphics=offScreenImage.getGraphics();
}
paint(offScreenGraphics);
g.drawImage(offScreenImage,0,0,this);
}
public void paint(Graphics g){
g.setColor(Color.black);
g.fillRect(0,0,400,175);
Moon m=(Moon)moonArray.elementAt(n);
g.setColor(Color.yellow);
g.fillOval(m.xm,m.ym,50,50);
g.setColor(Color.black);
g.fillOval(m.xm,m.ym,40,40);
if(m.ym>175){
Image image=Toolkit.getDefaultToolkit().getImage("sun.png");
g.drawImage(image,0,0,this);
}
g.setColor(Color.lightGray);
g.fillRect(0,175,400,225);
g.setColor(Color.white);
g.fillOval(225,120,100,100);
g.fillOval(215,210,120,120);
g.setColor(Color.blue);
g.fillOval(270,230,10,10);
g.fillOval(270,250,10,10);
g.fillOval(270,270,10,10);
g.setColor(Color.black);
g.fillRect(245,140,20,4);
g.fillRect(285,140,20,4);
g.fillOval(250,155,10,10);
g.fillOval(290,155,10,10);
g.fillRect(273,165,4,20);
g.fillRect(260,200,30,4);
}
public void quitLine(){
System.exit(0);
}
public void undoLine(){
n--;
if(n<0){
n=0;
}
repaint();
}
public void redoLine(){
n++;
if(n>=moonArray.size()){
n--;
}
repaint();
}
public void clearLine(){
moonArray.clear();
moonArray.addElement(new Moon(60,60));
n=0;
repaint();
}
public void keyPressed(KeyEvent e){
int key=e.getKeyChar();
System.out.println("keyPressed("+e+","+key+")");
if(key=='q'){
quitLine();
}
if(key=='u'){
undoLine();
}
if(key=='r'){
redoLine();
}
if(key=='c'){
clearLine();
}
}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){
int xg=e.getX();
int yg=e.getY();
System.out.println("mouseClicked("+e+","+xg+","+yg+")");
for(int i=n+1;i<=moonArray.size()-1;){
moonArray.remove(i);
}
moonArray.addElement(new Moon(xg,yg));
n++;
repaint();
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseDragged(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
}
class Kadai1202 extends Frame implements ActionListener{
MenuBar menuBar;
Menu fileMenu,editMenu;
Canvas1202 canvas1202;
Button quitButton,undoButton,redoButton,clearButton;
Kadai1202(){
super("Kadai1202");
menuBar=new MenuBar();
fileMenu=new Menu("File");
fileMenu.add("Quit(q)");
fileMenu.addActionListener(this);
menuBar.add(fileMenu);
editMenu=new Menu("Edit");
editMenu.add("Undo(u)");
editMenu.add("Redo(r)");
editMenu.addSeparator();
editMenu.add("Clear(c)");
editMenu.addActionListener(this);
menuBar.add(editMenu);
setMenuBar(menuBar);
Panel panel=new Panel();
panel.setLayout(new FlowLayout());
panel.add(undoButton=new Button("Undo(u)"));
undoButton.addActionListener(this);
panel.add(redoButton=new Button("Redo(r)"));
redoButton.addActionListener(this);
panel.add(clearButton=new Button("Clear(c)"));
clearButton.addActionListener(this);
panel.add(quitButton=new Button("Quit(q)"));
quitButton.addActionListener(this);
setLayout(new BorderLayout());
add(panel,"South");
add(canvas1202=new Canvas1202(),"North");
undoButton.addKeyListener(canvas1202);
redoButton.addKeyListener(canvas1202);
clearButton.addKeyListener(canvas1202);
quitButton.addKeyListener(canvas1202);
setSize(getPreferredSize());
setVisible(true);
}
public void actionPerformed(ActionEvent e){
System.out.println(e);
Object source=e.getSource();
if(source.equals(undoButton)){
canvas1202.undoLine();
}
else if(source.equals(redoButton)){
canvas1202.redoLine();
}
else if(source.equals(clearButton)){
canvas1202.clearLine();
}
else if(source.equals(quitButton)){
canvas1202.quitLine();
}
else if(source.equals(editMenu)){
String command=e.getActionCommand();
if(command.equals("Undo(u)")){
canvas1202.undoLine();
}
else if(command.equals("Redo(r)")){
canvas1202.redoLine();
}
else if(command.equals("Clear(c)")){
canvas1202.clearLine();
}
}
else if(source.equals(fileMenu)){
String command=e.getActionCommand();
if(command.equals("Quit(q)")){
canvas1202.quitLine();
}
}
}
public static void main(String args[]){
Kadai1202 frame=new Kadai1202();
}
}
コメント
解答例(4)
//XXXX XXXXX 雪だるまと月の絵です。
//左上のあたりをマウスでクリックすると、星が流れてきます。
// AWTを使うので java.awt.*を import する
import java.awt.*;
// イベント駆動関係のクラスを用いるため
import java.awt.event.*;
//Vectorクラスを用いるため
import java.util.*;
//星のクラスを定義する
class Star{
//星の場所をintで保持する
public int place_x,place_y;
//Starのコンストラクタをつくる
public Star(int x1,int y1){
place_x=x1;
place_y=y1;}
}
// 独立したウィンドウを開くので,Frameクラスのサブクラスにする
class Kadai1202 extends Frame implements KeyListener, MouseListener, MouseMotionListener,ActionListener{
// イメージを表す Image クラスの変数 image の宣言
Image image1,image2;
Vector starArray;
MenuBar menuBar;
Menu fileMenu,editMenu;
Button button;
Random r= new Random();
String message="";
// Delete ボタンが押された時の処理
public void deleteStar(){
int size;
if((size=starArray.size())>0){
starArray.removeElementAt(size-1);
repaint();
}
}
// Clear ボタンが押された時の処理
public void clearStar(){
starArray.removeAllElements();
repaint();
}
public Kadai1202(String title){
super(title);
// GUI部品と,Event Listenerを関連づける
// KeyAdapterは,KeyListenerを実装して中身は何もないクラス
// new クラス名(){} で,「クラス名」の名前のない子クラスを
//定義すると同時に
// インスタンスを作る
// 現在の Toolkit を得て,getImageで PNG 形式のファイルを指定して,
// イメージを得る.
image1=Toolkit.getDefaultToolkit().getImage("star.png");
image2=Toolkit.getDefaultToolkit().getImage("snowman.png");
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
starArray=new Vector();
// メニューバーを作成する
menuBar=new MenuBar();
// Fileというメニュー
fileMenu=new Menu("File");
fileMenu.add("Exit");
// メニューが選択された時に, CanvasTestがイベントを受け取る
fileMenu.addActionListener(this);
// メニューバーにfileMenuを加える.
menuBar.add(fileMenu);
editMenu=new Menu("Edit");
editMenu.add("Clear");
editMenu.add("Delete");
editMenu.addActionListener(this);
menuBar.add(editMenu);
// Frameにメニューバーを付け加える.
setMenuBar(menuBar);
setLayout(new FlowLayout());
// 「Theme」というラベルを持つボタンを作り,window中に配置
add(button= new Button("Theme"));
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
System.out.println(e);
Object source=e.getSource();
if(source instanceof Button){
String label=e.getActionCommand();
// 押されたボタンのラベルが"Theme"かどうかのチェック
if(label.equals("Theme")){
message="winter in the dark";
repaint();
}
}
// [Edit]メニューのどれかが選択された時
else if(source.equals(editMenu)){
String command=e.getActionCommand();
// Delete メニューが選択された時
if(command.equals("Delete")){
deleteStar();
}
// Clear メニューが選択された時
else if(command.equals("Clear")){
clearStar();
}
}
// [File]メニューのどれかが選択された時
else if(source.equals(fileMenu)){
String command=e.getActionCommand();
// Exitメニューが選択された時
if(command.equals("Exit")){
System.exit(0);
}
}
}
public static void main(String args[]){
Kadai1202 frame = new Kadai1202("Kadai1202");
//フレームのサイズをきめてつくる
frame.setSize(400,400);
frame.setVisible(true);
}
// インスタンス変数にしたがって描画するコードを書く
public void paint(Graphics g){
int i;
g.setColor(Color.black);
g.fillRect(0,0,400,200);
g.setColor(Color.blue);
g.fillRect(0,200,400,250);
g.setColor(new Color(230,230,230));
g.fillRect(0,250,400,400);
g.setColor(Color.red);
g.fillArc(260,60,60,60,0,360);
g.setColor(Color.white);
g.fillArc(100,190,70,70,0,360);
g.fillArc(100,250,100,100,0,360);
g.setColor(Color.blue);
g.fillArc(130,220,10,10,0,360);
g.fillArc(150,210,10,10,0,360);
g.setColor(Color.black);
g.drawLine(190,280,220,250);
g.drawLine(110,300,75,290);
g.setColor(Color.red);
g.fillArc(150,270,10,10,0,360);
g.fillArc(155,290,10,10,0,360);
g.fillArc(160,310,10,10,0,360);
int size=starArray.size();
for(i=0;i250&(l.place_x>200||l.place_x<70 ))
g.drawImage(image2,l.place_x,l.place_y,30,30,this);
}
for(int j=0;j<400;j++){
int snow_x=r.nextInt(400);
int snow_y=r.nextInt(400);
int snow_r=r.nextInt(6)+1;
g.setColor(Color.white);
g.fillOval(snow_x,snow_y,snow_r,snow_r);
}
g.setColor(Color.black);
g.drawString(message,250,300);
}
public void keyPressed(KeyEvent e){
int key=e.getKeyChar();
// 入力したキーのコードが「q」だった時は終了するl
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+")");
//星の場所を登録
starArray.addElement(new Star(mx,my));
// 再表示をおこなう
repaint();
}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseDragged(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
}
コメント
解答例(5
// ===============================================
// Kadai1202 "Snow Man - Ver 1.2"
// for 2 Dec., 2003 PROGRAMMING I ( T.Tanaka )
//
// Copyright(c) XXXXX, all rights reserved.
// ===============================================
//
// XXXXX XXXXX ---
// *
// * [ver1.0 2003/11/11]
// * 月と雪だるまを描画するJAVAプログラムです。
// * Graphicsクラスに含まれていない陰影のついた円を描く
// * 関数、fill3DOvalを作ることによって、ソフトな印象を
// * もった絵を描くことができました。
// *
// * [ver1.1 2003/11/25]
// * マウスの左クリックで星を、右クリックでカラフルな
// * 雪だるま(色はランダム)が追加できるようになっています。
// * 星の画像は外部ファイル"star.gif"からの読み込み。
// * 雪だるまは標準関数のみで描画しています。
// * 細かい修正として、ダブルバッファリングを採用しました。
// *
// * [ver1.2 2003/12/2]
// * 内部的な修正としては、描画を直接Frameにするのではなく
// * Canvasを用いました。
// * また、雪だるまの色をランダムにするか設定するかを設定
// * ようにし、スクロールバーで全ての色を設定することが
// * できます。
// *
// * ※課題完成していたのにも関わらず、情報棟に行くことが
// * できず、締め切りまでに提出することができませんでした。
// * 申し訳ありませんでした。
// *
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
class Kadai1202 extends Frame {
// ウィンドウのサイズ(タイトルバーを含む)
static final int SIZE= 400;
static final int X = SIZE, Y = SIZE;
// 雪の個数
static final int SNOW_NUMBER = 300;
// fill3DOvalの陰影の強さ(0:なし, 1:線形, ...)
static final int SHADE_STRENGTH = 20;
static int r = 255, g = 255, b = 255;
// 雪だるまと星の管理用
static Vector snowMen = new Vector();
static Vector star = new Vector();
static MainCanvas mainCanvas;
static Scrollbar scrollBar1;
static Scrollbar scrollBar2;
static Scrollbar scrollBar3;
static Checkbox checkBox;
/**
* Kadai1202のコンストラクタ
* @param title ウィンドウのタイトル
*
* 外部からのnewは不可
*/
Kadai1202(String title) {
super(title);
Label label1 = new Label("赤");
Label label2 = new Label("緑");
Label label3 = new Label("青");
Label label4 = new Label("色をランダムに");
addWindowListener(new WindowListener() {
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowClosing(WindowEvent e) { dispose(); }
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
});
scrollBar1 = new Scrollbar(Scrollbar.HORIZONTAL, 255, 20, 0, 255);
scrollBar2 = new Scrollbar(Scrollbar.HORIZONTAL, 255, 20, 0, 255);
scrollBar3 = new Scrollbar(Scrollbar.HORIZONTAL, 255, 20, 0, 255);
checkBox = new Checkbox("");
checkBox.setState(false);
scrollBar1.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
r = e.getValue();
}
});
scrollBar2.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
g = e.getValue();
}
});
scrollBar3.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
b = e.getValue();
}
});
setLayout(null);
mainCanvas = new MainCanvas(X, Y);
add(mainCanvas);
add(scrollBar1);
add(scrollBar2);
add(scrollBar3);
add(label1);
add(label2);
add(label3);
add(label4);
add(checkBox);
mainCanvas.setBounds(0, 0, X, Y);
scrollBar1.setBounds(X+40, 50, 80, 16);
scrollBar2.setBounds(X+40, 70, 80, 16);
scrollBar3.setBounds(X+40, 90, 80, 16);
setSize(X+120, Y+16);
checkBox.setBounds(X+5, 30, X+120, 16);
label1.setBounds(X+5, 50, X+120, 16);
label2.setBounds(X+5, 70, X+120, 16);
label3.setBounds(X+5, 90, X+120, 16);
label4.setBounds(X+30, 30, X+120, 16);
setVisible(true);
}
/** アプリケーションのエントリポイント */
public static void main(String[] args) {
Kadai1202 frame = new Kadai1202("雪だるま☆");
}
/** 陰影付の円を描画 */
public static void fill3DOval(Graphics g, int x, int y, int xlen, int ylen) {
Color c = g.getColor();
int len = Math.max(xlen, ylen);
int c_r, c_g, c_b;
g.fillOval(x, y, xlen, ylen);
x += xlen / 2;
y += ylen / 2;
for(float n = 0; n <= len / 2; n += 1.1 - n/len*2) {
c_r = (int)(c.getRed() * (1 - .3*Math.pow(n / (len / 2), SHADE_STRENGTH)));
c_g = (int)(c.getGreen() * (1 - .3*Math.pow(n / (len / 2), SHADE_STRENGTH)));
c_b = (int)(c.getBlue() * (1 - .3*Math.pow(n / (len / 2), SHADE_STRENGTH)));
// 周辺部にいくにしたがって、陰影が現れる
g.setColor(new Color(c_r, c_g, c_b));
g.drawOval((int)(x - n), (int)(y - n), (int)(n*2), (int)(n*2));
}
g.setColor(c);
}
public void paint(Graphics g) {
if(snowMen.size() == 0) addSnowMan(0.70, 0.65, Color.white);
mainCanvas.repaint();
}
public static void addSnowMan(double x, double y) {
if(checkBox.getState() == true)
// R,G,Bの要素がそれぞれ224〜255の範囲で動くランダムな色を生成
addSnowMan(x, y, new Color((int)(Math.random() * 32) + 224,
(int)(Math.random() * 32) + 224,
(int)(Math.random() * 32) + 224)
);
else
addSnowMan(x, y, new Color(r, g, b));
}
public static void addSnowMan(double x, double y, Color color) {
snowMen.add(new SnowMan(X, Y, SIZE, x, y, color));
mainCanvas.repaint();
}
public static void addStar(double x, double y) {
star.add(new Star(X, Y, SIZE, x, y, mainCanvas));
mainCanvas.repaint();
}
}
class SnowMan {
double x = 0, y = 0;
int X = 0, Y = 0, SIZE = 0;
Color color = null;
public SnowMan(int X, int Y, int SIZE, double x, double y, Color color) {
this.x = x;
this.y = y;
this.X = X;
this.Y = Y;
this.SIZE = SIZE;
if(color == null) this.color = Color.white;
else this.color = color;
}
void paint(Graphics g) {
g.setColor(color);
Kadai1202.fill3DOval(g, (int)(X*(x-.15)), (int)(Y*(y-.15)), (int)(SIZE*.30), (int)(SIZE*.30));
Kadai1202.fill3DOval(g, (int)(X*(x-.10)), (int)(Y*(y-.33)), (int)(SIZE*.20), (int)(SIZE*.20));
g.setColor(new Color(96, 96, 96));
Kadai1202.fill3DOval(g, (int)(X*(x-.07)), (int)(Y*(y-.25)), (int)(SIZE*.04), (int)(SIZE*.04));
Kadai1202.fill3DOval(g, (int)(X*(x+.03)), (int)(Y*(y-.25)), (int)(SIZE*.04), (int)(SIZE*.04));
Kadai1202.fill3DOval(g, (int)(X*(x-.01)), (int)(Y*(y-.20)), (int)(SIZE*.02), (int)(SIZE*.02));
}
}
class Star {
double x = 0, y = 0;
int X = 0, Y = 0, SIZE = 0;
Color color = null;
static Image image = null;
static ImageObserver ob = null;
public Star(int X, int Y, int SIZE, double x, double y, ImageObserver ob) {
if(image == null) image = Toolkit.getDefaultToolkit().getImage("./star.gif");
this.x = x;
this.y = y;
this.X = X;
this.Y = Y;
this.SIZE = SIZE;
this.ob = ob;
}
void paint(Graphics g) {
g.drawImage(image, (int)(X*x-16), (int)(Y*y-16), ob);
}
}
class MainCanvas extends Canvas {
final int X = Kadai1202.X, Y = Kadai1202.Y;
/**
* MainCanvasのコンストラクタ
*/
public MainCanvas(int x, int y) {
setSize(x, y);
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
int key = e.getKeyChar();
if(key == 'q') System.exit(0);
}
});
addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
switch(e.getButton()) {
case 1: // 左クリック
Kadai1202.addStar((double)e.getX() / (double)X, (double)e.getY() / (double)Y);
break;
case 3: // 右クリック
Kadai1202.addSnowMan((double)e.getX() / (double)X, (double)e.getY() / (double)Y);
break;
default:
repaint();
}
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
});
}
/** 画像の描画 */
public void paint(Graphics g_real) {
// ダブルバッファリング用バッファー
Image buffer = createImage(X, Y);
Graphics g = buffer.getGraphics();
// 空
for(int n = 0; n <= Y*.7; n++) {
g.setColor(new Color(0, 0, (int)(255 * (1 - n / (Y*.7)))));
g.drawLine(0, n, X, n);
}
// 雪面
for(int n = 0; n <= Y*.3; n++) {
int c = (int)(255 * Math.pow(n / (Y*.3), .7));
g.setColor(new Color(c, c, c));
g.drawLine(0, (int)(n + Y*.7), X, (int)(n + Y*.7));
}
// 雪だるま
for(int n = 0; n < Kadai1202.snowMen.size(); n++) {
((SnowMan)(Kadai1202.snowMen.get(n))).paint(g);
}
// 星
for(int n = 0; n < Kadai1202.star.size(); n++) {
((Star)(Kadai1202.star.get(n))).paint(g);
}
// 月
g.setColor(new Color(255, 255, 96));
g.fillArc((int)(X*.10), (int)(Y*.10), (int)(X*.12),
(int)(Y*.12), 240, 180);
// 雪
for(int n = 0; n < Kadai1202.SNOW_NUMBER; n++) {
int r = (int)((1 + Math.random()) * Kadai1202.SIZE/120);
int x = (int)(Math.random() * X);
int y = (int)(Math.random() * Y);
int c = (int)(239 + Math.random() * 16);
g.setColor(new Color(c, c, c));
Kadai1202.fill3DOval(g, (int)(x - r/2), (int)(y - r/2), r, r);
}
// 情報表示
g.setColor(Color.black);
g.drawString("星の個数:" + Integer.toString(Kadai1202.star.size()) + " / " +
"雪だるまの個数:" + Integer.toString(Kadai1202.snowMen.size()), 20, Y - 20);
// バッファの転送
g_real.drawImage(buffer, 0, 0, this);
}
}
コメント
解答例(6)
//名前:XXXXX
//学生証番号:XXXXX
//家のなかから見た風景です。基本的には長方形、楕円、多角形を塗り潰しただけの
//図形しか描いていません。
//マウスを押すと、その点をimageの左上の点として、星の絵を張り付けるようにしました。
//オフスクリーンイメージも利用しました。
//GUI部品の追加。題名と雪の色を変えるためのボタンをつけました。
//ただでさえ貧弱な装備に加えて、なぜかボタンを押しただけでは色は変化せず、
//一回絵の上でクリックしないと色が変わりません。
//原因を突き止めたかったのですが、時間切れです。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
//星のクラスを定義
class Star{
//張り付けるイメージの左上の点のX座標、Y座標をintで保持する。
public int start_x,start_y;
public Star(int x1,int x2){
start_x=x1;
start_y=x2;
}
}
//今回はKeyListenerとMouseListenerを実装
class Kadai1125 extends Canvas implements KeyListener,MouseListener{
Color snowColor;
Image image;
// Starの配列を保持するVectorクラスの変数 starArrayの宣言
Vector starArray;
// マウスをドラッグ中かどうかを示す boolean型(真偽値)の変数draggingの宣言
boolean dragging;
public Kadai1125(){
super();
// 背景が透明の星のイメージを得る。
image=Toolkit.getDefaultToolkit().getImage("test.png");
starArray=new Vector();
dragging=false;
//最初の雪の色は白
snowColor=Color.white;
addKeyListener(this);
addMouseListener(this);
}
//ウィンドウの作成
public static void main(String[] args){
Kadai1125 frame=new Kadai1125();
frame.setSize(400,400);
frame.setVisible(true);
}
//オフスクリーンイメージの作成
Image offScreenImage;
Graphics offScreenGraphics;
public void update(Graphics g){
if(offScreenImage==null){
offScreenImage=createImage(400,400);
offScreenGraphics=offScreenImage.getGraphics();
}
paint(offScreenGraphics);
g.drawImage(offScreenImage,0,0,this);
}
public void paint(Graphics g){
int i;
//月と雪だるまの絵
g.setColor(Color.orange);
g.fillRect(0,0,400,400);
g.setColor(Color.blue);
g.fillRect(40,40,320,320);
g.setColor(Color.black);
g.fillRect(60,60,132,132);
g.fillRect(60,208,132,92);
g.fillRect(208,60,132,132);
g.fillRect(208,208,132,92);
g.setColor(Color.lightGray);
g.fillRect(60,300,132,40);
g.fillRect(208,300,132,40);
g.setColor(Color.yellow);
g.fillOval(80,80,64,64);
g.setColor(Color.black);
g.fillOval(108,76,64,64);
//ここでセットしている色をボタンによって変える
g.setColor(snowColor);
g.fillOval(260,232,40,40);
g.fillOval(248,268,64,64);
g.fillOval(240,100,8,8);
g.fillOval(300,120,8,8);
g.fillOval(240,160,8,8);
g.fillOval(160,160,8,8);
g.fillOval(100,240,8,8);
g.fillOval(140,260,8,8);
g.setColor(Color.orange);
int[] xs0={240,244,264,260};
int[] ys0={268,264,284,288};
g.fillPolygon(xs0,ys0,4);
g.setColor(Color.cyan);
int[] xs1={262,300,300,281};
int[] ys1={242,252,222,217};
g.fillPolygon(xs1,ys1,4);
//
int size=starArray.size();
if(dragging) size--;
//イメージを張り付ける際の位置や大きさを設定
for(i=0;i< size;i++){
Star s=(Star)starArray.elementAt(i);
g.drawImage(image,s.start_x,s.start_y,30,30,this);
}
}
// キーを押した際に発生するイベント
public void keyPressed(KeyEvent e){
int key=e.getKeyChar();
// 入力したキーのコードが「q」だった時は終了する
if(key=='q') System.exit(0);
}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
//マウスを押した際に発生するイベント
public void mousePressed(MouseEvent e){
// 押された時のマウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
// デバッグ用の表示
System.out.println("mousePressed("+e+","+mx+","+my+")");
starArray.addElement(new Star(mx,my));
Star s=(Star)starArray.elementAt(starArray.size()-1);
//張り付け位置は押されたときのマウスカーソルの位置をイメージの左上の点とする。
s.start_x=mx;
s.start_y=my;
// 再表示をおこなう
repaint();
}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
//各種ボタンを押したときのイベント
public void redSnow(){
snowColor=Color.red;
}
public void blueSnow(){
snowColor=Color.blue;
}
public void whiteSnow(){
snowColor=Color.white;
}
}
class Kadai1202 extends Frame implements ActionListener{
Button button1,button2,button3;
Label label;
Kadai1125 kadai1125;
Kadai1202(){
super("Kadai1202");
//ボタンを横に並べたパネルをつくる。
Panel panel=new Panel();
panel.setLayout(new FlowLayout());
panel.add(button1=new Button("red"));
button1.addActionListener(this);
panel.add(button2=new Button("blue"));
button2.addActionListener(this);
panel.add(button3=new Button("return"));
button3.addActionListener(this);
//上からボタンの並ぶパネル、絵、題名というように並べる。
setLayout(new BorderLayout());
add(panel,"North");
add(kadai1125=new Kadai1125(),"Center");
add(label=new Label("月と雪だるま"),"South");
//キー入力がbuttonに横取りされないようにするため
button1.addKeyListener(kadai1125);
button2.addKeyListener(kadai1125);
button3.addKeyListener(kadai1125);
setSize(400,500);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
System.out.println(e);
Object source=e.getSource();
//"red"ボタンが押されたとき。以下同様
if(source.equals(button1)) kadai1125.redSnow();
if(source.equals(button2)) kadai1125.blueSnow();
if(source.equals(button3)) kadai1125.whiteSnow();
}
public static void main(String args[]){
Kadai1202 frame=new Kadai1202();
}
}
コメント
解答例(7)
//氏名 XXXX
//学生番号 XXXX
//マウスを"DrawSnow"と"DrawArc"をクリックしてから、マウスの入力に応じて月とだ//るましきに加えるプログラム
//座標を求めるためにtextfield に"123 234"のように入力し、もうちょっと手間がか//かる、ごめんなさいが、"return"を押してから画面の灰色ところにマウスをプレー///スし、そのとき、その点に"+"が出てくる
//"NewSearch"を押すと新しい採点を始める
// AWTを使うので java.awt.*を import する
import java.awt.*;
// イベント駆動関係のクラスを用いるため
import java.awt.event.*;
//Vectorクラスを用いるため
import java.util.*;
//円弧のクラスを定義する
class Arc {
// 円弧を覆う長方形の始点,終点のX座標,Y座標を int で保持する.
public int start1_x,start1_y,end1_x,end1_y;
// Arcのコンストラクタ
public Arc(int x1,int x2,int x3,int x4) {
start1_x=x1;
start1_y=x2;
end1_x=x3;
end1_y=x4;
}
}
//雪のクラスを定義する
class Snow{
//始点の座標、直径を保持する
public int start2_x,start2_y,r2;
// Circleのコンストラクタ
public Snow(int x1,int x2,int x3){
start2_x =x1;
start2_y=x2;
r2=x3;
}
}
// 独立したウィンドウを開くので,Frameクラスのサブクラスにする
// インタフェースの実装では 「implements インタフェース名」と書く
// 複数書く場合は,カンマで区切る
class Draw extends Canvas implements KeyListener,MouseListener,MouseMotionListener{
// Arc,Snowの配列を保持するVectorクラスの変数
Vector arcArray,snowArray;
// マウスをドラッグ中かどうかを示す boolean型(真偽値)の変数 draggingの宣言
boolean dragging;
// 表示する色を保持する変数
public Color arcColor,snowColor;
public int ch,x7=0,y7=0;
public Image image;
public Graphics g1;
//コンストラクタの宣言
public Draw() {
// 親クラス Frameのコンストラクタの宣言
super();
image=Toolkit.getDefaultToolkit().getImage("kadai1111.png");
arcArray=new Vector();
snowArray=new Vector();
// ドラッグ中ではない
dragging=false;
arcColor=Color.white;
snowColor=Color.white;
// GUI部品と,Event Listenerを関連づける
setSize(600,400);
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
Image offScreenImage;
Graphics offScreenGraphics;
public void update(Graphics g){
if(offScreenImage==null){
// オフスクリーンイメージを400x400のサイズで作成
offScreenImage=createImage(400,400);
// オフスクリーンイメージに描画するための Graphics オブジェクト
offScreenGraphics=offScreenImage.getGraphics();
}
paint(offScreenGraphics); // 次の画面のイメージを作る.
g.drawImage(offScreenImage,0,0,this); // イメージを本物のスクリーンに書き込 //む
}
//雪を描くためメソッド
void drawsnow(Graphics g,int x,int y,int r) {
Graphics2D g2=(Graphics2D)g;
// 座標系を45度(π/4)回転させる
g2.translate(x,y);
for(int i1=1;i1<=8;i1++) {
g2.rotate(Math.PI/4);
g2.drawLine(0,0,r,0);
}
//はじめの座標系を返す
g2.translate(-x,-y);
}
public void paint(Graphics g){
g.drawImage(image,0,50,this);
int i;
//textfieldの機能のため
g.setColor(Color.yellow);g.drawString("+",x7,y7);
switch(ch){
//雪を描く
case 1:
g.setColor(snowColor);
int size=snowArray.size();
if(dragging) size--;
for(i=0;i< size;i++){
Snow s=(Snow)snowArray.elementAt(i);
drawsnow(g,s.start2_x,s.start2_y,(int) Math.round(s.r2/2));
}
// マウスをドラッグ中の時は
if(dragging){
g.setColor(Color.white);
// snow[snowCount] を描画する.
Snow s=(Snow)snowArray.elementAt(i);
drawsnow(g,s.start2_x,s.start2_y,(int) Math.round((s.r2)/2));
}
//ここでを"break"書くと同時に雪と円弧を表させることができない
//円弧を描く
case 2:
g.setColor(arcColor);
int size1=arcArray.size();
if(dragging) size1--;
for(i=0;i< size1;i++){
Arc a=(Arc)arcArray.elementAt(i);
//簡単のため、startAngleとarcAngleを指定しておく
g.drawArc(a.start1_x,a.start1_y,(int)(a.end1_x-a.start1_x),(int)(a.end1_y-a.start1_y),150,210);
}
// マウスをドラッグ中の時は
if(dragging){
g.setColor(Color.white);
// arcs[arcCount] を描画する.
Arc a=(Arc)arcArray.elementAt(i);
g.drawArc(a.start1_x,a.start1_y,(int)(a.end1_x-a.start1_x),
(int)(a.end1_y-a.start1_y),150,210);
}
break; }
}
//KeyListenerを実装するためのメソッド
public void keyPressed(KeyEvent e){}
// 要らないイベントに対応するメソッドも中身は空
//で書いておく必要があ る.
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e){}
int bx,by;
//MouseListenerを実装するためのメソッド
public void mousePressed(MouseEvent e){
// 押された時のマウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
switch(ch) {
case 1:
bx=mx;
by=my;
// デバッグ用の表示
System.out.println("mousePressed("+e+","+mx+","+my+")");
// 配列snowsのsnowCount番目に雪を登録
snowArray.addElement(new Snow(bx,by,0));
// ドラッグ中であることを示す
dragging=true;
// 再表示をおこなう
repaint();
case 2:
// デバッグ用の表示
System.out.println("mousePressed("+e+","+mx+","+my+")");
// 配列arcsのarcCount番目に円弧を登録
arcArray.addElement(new Arc(mx,my,mx,my));
// ドラッグ中であることを示す
dragging=true;
// 再表示をおこなう
repaint();
break; }
}
// マウスのボタンが離された時のイベント
public void mouseReleased(MouseEvent e){
// マウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
switch(ch) {
case 1:
// デバッグ用の表示
System.out.println("mousePressed("+e+","+mx+","+my+")");
// 配列snowsのsnowCount番目の始点を変更
Snow s=(Snow)snowArray.elementAt(snowArray.size()-1);
//雪の直径を選ぶ
s.r2=Math.min((int)Math.abs(mx-bx),(int)Math.abs(my-by));
dragging=false;
// 再表示をおこなう
repaint();
break;
case 2:
// デバッグ用の表示
System.out.println("mousePressed("+e+","+mx+","+my+")");
// 配列arcsのarcCount番目の始点を変更
Arc a=(Arc)arcArray.elementAt(arcArray.size()-1);
a.end1_x=mx;
a.end1_y=my;
dragging=false;
// 再表示をおこなう
repaint();
break; }
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseDragged(MouseEvent e){
// マウスカーソルの位置を得る
int mx=e.getX(),my=e.getY();
switch(ch) {
case 1:
// デバッグ用の表示
System.out.println("mouseDrag("+e+","+mx+","+my+")");
// 配列snowsのsnowCount番目の始点を変更
Snow s=(Snow)snowArray.elementAt(snowArray.size()-1);
s.r2=Math.min((int)Math.abs(mx-bx),(int)Math.abs(my-by));
// 再表示をおこなう
repaint();
break;
case 2:
System.out.println("mouseDrag("+e+","+mx+","+my+")");
// 配列arcsのarcCount番目の始点を変更
Arc a=(Arc)arcArray.elementAt(arcArray.size()-1);
a.end1_x=mx;
a.end1_y=my;
// 再表示をおこなう
repaint();
break; }
}
public void mouseMoved(MouseEvent e){}
public void deleteSnow(){
int size;
if((size=snowArray.size())>0){
snowArray.removeElementAt(size-1);
repaint(); }
}
public void deleteArc() {
int size;
if((size=arcArray.size())>0){
arcArray.removeElementAt(size-1);
repaint(); }
}
public void clearSnow(){
snowArray.removeAllElements();
repaint(); }
public void clearArc() {
arcArray.removeAllElements();
repaint();
}
}
class Kadai1202 extends Frame implements ActionListener {
MenuBar menuBar;
Menu fileMenu,editMenu,toolMenu,colorMenu;
Draw draw;
Button deleteButton,clearButton,snowButton,arcButton,searchButton;
TextField textField;
Image image1;
Kadai1202() {
super("Kadai1202");
menuBar=new MenuBar();
fileMenu=new Menu("File");
fileMenu.add("Exit");
fileMenu.addActionListener(this);
menuBar.add(fileMenu);
editMenu=new Menu("Edit");
editMenu.add("Delete");
editMenu.add("Clear");
editMenu.addActionListener(this);
menuBar.add(editMenu);
toolMenu=new Menu("Tool");
toolMenu.add("SnowDraw");
toolMenu.add("ArcDraw");
colorMenu=new Menu("Color");
colorMenu.add("yellow");
colorMenu.add("red");
colorMenu.add("green");
colorMenu.add("blue");
colorMenu.addActionListener(this);
toolMenu.add(colorMenu);
toolMenu.addActionListener(this);
menuBar.add(toolMenu);
setMenuBar(menuBar);
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);
panel.add(snowButton=new Button("SnowDraw"));
snowButton.addActionListener(this);
panel.add(arcButton=new Button("ArcDraw"));
arcButton.addActionListener(this);
panel.add(searchButton=new Button("New Search"));
searchButton.addActionListener(this);
panel.add(textField=new TextField(10));
textField.addActionListener(this);
setLayout(new BorderLayout());
add(panel,"North");
draw=new Draw();
add(draw,"South");
deleteButton.addKeyListener(draw);
clearButton.addKeyListener(draw);
snowButton.addKeyListener(draw);
arcButton.addKeyListener(draw);
setSize(getPreferredSize());
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
System.out.println(e);
Object source=e.getSource();
if(source.equals(deleteButton))
switch(draw.ch) {
case 1:
draw.deleteSnow();
break;
case 2:
draw.deleteArc();
break; }
else if(source.equals(clearButton))
switch(draw.ch) {
case 1:
draw.clearSnow();
break;
case 2:
draw.clearArc();
break; }
else if(source.equals(snowButton)) draw.ch=1;
else if(source.equals(arcButton)) draw.ch=2;
else if(source.equals(searchButton)) textField.setText("");
else if(source.equals(textField)){
String s=textField.getText();
String[] data=new String[2];
data=s.split(" ",2);
int mx=Integer.parseInt(data[0]);
int my=Integer.parseInt(data[1]);
draw.ch=1;
draw.x7=mx;draw.y7=my;
}
else if(source.equals(editMenu)){
String command=e.getActionCommand();
if(command.equals("Delete"))
switch(draw.ch) {
case 1:
draw.deleteSnow();
break;
case 2:
draw.deleteArc();
break; }
else if(command.equals("Clear"))
switch(draw.ch) {
case 1:
draw.clearSnow();
break;
case 2:
draw.clearArc();
break; }
}
else if(source.equals(fileMenu)){
String command=e.getActionCommand();
if(command.equals("Exit")) System.exit(0);
}
else if(source.equals(toolMenu)){
String command=e.getActionCommand();
if(command.equals("SnowDraw")) draw.ch=1;
else if(command.equals("ArcDraw")) draw.ch=2;
}
else if(source.equals(colorMenu)) {
String command=e.getActionCommand();
if (command.equals("yellow"))
switch(draw.ch) {case 1:draw.snowColor=Color.yellow;break;
case 2:draw.arcColor=Color.yellow;break;}
if (command.equals("blue"))
switch(draw.ch) {case 1:draw.snowColor=Color.blue;break;
case 2:draw.arcColor=Color.blue;break;}
if (command.equals("green"))
switch(draw.ch) {case 1:draw.snowColor=Color.green;break;
case 2:draw.arcColor=Color.green;break;}
if (command.equals("red"))
switch(draw.ch) {case 1:draw.snowColor=Color.red;break;
case 2:draw.arcColor=Color.red;break;}
}
}
public static void main(String[] args) {
Kadai1202 frame=new Kadai1202();
}
}
コメント
解答例(8)
// 名前 : XXXX
// 学生証番号 : XXXX
// 説明 : AWTにより月と雪だるまを描画するプログラム・改2
// (前回) マウスの入力により次のような変化を与える
// 1.月及び雪だるまをドラッグにより移動させる
// 2.なにもないところでドラッグすると, ランダムに3色の星を書き込む
// (今回) GUI部品を使っての指示により, 次のような変化を与える
// 1.Delete ボタンを押すと星が一つ消える
// 2.Clear ボタンを押すと星がすべて消える
// 3.Checkbox により, 夜と昼を切り替える
// 4.昼は月の変わりに太陽が動くが, 固定された月の影に太陽が入ると
// 日食が起こる。元に戻すには隠れた太陽を月の外に出す
// 5.以上の機能をメニューバーにも搭載した
// AWTを使うので java.awt.*を import する
import java.awt.*;
// イベント駆動関係のクラスを用いるため
import java.awt.event.*;
// Randomクラス, Vectorクラスを用いるために必要
import java.util.*;
// "星"のクラスを定義する
class Star{
// x座標, y座標を int で保持する
public int st_x,st_y,st_color;
// Star のコンストラクタ
// Star(x座標,y座標,星の色)と指定する
public Star(int sx1,int sy1,int sc1){
st_x = sx1; st_y = sy1;
st_color = sc1;
}
}
// 描画用の領域として Canvas クラスのサブクラスを作る
class MyCanvas extends Canvas{
// Star の配列を保持する Vector クラスの変数 starArray の宣言
Vector starArray;
// 月や雪だるまのないところでドラッグ中ならば dragging = true
// 月の上にマウスカーソルがあれば moon = true
// 雪だるまの上にマウスカーソルがあれば snowman = true
boolean dragging, moon, snowman;
// (x1,y1)が月, (x2,y2)が雪だるまの座標を表す
int x1 = 55, y1 = 40, x2 = 230, y2 = 190;
Image star[] = new Image[3];
Image sun, sweat;
// Random に雪を降らせたり, 星の色を決めたりするための
// 乱数の元となるオブジェクトを作成
Random r = new Random();
// マウスで月や雪だるまをドラッグする際の相対的な座標を int で保持する
int dx, dy;
// night = true で夜, false で昼, eclipse = true で日食
boolean night = true, eclipse = false;
// コンストラクタ
public MyCanvas(){
super();
starArray = new Vector();
dragging = false;
int i;
for(i = 0; i < 3; i++){
star[i] = Toolkit.getDefaultToolkit().getImage("star"+i+".png");
}
sun = Toolkit.getDefaultToolkit().getImage("sun1.png");
sweat = Toolkit.getDefaultToolkit().getImage("sweat.png");
setSize(400, 400);
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
// "q" が押されたら終了
int key = e.getKeyChar();
if(key == 'q') System.exit(0);
}
});
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
int mx = e.getX(), my = e.getY();
// なにもないところでマウスボタンが押されたら星を一つ追加
// その際, Random に星の色を決める
// mc=0,1,2 がそれぞれ黄色, 青色, 赤色に対応
// 月(太陽)や雪だるまの上でマウスボタンが押されたら,
// 月や雪だるまに対する相対的な座標を記録する
if(night){
if(!moon & !snowman){
int mc = r.nextInt(3);
starArray.addElement(new Star(mx, my, mc));
dragging = true;
}
else if(moon){
dx = mx-x1; dy = my-y1;
}
else if(snowman){
dx = mx-x2; dy = my-y2;
}
}
else{
if(moon){
dx = mx-x1; dy = my-y1;
}
}
// 再表示をおこなう
repaint();
}
public void mouseReleased(MouseEvent e){
int mx = e.getX(), my = e.getY();
// マウスボタンが離されたら星の座標及び色を固定する
if(night){
if(!moon & !snowman){
Star s = (Star)starArray.elementAt(starArray.size()-1);
s.st_x = mx; s.st_y = my;
dragging = false;
}
repaint();
}
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
int mx = e.getX(),my = e.getY();
// マウスのドラッグに合わせて星, 月, 雪だるまを動かす
// ドラッグ中は星の色は変えない
if(night){
if(!moon & !snowman){
Star s = (Star)starArray.elementAt(starArray.size()-1);
s.st_x = mx; s.st_y = my;
}
else if(moon){
x1 = mx-dx; y1 = my-dy;
}
else if(snowman){
x2 = mx-dx;
// 雪だるまの下の部分が地平線から
// はみ出さないようにする
if (my > 157+dy) y2 = my-dy;
else y2 = 158;
}
eclipse = false;
}
else if(moon){
x1 = mx-dx; y1 = my-dy;
if(x1 < 21 & y1 < 11){
eclipse = true;
}
if(eclipse & (x1 > 40 | y1 > 30)){
eclipse = false;
}
}
repaint();
}
public void mouseMoved(MouseEvent e){
int mx = e.getX(), my = e.getY();
// マウスカーソルが月の上に入ったら moon = true
// 雪だるまの上に入ったら snowman = true
if(night){
if(mx > x2 & mx < x2+100 & my > y2-80 & my < y2+100){
moon = false; snowman = true;
}
else if(mx > x1 & mx y1 & my < y1+46){
moon = true; snowman = false;
}
else{
moon = false; snowman = false;
}
}
else{
if(mx > x1 & mx y1 & my < y1+46){
moon = true; snowman = false;
}
else{
moon = false; snowman = false;
}
}
}
});
}
Image offScreenImage;
Graphics offScreenGraphics;
public void update(Graphics g){
if(offScreenImage == null){
// offScreenImage に値を入れるので, 次回はif文は成立しない
offScreenImage = createImage(400, 400);
offScreenGraphics = offScreenImage.getGraphics();
}
paint(offScreenGraphics);
g.drawImage(offScreenImage, 0, 0, this);
}
public void paint(Graphics g){
int i;
// 遠いものや大きいものから配置する
// night = true (夜)のとき
if(night){
// 夜の空
g.setColor(new Color(25, 25, 112));
g.fillRect(0, 0, 400, 400);
// 星
int size = starArray.size();
if(dragging) size--;
for(i = 0; i < size; i++){
Star s = (Star)starArray.elementAt(i);
g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this);
}
if(dragging){
Star s = (Star)starArray.elementAt(size);
g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this);
}
// 三日月
g.setColor(new Color(255, 255, 204));
g.fillOval(x1, y1, 46, 46);
g.setColor(new Color(25, 25, 112));
g.fillOval(x1-29, y1-29, 69, 69);
// 一面の雪にやや丸い地平線
g.setColor(new Color(245, 255, 250));
g.fillOval(-600, 210, 1600, 360);
// 雪だるまの影
g.setColor(new Color(245, 245, 245));
g.fillOval(x2+37, y2+75, 100, 50);
// 雪だるま(下)
g.setColor(new Color(255, 250, 250));
g.fillOval(x2, y2, 100, 100);
// 雪だるま(上)
g.fillOval(x2+10, y2-65, 80, 80);
// "口"
g.setColor(Color.black);
g.fillRect(x2+32, y2-18, 19, 3);
// "鼻(小枝)"
g.setColor(new Color(128, 0, 0));
int[] xs0 = {x2+15, x2+15, x2+40, x2+40};
int[] ys0 = {y2-28, y2-25, y2-25, y2-31};
g.fillPolygon(xs0, ys0, 4);
// "帽子(バケツ)"
g.setColor(Color.red);
int[] xs1 = {x2+35, x2+85, x2+83, x2+53};
int[] ys1 = {y2-63, y2-45, y2-74, y2-84};
g.fillPolygon(xs1, ys1, 4);
// Randomに雪を降らせる
// (sx, sy) = ((雪のx座標)+10, (雪のy座標)+10)
// 10 ずらしているのは左端も自然に描画するため
// s_size は雪の大きさを表す
for(i = 0; i < 300; i++){
int sx = r.nextInt(420);
int sy = r.nextInt(420);
int s_size = r.nextInt(5)+3;
g.setColor(Color.white);
g.fillOval(sx-10, sy-10, s_size, s_size);
g.setColor(new Color(230, 230, 250));
g.drawOval(sx-10, sy-10, s_size, s_size);
}
// 雪だるまの"目"
g.setColor(Color.black);
g.fillOval(x2+30, y2-45, 6, 6);
g.fillOval(x2+50, y2-45, 6, 6);
// 説明
g.setFont(new Font("Serif", Font.ITALIC, 11));
g.drawString("You can move the moon or the snowman", 180, 270);
g.drawString("by dragging it.", 320, 285);
g.drawString("You can create a new star", 180, 300);
g.drawString("by dragging any other area.", 255, 315);
}
// night = false (昼)のとき(通常時)
else if(!eclipse){
// 昼の空
g.setColor(new Color(135, 206, 250));
g.fillRect(0, 0, 400, 400);
// 太陽
g.drawImage(sun, x1, y1, this);
// 昼の月
g.setColor(new Color(240, 248, 255));
g.fillOval(20, 10, 46, 46);
g.setColor(new Color(135, 206, 250));
g.fillOval(-9, -19, 69, 69);
// 一面の雪にやや丸い地平線
g.setColor(new Color(255, 250, 250));
g.fillOval(-600, 210, 1600, 360);
// 雪だるまの影
g.setColor(new Color(230, 230, 250));
g.fillOval(x2+37, y2+75, 100, 50);
// 雪だるま(下)
g.setColor(new Color(255, 250, 240));
g.fillOval(x2, y2, 100, 100);
// 雪だるま(上)
g.fillOval(x2+10, y2-65, 80, 80);
g.drawImage(sweat, x2+60, y2-40, 15, 20, this);
// "口"
g.setColor(Color.black);
g.fillRect(x2+32, y2-10, 19, 3);
// "鼻(小枝)"
g.setColor(new Color(128, 0, 0));
int[] xs0 = {x2+15, x2+15, x2+40, x2+40};
int[] ys0 = {y2-20, y2-17, y2-17, y2-23};
g.fillPolygon(xs0, ys0, 4);
// "帽子(バケツ)"
g.setColor(Color.red);
int[] xs1 = {x2+80, x2+140, x2+130, x2+90};
int[] ys1 = {y2+120, y2+120, y2+90, y2+90};
g.fillPolygon(xs1, ys1, 4);
// 雪だるまの"目"
g.setColor(Color.black);
g.fillOval(x2+30, y2-37, 6, 6);
int[] xs2 = {x2+25, x2+39, x2+37, x2+23};
int[] ys2 = {y2-40, y2-47, y2-49, y2-42};
g.fillPolygon(xs2, ys2, 4);
g.fillOval(x2+50, y2-37, 6, 6);
int[] xs3 = {x2+62, x2+48, x2+50, x2+64};
int[] ys3 = {y2-40, y2-47, y2-49, y2-42};
g.fillPolygon(xs3, ys3, 4);
// 説明
g.setFont(new Font("Serif", Font.ITALIC, 11));
g.drawString("You can move the sun by dragging it.", 220, 315);
}
// 日食
else{
// 夜の空
g.setColor(new Color(25, 25, 112));
g.fillRect(0, 0, 400, 400);
// 星
int size = starArray.size();
if(dragging) size--;
for(i = 0; i < size; i++){
Star s = (Star)starArray.elementAt(i);
g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this);
}
if(dragging){
Star s = (Star)starArray.elementAt(size);
g.drawImage(star[s.st_color], s.st_x-8, s.st_y-8, this);
}
// 月と太陽
g.setColor(new Color(255, 215, 0));
g.fillOval(x1-2, y1-2, 50, 50);
g.setColor(new Color(255, 255, 204));
g.fillOval(20, 10, 46, 46);
// 一面の雪にやや丸い地平線
g.setColor(new Color(245, 255, 250));
g.fillOval(-600, 210, 1600, 360);
// 雪だるまの影
g.setColor(new Color(245, 245, 245));
g.fillOval(x2+37, y2+75, 100, 50);
// 雪だるま(下)
g.setColor(new Color(255, 250, 250));
g.fillOval(x2, y2, 100, 100);
// 雪だるま(上)
g.fillOval(x2+10, y2-65, 80, 80);
// "口"
g.setColor(Color.black);
g.fillRect(x2+32, y2-10, 19, 3);
// "鼻(小枝)"
g.setColor(new Color(128, 0, 0));
int[] xs0 = {x2+15, x2+15, x2+40, x2+40};
int[] ys0 = {y2-20, y2-17, y2-17, y2-23};
g.fillPolygon(xs0, ys0, 4);
// "帽子(バケツ)"
g.setColor(Color.red);
int[] xs1 = {x2+35, x2+85, x2+83, x2+53};
int[] ys1 = {y2-63, y2-45, y2-74, y2-84};
g.fillPolygon(xs1, ys1, 4);
// 雪だるまの"目"
g.setColor(Color.black);
g.fillOval(x2+30, y2-37, 6, 6);
int[] xs2 = {x2+37, x2+23, x2+25, x2+39};
int[] ys2 = {y2-40, y2-47, y2-49, y2-42};
g.fillPolygon(xs2, ys2, 4);
g.fillOval(x2+50, y2-37, 6, 6);
int[] xs3 = {x2+50, x2+64, x2+62, x2+48};
int[] ys3 = {y2-40, y2-47, y2-49, y2-42};
g.fillPolygon(xs3, ys3, 4);
// 説明
g.setFont(new Font("Serif", Font.ITALIC, 40));
g.drawString("eclipse!!!", 130, 275);
g.setFont(new Font("Serif", Font.ITALIC, 11));
g.drawString("You can move the sun by dragging it.", 220, 315);
}
}
// 星を1つ消すメソッド
public void deleteStar(){
int size;
if((size = starArray.size())>0 & (night | eclipse)){
starArray.removeElementAt(size-1);
repaint();
}
}
// 星をすべて消すメソッド
public void clearStar(){
if(night | eclipse){
starArray.removeAllElements();
repaint();
}
}
}
class Kadai1202 extends Frame implements ActionListener, ItemListener{
MenuBar menuBar;
Menu fileMenu, editMenu, hoursMenu;
MyCanvas myCanvas;
Button deleteButton, clearButton, exitButton;
CheckboxGroup cbg = new CheckboxGroup();
Checkbox nightChkbox, dayChkbox;
// コンストラクタ
public Kadai1202(){
// 親クラスであるFrameクラスのコンストラクタの宣言
super("Kadai1202");
menuBar = new MenuBar();
fileMenu = new Menu("File");
fileMenu.add("Exit");
// メニューが選択された時に, Kadai1202 がイベントを受け取る
fileMenu.addActionListener(this);
// メニューバーにfileMenuを加える.
menuBar.add(fileMenu);
editMenu = new Menu("Edit");
editMenu.add("Clear");
editMenu.add("Delete");
editMenu.addSeparator();
editMenu.add(hoursMenu = new Menu("Hours"));
editMenu.addActionListener(this);
hoursMenu.add("Night");
hoursMenu.add("Day");
hoursMenu.addActionListener(this);
menuBar.add(editMenu);
// Frameにメニューバーを付け加える
setMenuBar(menuBar);
// レイアウトを GridBagLayout に設定し, Button や Checkbox を配置する
Panel panel = new Panel();
panel.setLayout(new GridBagLayout());
panel.add(deleteButton = new Button("Delete"));
deleteButton.addActionListener(this);
panel.add(clearButton = new Button("Clear"));
clearButton.addActionListener(this);
panel.add(exitButton = new Button("Exit"));
exitButton.addActionListener(this);
panel.add(nightChkbox = new Checkbox("night", cbg, true));
nightChkbox.addItemListener(this);
panel.add(dayChkbox = new Checkbox("day", cbg, false));
dayChkbox.addItemListener(this);
setLayout(new BorderLayout());
add(panel,"South");
add(myCanvas = new MyCanvas(),"North");
// Button や Checkbox が選択されているときも
// キー入力を受け付けるようにする
deleteButton.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
// "q" が押されたら終了
int key = e.getKeyChar();
if(key == 'q') System.exit(0);
}
});
clearButton.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
int key = e.getKeyChar();
if(key == 'q') System.exit(0);
}
});
nightChkbox.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
int key = e.getKeyChar();
if(key == 'q') System.exit(0);
}
});
dayChkbox.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
int key = e.getKeyChar();
if(key == 'q') System.exit(0);
}
});
// サイズを400x400に設定
setSize(400,400);
// サイズの変更を禁止する
setResizable(false);
// 表示する.
setVisible(true);
}
public void actionPerformed(ActionEvent e){
System.out.println(e);
Object source = e.getSource();
if(source.equals(deleteButton)){
myCanvas.deleteStar();
}
else if(source.equals(clearButton)){
myCanvas.clearStar();
}
else if(source.equals(exitButton)){
System.exit(0);
}
// [Edit]メニューのどれかが選択されたとき
else if(source.equals(editMenu)){
String command = e.getActionCommand();
// Delete メニューが選択されたとき
if(command.equals("Delete")){
myCanvas.deleteStar();
}
// Clear メニューが選択されたとき
else if(command.equals("Clear")){
myCanvas.clearStar();
}
}
// Hours メニューが選択されたとき
else if(source.equals(hoursMenu)){
String command = e.getActionCommand();
if(command.equals("Night")){
myCanvas.night = true;
nightChkbox.setState(true);
dayChkbox.setState(false);
myCanvas.repaint();
}
else if(command.equals("Day")){
myCanvas.night = false;
nightChkbox.setState(false);
dayChkbox.setState(true);
myCanvas.repaint();
}
}
// [File]メニューのどれかが選択されたとき
else if(source.equals(fileMenu)){
String command = e.getActionCommand();
// Exitメニューが選択されたとき
if(command.equals("Exit")){
System.exit(0);
}
}
}
public void itemStateChanged(ItemEvent e){
if(nightChkbox.getState()){
myCanvas.night = true;
}
else{
myCanvas.night = false;
}
myCanvas.repaint();
}
public static void main(String [] args){
// Kadai1202クラスのインスタンスを作成 frame に代入
Kadai1202 frame = new Kadai1202();
}
}
コメント