Swingでいろいろ作ってみます
事前学習とまとめ
repaint();
を実行することで
- paint()を再度呼び出し
を実行します。
背景色のぬりつぶしをなくすにはupdate()をオーバーライドして
public void update(Graphics g) {
paint(g);
}
に変更するらしい。
マウスイベントは抽象クラスMouseListenerに対し処理内容を記述すればよい。ただし、抽象クラスのためすべて定義が必要。
public void mousePressed(MouseEvent me) {}
public void mouseClicked(MouseEvent me) {}
public void mouseEntered(MouseEvent me) {}
public void mouseExited(MouseEvent me) {}
public void mouseReleased(MouseEvent me) {}
Timerオブジェクト
よくわかりませんが、mainの処理は止まるのでしょうか?
ー>止まりません
main内でscheduleで設定後、次の文に移動します。Timerタスクは別で割り込み処理のように実行されます。
初期設定
Timer time = new Timer();
time.scheduleAtFixedRate(new SampleTask(), delay, period);
実行内容
public class SampleTask extends TimerTask {
public void run() {
}
}
repaint()を頻繁に呼び出せば動的な画面が作れます。
cancel()でタイマーを終了することができる
アニメーション:徐々に大きくなる正方形
Timerオブジェクト:repaintを起動
Flameオブジェクト:フレームを作る
<-このクラス内でmainを記述
<-paint();を書く
Timerオブジェクト:repaintを起動
をするには、Timerオブジェクトにフレームのインスタンスを渡す必要があります。
TimerクラスとTimerTaskクラス
の二つがある
- Timerクラスはスケジュールを設定するのみ
- TimerTaskクラスは実行内容を定義する
TimerTaskはcancel()で停止
Timerはdispose()で終了ー>これを止めないとプログラムが終わらない
経過時間を取得
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime; //msで経過時間を取得
ダブルバッファ
アニメーション表示をさせると、画面のちらつきが問題になります。これは描画する要素が増えると全要素の描画が終わる前に一度表示され、描画が追加され表示が完了という流れが起きることに起因します。
対策としてはダブルバッファを入れることで全描画が完了してから表示させるという方法を取ります。
Image imgBuf = createImage(width,hight);
Graphics gBuf = imgBuf.getGraphics(); gBuf.fillRect(0,0,width,hight);
/*
描画処理
*/
Graphics graphics = getContentPane().getGraphics();
graphics.drawImage(imgBuf,0,0,this);
これでダブルバッファできます。
サンプル1:波紋生成
ランダムで円を描画し、リアルタイムでサイズを大きくしていきます。
まだまだオブジェクト指向がよくわかっていません。
動作の流れは
- フレームを作成
- タイマーを仕掛ける
- タイマーの呼び出しで描画(+波紋のインスタンス内のdrawメソッド呼び出し)
- 各画面作成時、特定の確率で波紋のインスタンスを生成
import javax.swing.*;
import java.awt.*;
import java.util.Random;
import java.util.Timer;
public class Flame extends JFrame {
long startTime;
int hight = 500;
int width = 500;
WaterRipple[] ripples = new WaterRipple[100];
int ripples_num = 0;
public static void main(String[] args) {
System.out.println("Start");
Flame frame = new Flame();
java.util.Timer timer = new Timer();
Timer_task timer_task = new Timer_task();
timer_task.setFlame(frame);
timer_task.setTimer(timer);
timer.scheduleAtFixedRate(timer_task, 0,30);
}
public Flame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(width, hight);
setVisible(true);
startTime = System.currentTimeMillis();
}
public void paint(Graphics g){
Image imgBuf = createImage(width,hight);
Graphics gBuf = imgBuf.getGraphics();
gBuf.setColor(Color.white);
gBuf.fillRect(0,0,width,hight);
long now_time = System.currentTimeMillis();
//10%の確率で波紋を生成
Random rand = new Random();
int probability = rand.nextInt(99);
if(probability<10){
ripples[ripples_num] = new WaterRipple(width,hight,now_time);
ripples_num++;
}
//波紋を描画
for(int i = 0;i<ripples_num;i++ ){
if(ripples[i].drawable == true) {
ripples[i].calculate_radius(now_time);
ripples[i].draw(gBuf);
}
}
Graphics graphics = getContentPane().getGraphics();
graphics.drawImage(imgBuf,0,0,this);
System.out.println(ripples_num);
}
}
import java.util.Timer;
import java.util.TimerTask;
public class Timer_task extends TimerTask {
Flame frame_timer;
int num = 0;
Timer time2;
public void run() {
frame_timer.repaint();
num++;
if(num>1000){
System.out.println("End");
cancel();
frame_timer.dispose();
time2.cancel();
}
}
public void setFlame(Flame frame){
frame_timer = frame;
}
public void setTimer(Timer time3){
this.time2 = time3;
}
}
import java.awt.*;
import java.util.Random;
public class WaterRipple {
int x;
int y;
int radius = 0;
long start_time;
Color color;
boolean drawable = true;
int height;
int width;
public WaterRipple(int width,int height,long start_time){
Random rand = new Random();
this.x = rand.nextInt(width);
this.y = rand.nextInt(height);
this.height = height;
this.width = width;
this.start_time = start_time;
color = new Color(rand.nextInt(250),rand.nextInt(250),rand.nextInt(250));
}
public void calculate_radius(long now_time){
radius = (int) ((now_time-start_time)*0.05);
if(radius>width || radius> height){
this.drawable = false;
}
}
public void draw(Graphics g){
g.setColor(color);
g.fillOval(x-radius,y-radius,radius*2,radius*2);
}
}
初めてにしては割と頑張ったと思います。