001:// パネルの端で跳ね返るボール
002:import java.awt.*;
003:import java.awt.event.*;
004:import javax.swing.*;
005:import java.util.*;
006:
007:class Ball {
008: public int x, y; // ボールの位置
009: public int d; // ボールの直径
010: int dx, dy; // ボールの移動速度
011: public Color c; // ボールの色
012:
013: Ball(int xx, int yy, int dd, int dxx, int dyy, Color cc) { // Ball の生成
014: x = xx; // x座標
015: y = yy; // y座標
016: d = dd; // ボールの直径
017: dx = dxx; // x方向への移動ドット数
018: dy = dyy; // y方向への移動ドット数
019: c = cc; // ボールの色
020: }
021:
022: void move(int w1, int w2, int h1, int h2){ // Ball の移動
023: if(dy>0 && y+d > h2) dy = -dy; // 下側の縁に接触、上向きに方向転換
024: if(dy<0 && y < h1) dy = -dy; // 上側の縁に接触、下向きに方向転換
025: y += dy; // 上下方向の移動
026: if(dx>0 && x+d > w2) dx = -dx; // 右側の縁に接触、左向きに方向転換
027: if(dx<0 && x < w1) dx = -dx; // 左側の縁に接触、右向きに方向転換
028: x += dx; // 左右方向の移動
029: }
030: } // class Ball
031:
032:class BallPanel extends JPanel implements Runnable { // BallPanel クラス
033: final int psize=300; // パネルの大きさ
034: final int bwid = 5; // パネルの縁の厚さ
035: final Color[] cs = { Color.red, Color.orange, Color.yellow, Color.green,
036: Color.lightGray,
037: Color.cyan, Color.blue, Color.magenta, Color.pink,
038: Color.gray };
039: Thread th; // スレッド
040: int w, h; // パネルの幅と高さ
041: int num; // ボールの個数
042: Ball[] b = new Ball[40]; // ボール
043: Random ran; // 乱数の初期値
044:
045: BallPanel(int i){ // BallPanel の生成
046: if(i>40) num = 40;
047: else num = i; // ボールの個数
048: setBackground(Color.white); // パネルの背景色
049: setForeground(Color.red); // 描画色
050: setBorder(BorderFactory.createLineBorder(Color.lightGray, bwid));
051: setMinimumSize(new Dimension(psize, psize)); // パネルの最小サイズ
052: setPreferredSize(new Dimension(psize, psize)); // パネルの希望サイズ
053: w=psize; // パネルの幅
054: h=psize; // パネルの高さ
055:
056: ran = new Random();
057: for(int j=0; j<num; j++) { // Ball の生成
058: b[j] = new Ball(w/2, h/2, 25-4*(j % 5), myRandom(), myRandom(), cs[j % cs.length]);
059: }
060: } // constructor BallPanel
061:
062: public void paintComponent(Graphics g){ //
063: super.paintComponent(g); // JPanel の描画
064: for(int i=0; i<num; i++) { // すべてのボールについて
065: b[i].move(bwid, w-bwid, bwid, h-bwid); // Ball の移動
066: g.setColor(b[i].c); // Ball の色を設定
067: g.fillOval(b[i].x, b[i].y, b[i].d, b[i].d); // ボールの描画
068: }
069: } // method paintComponent
070:
071: public void run(){ // スレッドの実行
072: while(true){ // 永久ループ
073: try{
074: Thread.sleep(25); // 表示間隔
075: }catch(InterruptedException e){}
076: repaint(); // 描画
077: }
078: } // method run
079:
080: int myRandom(){ // 5〜-2, 2〜5 の乱数
081: int n = ran.nextInt()%6;
082: while(n>=-1 && n<=1) {
083: n = ran.nextInt()%6;
084: }
085: return n;
086: } // method myRandom
087:
088: public static void main(String args[]){
089: int num;
090: if(args.length < 1) num = 10; // デフォルトのボール個数10
091: else num = Integer.parseInt(args[0]); // ボールの個数
092: JFrame f = new JFrame("Ball Sample"); // ウィンドウの生成
093: f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // クローズ時の処理の指定
094:
095: BallPanel example = new BallPanel(num); // 描画領域パネル
096: f.getContentPane().add(example, BorderLayout.CENTER); // パネルをウィンドウに張付け
097: f.pack(); // ウィンドウの大きさの調整
098: f.setVisible(true); // ウィンドウの表示
099: Thread th = new Thread(example); // 描画表示パネルの表示スレッド
100: th.start(); // 描画開始
101: } // method main
102:} // class BallPanel