[an error occurred while processing this directive]
[an error occurred while processing this directive]class Env { public static int W, H; public static double WH_RATIO; public static String URL; /** 各種パラメータのデフォルト値を設定 */ static { W = 800; H = 600; WH_RATIO = 1.333333; URL = "http://funini.com/kei/ivy/narita/"; } }
public class Ivylet extends JApplet { public void init() { String[] imgPaths = extractPaths(Env.URL); IvyPanel tp = new IvyPanel(imgPaths); setContentPane(tp); } /** 指定されたパスから、画像の 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 MouseListener { IconList iconList; // 各画像の重ね順です。 public IvyPanel(String[] urls) { /** コンストラクタ 引数は画像が入っているパス */ setBackground(new Color(0x33, 0x33, 0x33)); // 背景色設定 setPreferredSize(new Dimension(Env.W, Env.H)); // サイズ設定 iconList = new IconList(urls); addMouseListener(this); // マウスのイベントを扱えるようにする } public synchronized void mousePressed(MouseEvent e) { /** マウスがクリックされたときのイベント */ Point p = e.getPoint(); // ボタン以外がクリックされた時 for(int i = iconList.size() - 1; i >= 0; i--) { // クリックは表示と逆順で調べる Icon icon = iconList.get(i); // i 番目のアイコンについて if(icon.hit(p)){ // クリックされている場合 iconList.piledTop(icon); // icon をトップに表示 (重ね表示) repaint(); return; } } // ボタンもアイコンもクリックされていない場合、初期表示に戻る initView(); repaint(); } void initView() { /** 初期表示を行う */ iconList.pile(); // 重ね表示 } /** 描画を行う */ public void paintComponent(Graphics g) { super.paintComponent(g); // ウィンドウを表示 Graphics2D g2 = (Graphics2D) g; // アンチエイリアスの設定など g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); for(int i = 0; i < iconList.size(); i++) iconList.get(i).draw(g2); // 各アイコンを表示 } /** MouseListener を実装するために必要なメソッド群 */ public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} }
class IconList {
int nIcons; // アイコンの数
Icon[] icons; // アイコン (画像1枚につき、一つのアイコンです)
int[] orders;
PiledPosition piledPos; // 重ねた表示の時の各画像の位置
public IconList(String[] imgPaths) {
/** 引数: ロードされた画像リスト */
nIcons = imgPaths.length;
icons = new Icon[nIcons];
for(int i = 0; i < nIcons; i++)
icons[i] = new Icon(imgPaths[i]);
orders = new int[nIcons];
piledPos = new PiledPosition(nIcons);// 一覧表示での位置を計算
pile(); // 初期表示(重ね表示)に移行
}
/** 重ね表示にアイコンを移動 */
public void pile() {
for(int i = 0; i < nIcons; i++) {
// 重ね順を設定。orders は描画順なので、一番新しい画像を最後にする
orders[i] = nIcons - i - 1;
icons[i].setPosition(piledPos.getPos(i));
}
}
/** アイコンのインデックス(何番目のアイコンか)を返す */
int searchIcon(Icon ic) {
for(int i = 0; i < nIcons; i++)
if(icons[i] == ic) return i;
return -1; // 見つからなかった場合
}
/** 指定されたインデックスが何番目に重なっているかを返す */
int searchOrder(int index) {
for(int i = 0; i < nIcons; i++)
if(orders[i] == index) return i;
return -1; // 見つからなかった場合
}
/** 重ね表示において、指定されたアイコンをトップに移動 */
public void piledTop(Icon ic) {
int index = searchIcon(ic);
// 指定されたアイコンより手前のものは、画面外に移動
for(int i = 0; i < index; i++)
icons[i].setPosition(piledPos.getOuterPos());
// 指定されたアイコン以後のものを手前から順番に並べる
for(int i = index; i < nIcons; i++)
icons[i].setPosition(piledPos.getPos(i - index));
}
/** アイコンの数を返すメソッド */
public int size() { return nIcons; }
/** 重ね順が(下から) i 番目のアイコンを返すメソッド */
public Icon get(int i){ return icons[orders[i]]; }
}
abstract class IconPosition { /** 各アイコンの配置を示すクラス */ int[] X, Y; // アイコンの X, Y, W, H int w, h; public IconPosition(int n) { /** 各アイコンの座標、大きさ */ X = new int[n]; Y = new int[n]; } /** 指定されたインデックスのアイコン位置を返す */ public int[] getPos(int i) { return new int[] { X[i], Y[i], w, h }; } /** 指定された幅/高さ 最大値を超えないように、幅・高さを設定する */ public void setWH(int wMax, int hMax) { w = wMax; // アイコンの(最大)幅 h = (int) ((double) w / Env.WH_RATIO); // アイコンの(最大)高さ if(h > hMax) { // 幅を基準にしたら、高さがhMaxをはみ出てしまった場合 h = hMax; w = (int) (h * Env.WH_RATIO); } } }
class PiledPosition extends IconPosition { /** 重ね表示 の時の位置情報を持つクラス */ int zw, zh; int outerX, outerY; /** コンストラクタ (引数: 画像の数) */ public PiledPosition(int n) { super(n); setWH(Env.W / 2, Env.H / 2); X[0] = Env.W / 2 - Env.W / 10; // 一番手前のアイコンのX座標 Y[0] = Env.H / 2 - Env.H / 10; // 一番手前のアイコンのY座標 for(int i = 1; i < n; i++) { X[i] = X[i - 1] - (int) ((10 - i) * (10 - i) * 0.9); Y[i] = Y[i - 1] - (int) ((10 - i) * (10 - i) * 0.4 + 20); } outerX = Env.W; outerY = Env.H; } /** フォーカスアウトして、画面からはみ出た位置を返す */ public int[] getOuterPos() { return new int[] { outerX, outerY, w, h }; } }
abstract class Rect {
int[] P; // X,Y座標, 幅、高さ
Image img;
int imgW, imgH; // 画像の幅、高さ
Color col;
public Rect(int x, int y, int w, int h) {
P = new int[] { x, y, w, h };
}
/** 指定された座標 p が、この長方形の内部かどうかを返す */
public boolean hit(Point p) {
return (P[0] <= p.x && p.x <= P[0] + P[2]
&& P[1] <= p.y && p.y <= P[1] + P[3]);
}
/** 画像をロード。path がhttp:// で始まる場合、HTTPで取得する */
public void loadImage(String path){
img = ImageLoader.load(path);
imgW = img.getWidth(null);
imgH = img.getHeight(null);
}
public void setPosition(int[] P){
for(int i = 0; i < 4; i++)
this.P[i] = P[i];
}
}
class Icon extends Rect {
public Icon(String imgPath) {
super(0, 0, 0, 0);
loadImage(imgPath);
col = new Color(0.85f, 0.85f, 0.75f, 0.3f);
}
/** アイコンを描画する */
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 ImageLoader { /** 画像をロード。path がhttp:// で始まる場合、HTTPで取得する */ public static Image load(String path) { try { if(path.startsWith("http://")){ URLConnection urlc = new URL(path).openConnection(); return ImageIO.read(urlc.getInputStream()); } return ImageIO.read(new File(path)); } catch (IOException ie) { ie.printStackTrace();} return null; } }