[an error occurred while processing this directive]
[an error occurred while processing this directive]
class Env {
public static int W, H, BTN_W;
public static int T_MAX;
public static int REFRESH;
public static double WH_RATIO;
public static String URL, BACKGROUND_URL;
}
public class Ivylet extends JApplet { public void init() { loadParameter(); String[] imgPaths = extractPaths(Env.URL); IvyPanel tp = new IvyPanel(imgPaths); setContentPane(tp); new Timer(Env.REFRESH, tp).start(); } /** 各種パラメータのデフォルト値を設定 */ void loadParameter() { Env.W = getIntParameter("width", 800); Env.H = getIntParameter("height", 600); Env.BTN_W = getIntParameter("button_width", 30); Env.T_MAX = getIntParameter("t_max", 20); Env.WH_RATIO = getDoubleParameter("wh_ratio", 1.333333); Env.REFRESH = getIntParameter("refresh", 15); Env.URL = getParameter("url", "http://funini.com/kei/ivy/narita/"); Env.BACKGROUND_URL = getParameter("background_url", "http://funini.com/kei/ivy/imgs/back.jpg"); } /** param タグから String のパラメータを取得。失敗時はデフォルト値を返す */ String getParameter(String key, String defval) { String s = getParameter(key); return (s == null) ? defval : s; } /** param タグから int のパラメータを取得。失敗時はデフォルト値を返す */ int getIntParameter(String key, int defval) { try { String s = getParameter(key); return (s == null) ? defval : Integer.parseInt(s); } catch (Exception e){ return defval; } } /** param タグから、double のパラメータを取得。失敗時はデフォルト値を返す */ double getDoubleParameter(String key, double defval) { try { String s = getParameter(key); return (s == null) ? defval : Double.parseDouble(s); } catch (Exception e) { return defval; } } /** 指定されたパスから、画像の URL 一覧を取得 */ public String[] extractPaths(String urlStr) { // urlBase には、URLの / 以前の部分が入る ( http://funini.com/kei/ など) String urlBase = urlStr.substring(0, urlStr.lastIndexOf("/") + 1); ArrayList files = new ArrayList(); try { BufferedReader br = new BufferedReader(new InputStreamReader( new URL(urlStr).openConnection().getInputStream())); extractFiles(files, urlBase, br); } catch (IOException ie) { ie.printStackTrace(); } return (String[]) files.toArray(new String[0]); } /** br から全体を読み込み、画像の URL 一覧を取得 */ void extractFiles(ArrayList files, String urlBase, BufferedReader br) throws IOException{ Pattern pattern = Pattern.compile("^(.+\\.(jpg|JPG))<.*"); for(;;) { String line = br.readLine(); if(line == null) break; String[] targets = line.split(">"); for(int i = 0; i < targets.length; i++) { Matcher m = pattern.matcher(targets[i]); if(m.matches()) files.add(urlBase + m.group(1)); } } } }
class IvyPanel extends JPanel implements ActionListener, MouseListener { Button button; // ボタンです。クリックすると表示モードが変わります Shadow shadow; // 全体に被せる影です。モードが変わるときに描画されます。 Background back; // 背景です。 IconList iconList; // 各画像の重ね順です。 boolean listmode; // 表示モードです。「一覧表示(true)」と「重ね表示(false)」があります public IvyPanel(String[] urls) { /** コンストラクタ 引数は画像が入っているパス */ setBackground(new Color(0x33, 0x33, 0x33)); // 背景色設定 setPreferredSize(new Dimension(Env.W, Env.H)); // サイズ設定 button = new Button(0, Env.H - Env.BTN_W, 210, Env.BTN_W); // ボタンを配置 shadow = new Shadow(Env.W, Env.H); // 影作成 back = new Background(Env.BACKGROUND_URL, Env.W, Env.H); iconList = new IconList(urls); listmode = false; addMouseListener(this); // マウスのイベントを扱えるようにする } public synchronized void mousePressed(MouseEvent e) { /** マウスがクリックされたときのイベント */ Point p = e.getPoint(); if(button.hit(p)) { // ボタンがクリックされた場合 listmode = !listmode; // 一覧表示 と 重ね表示を切り替え initView(); // 初期表示 return; } // ボタン以外がクリックされた時 for(int i = iconList.size() - 1; i >= 0; i--) { // クリックは表示と逆順で調べる Icon icon = iconList.get(i); // i 番目のアイコンについて if(icon.hit(p)){ // クリックされている場合 if(listmode) iconList.listTop(icon); // icon をトップに表示 (一覧表示) else iconList.piledTop(icon); // icon をトップに表示 (重ね表示) return; } } // ボタンもアイコンもクリックされていない場合、初期表示に戻る initView(); } void initView() { /** 初期表示を行う */ if(listmode) iconList.list(); // 一覧表示 else iconList.pile(); // 重ね表示 shadow.animationStart(); // 影を表示 } /** タイマイベントが発生したら、時間を進める */ public void actionPerformed(ActionEvent ae) { addTime(); } /** 時間を進める (何度も呼ばれると困るから、synchronized にしました) */ synchronized void addTime() { for(int i = 0; i < iconList.size(); i++) // 全てのアイコンについて iconList.get(i).addTime(); // 時間を進める shadow.addTime(); // 影も時間を進める repaint(); // 再描画 } /** 描画を行う */ public void paintComponent(Graphics g) { super.paintComponent(g); // ウィンドウを表示 Graphics2D g2 = (Graphics2D) g; // アンチエイリアスの設定など g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); back.draw(g2); // 背景を表示 button.draw(g2); // ボタンを表示 for(int i = 0; i < iconList.size(); i++) iconList.get(i).draw(g2); // 各アイコンを表示 shadow.draw(g2); // 影を表示 } /** MouseListener を実装するために必要なメソッド群 */ public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} }
class Icon extends Rect { int[] dest, orig; // 移動先と移動元のx, y, w, hを持つ配列 public Icon(String imgPath) { super(0, 0, 0, 0); loadImage(imgPath); col = new Color(0.85f, 0.85f, 0.75f, 0.3f); dest = new int[] { 0, 0, 0, 0 }; orig = new int[] { 0, 0, 0, 0 }; } /** アニメーションの目的地を設定 */ public void setDestination(int[] A) { for(int i = 0; i < 4; i++) { orig[i] = P[i]; dest[i] = A[i]; } animationStart(); // 時間変数 t,state を初期化 } /** 時間を進め、state に応じて、このオブジェクトを移動させる。 * 移動元は orig, 移動先は dest。*/ public void addTime() { super.addTime(); for(int i = 0; i < 4; i++) P[i] = (int) (orig[i] * (1 - state) + dest[i] * state); } /** アイコンを描画する */ void draw(Graphics2D g) { // まずは、画像が半分以上画面外にはみ出ている場合は描画しない if(P[0] + P[2] / 2 < 0 || P[1] + P[3] / 2 < 0 || Env.W <= P[0] || Env.H <= P[1]) return; g.setColor(col); // アイコンの周りの、少し透明な枠を描画する g.fillRect(P[0], P[1], P[2], P[3]); // 少し余白をあけて、アイコンを描画する int marginX = P[2] / 30; int marginY = P[3] / 30; g.drawImage(img, P[0] + marginX, P[1] + marginY, P[0] + P[2] - marginX, P[1] + P[3] - marginY, 0, 0, imgW, imgH, null); } }
class Shadow extends Rect {
public Shadow(int w, int h) { super(0, 0, w, h); }
public void draw(Graphics2D g) {
/** 影を全体に描画する */
if(t == Env.T_MAX) return; // 影が終了していれば return
// 透明度を計算する
float alpha = (float)(0.5 - 2 * Math.pow(state - 0.5, 2));
g.setColor(new Color(0.6f, 0.4f, 0.2f, alpha));
// 全体を塗りつぶす
g.fillRect(0, 0, Env.W, Env.H);
}
}
class Background extends Rect {
/** コンストラクタ。引数: 画像のURL(またはパス)、幅、高さ*/
public Background(String url, int w, int h) {
super(0, 0, w, h);
loadImage(url);
}
/** img にロードされた画像を、指定された幅・高さを満たすよう敷き詰める */
public void draw(Graphics2D g) {
int n = (int) Math.ceil((double) P[2] / imgW);
int m = (int) Math.ceil((double) P[3] / imgH);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
g.drawImage(img, i * imgW, j * imgH, null);
}
}