/* * @(#)GridViewer.java * * Copyright (c) 1997 NAKAGAWA Masami * * Permission to use, copy, modify, and distribute this software * for NON-COMMERCIAL purpose and without fee is hereby granted. */ import java.applet.*; import java.awt.*; import java.util.*; import java.awt.image.*; /** A class of GridViewer * @author NAKAGAWA Masami * @version 1.1, 1 Nov 1997 */ public class GridViewer extends Applet implements Runnable { static final int HORIZONTAL = 0; static final int VERTICAL = 1; static final int RANDOM = 2; static final int PLAIN = 0; static final int RAISED = 1; static final int SUNKEN = 2; int column; int row; int gridX; int gridY; int gridWidth; int gridHeight; Image offImage; Image gridImage; Graphics offScreen; Graphics onScreen; Graphics gridScreen; boolean raised = true; boolean fillStart = true; Thread thread; int mode; int count; int countY; Dimension size; Dimension grid; int gap = 1; Color gridColor = Color.black; Color rectColor = Color.darkGray; Color bgColor = Color.black; MediaTracker mt; Rectangle[][] area; Rectangle toUpArea; Rectangle toDownArea; Rectangle toRightArea; Rectangle toLeftArea; Rectangle gridArea; Dimension unit; Vector ivec = new Vector(); Image bgImage; Vector pvec = new Vector(); Color[] pcol; int[] pix; int nextX; int nextY; int crntX; int crntY; int interval = 20; Dimension imgSize; int relief; public void init() { Image image; size = size(); mt = new MediaTracker(this); String s = getParameter("column"); if (s != null) column = Integer.parseInt(s); s = getParameter("row"); if (s != null) row = Integer.parseInt(s); s = getParameter("gridX"); if (s != null) gridX = Integer.parseInt(s); s = getParameter("gridY"); if (s != null) gridY = Integer.parseInt(s); s = getParameter("gridWidth"); gridWidth = (s != null)?Integer.parseInt(s):size.width; s = getParameter("gridHeight"); gridHeight = (s != null)?Integer.parseInt(s):size.height; s = getParameter("gridColor"); if (s != null) gridColor = new Color(Integer.parseInt(s, 16)); s = getParameter("rectColor"); if (s != null) rectColor = new Color(Integer.parseInt(s, 16)); s = getParameter("bgColor"); if (s != null) bgColor = new Color(Integer.parseInt(s, 16)); s = getParameter("image"); if (s != null) { StringTokenizer st = new StringTokenizer(s, "|"); while (st.hasMoreTokens()) { ivec.addElement(image = getImage(getDocumentBase(), st.nextToken().trim())); mt.addImage(image, 0); } } s = getParameter("bgImage"); if (s != null) { bgImage = getImage(getDocumentBase(), s); mt.addImage(bgImage, 0); } s = getParameter("gap"); if (s != null) gap = Integer.parseInt(s); s = getParameter("raised"); if (s != null) raised = Boolean.valueOf(s).booleanValue(); s = getParameter("fillStart"); if (s != null) fillStart = Boolean.valueOf(s).booleanValue(); s = getParameter("mode"); if (s != null) { if (s.equals("random")) { mode = RANDOM; } else if (s.equals("vertical")) { mode = VERTICAL; } else { mode = HORIZONTAL; } } s = getParameter("relief"); if (s != null) { s = s.trim().toLowerCase(); if (s.equals("raised")) relief = RAISED; else if (s.equals("sunken")) relief = SUNKEN; else relief = PLAIN; } s = getParameter("interval"); if (s != null) { interval = Integer.parseInt(s); if (interval < 10) interval = 10; } offImage = createImage(size.width, size.height); offScreen = offImage.getGraphics(); onScreen = getGraphics(); } public void start() { repaint(); if (thread == null) { thread = new Thread(this); thread.start(); } } public void stop() { if (thread != null) { thread.stop(); } thread = null; } public void paint(Graphics g) { if (offImage != null) { g.drawImage(offImage, 0, 0, null); } } public void update(Graphics g) { paint(g); } private void drawBox(Graphics g, Rectangle r, Color color) { g.setColor(color); g.fillRect(r.x, r.y, r.width, r.height); if (relief != PLAIN) { g.draw3DRect(r.x, r.y, r.width - 1, r.height - 1, (relief == RAISED)); } } private void drawHorizontal(Graphics g) { g.copyArea(toLeftArea.x, toLeftArea.y, toLeftArea.width, toLeftArea.height, -unit.width, 0); int x = column - 1; if (++crntX + x >= imgSize.width) crntX = -x; for (int y = 0; y < row; y++) { int idx = (crntY + y) * imgSize.width + crntX + x; drawBox(g, area[x][y], pcol[idx]); } } private void drawVertical(Graphics g) { g.copyArea(toUpArea.x, toUpArea.y, toUpArea.width, toUpArea.height, 0, -unit.height); int y = row - 1; if (++crntY + y >= imgSize.height) crntY = -y; for (int x = 0; x < column; x++) { int idx = (crntY + y) * imgSize.width + crntX + x; drawBox(g, area[x][y], pcol[idx]); } } private void drawRandom(Graphics g) { if (crntX < nextX) { g.copyArea(toLeftArea.x, toLeftArea.y, toLeftArea.width, toLeftArea.height, -unit.width, 0); if (++crntX == nextX) { do { nextY = (int)((imgSize.height - row) * Math.random()); } while (nextY == crntY); } int x = column - 1; for (int y = 0; y < row; y++) { int idx = (crntY + y) * imgSize.width + crntX + x; drawBox(g, area[x][y], pcol[idx]); } } else if (crntX > nextX) { g.copyArea(toRightArea.x, toRightArea.y, toRightArea.width, toRightArea.height, unit.width, 0); if (--crntX == nextX) { do { nextY = (int)((imgSize.height - row) * Math.random()); } while (nextY == crntY); } for (int y = 0; y < row; y++) { int idx = (crntY + y) * imgSize.width + crntX; drawBox(g, area[0][y], pcol[idx]); } } else if (crntY < nextY) { g.copyArea(toUpArea.x, toUpArea.y, toUpArea.width, toUpArea.height, 0, -unit.height); if (++crntY == nextY) { do { nextX = (int)((imgSize.width - column) * Math.random()); } while (nextX == crntX); } int y = row - 1; for (int x = 0; x < column; x++) { int idx = (crntY + y) * imgSize.width + crntX + x; drawBox(g, area[x][y], pcol[idx]); } } else if (crntY > nextY) { g.copyArea(toDownArea.x, toDownArea.y, toDownArea.width, toDownArea.height, 0, unit.height); if (--crntY == nextY) { do { nextX = (int)((imgSize.width - column) * Math.random()); } while (nextX == crntX); } for (int x = 0; x < column; x++) { int idx = crntY * imgSize.width + crntX + x; drawBox(g, area[x][0], pcol[idx]); } } } private void initGridArea() { if (fillStart) { if (mode == VERTICAL) { for (int y = 0; y < row; y++) { drawVertical(gridScreen); } } else { for (int x = 0; x < column; x++) { drawHorizontal(gridScreen); } } } else { gridScreen.setColor(rectColor); for (int l = 0; l < row; l++) { for (int c = 0; c < column; c++) { gridScreen.fill3DRect(area[c][l].x, area[c][l].y, area[c][l].width, area[c][l].height, raised); } } } } private void calcGridArea() { area = new Rectangle[column][row]; int uw = (gridWidth - gap) / column; int uh = (gridHeight - gap) / row; if (uw <= 0) uw = 1; if (uh <= 0) uh = 1; if (uw <= gap || uh <= gap) { gap = Math.min(uw, uh) - 1; } int w = (gridWidth - gap) / column * column + gap; int h = (gridHeight - gap) / row * row + gap; uw = (w - gap) / column; uh = (h - gap) / row; int x0 = (gridX > 0)?gridX:(size.width - w) / 2; int y0 = (gridY > 0)?gridY:(size.height - h) / 2; for (int l = 0; l < row; l++) { for (int c = 0; c < column; c++) { area[c][l] = new Rectangle(c * uw + gap, l * uh + gap, uw - gap, uh - gap); } } gridArea = new Rectangle(x0, y0, w, h); toDownArea = new Rectangle(0, 0, w, h - uh); toUpArea = new Rectangle(0, uh, w, h - uh); toLeftArea = new Rectangle(uw, 0, w - uw, h); toRightArea = new Rectangle(0, 0, w - uw, h); unit = new Dimension(uw, uh); gridImage = createImage(gridArea.width, gridArea.height); gridScreen = gridImage.getGraphics(); gridScreen.setColor(gridColor); gridScreen.fillRect(0, 0, w, h); gridScreen.setColor(rectColor); } private void fillImage(Graphics g, Image image, Color color) { g.setColor(color); g.fillRect(0, 0, size.width, size.height); if (image != null) { int w = image.getWidth(null); int h = image.getHeight(null); for (int x = 0; x < size.width; x += w) { for (int y = 0; y < size.height; y += h) { g.drawImage(image, x, y, null); } } } } private void drawMessage(String s) { offScreen.setColor(Color.black); offScreen.fillRect(0, 0, size.width, size.height); offScreen.setColor(Color.cyan); offScreen.drawString(s, 10, 20); onScreen.drawImage(offImage, 0, 0, null); } private void checkRowColumn() { int c = Math.min(imgSize.width, gridWidth); int r = Math.min(imgSize.height, gridHeight); if (mode == VERTICAL) { if (column <= 0 || column > c) { column = c; } if (row <= 0) { int gwid = (gridWidth - gap) / column; if (gwid <= 0) gwid = 1; row = (gridHeight - gap) / gwid; } if (row > r) { row = r; } } else if (mode == HORIZONTAL) { if (row <= 0 || row > r) { row = r; } if (column <= 0) { int gwid = (gridHeight - gap) / row; if (gwid <= 0) gwid = 1; column = (gridWidth - gap) / gwid; } if (column > c) { column = c; } } else if (mode == RANDOM) { if (row <= 0) { row = (gridHeight - gap) / (8 + gap); } if (row >= r - 2) { row = r - 2; } if (column <= 0) { column = (gridWidth - gap) / (8 + gap); } if (column >= c - 2) { column = c - 2; } } } public void run() { Image image; int width = 0; int height = 0; Thread.currentThread().setPriority(Thread.NORM_PRIORITY - 1); if (pcol == null) { drawMessage("Loading images..."); try { mt.waitForID(0); } catch (InterruptedException e) { e.printStackTrace(); } if (mt.isErrorAny()) { drawMessage("Error: loading images"); return; } drawMessage("Processing images..."); image = (Image)ivec.firstElement(); for (Enumeration e = ivec.elements(); e.hasMoreElements(); ) { image = (Image)e.nextElement(); int w = image.getWidth(null); int h = image.getHeight(null); if (width <= 0 || mode == HORIZONTAL) width += w; if (height <= 0 || mode == VERTICAL) height += h; } imgSize = new Dimension(width, height); fillImage(offScreen, bgImage, bgColor); checkRowColumn(); if (mode == VERTICAL) { crntX = 0; crntY = -row; } else { crntX = -column; crntY = 0; } if (mode == RANDOM) { nextX = (int)((width - column - 1) * Math.random() + 1); nextY = 0; } pix = new int[width * height]; pcol = new Color[width * height]; int offset = 0; for (Enumeration e = ivec.elements(); e.hasMoreElements(); ) { image = (Image)e.nextElement(); int w = image.getWidth(null); int h = image.getHeight(null); PixelGrabber pg = null; if (mode == HORIZONTAL) { pg = new PixelGrabber(image, 0, 0, w, height, pix, offset, width); offset += w; } else if (mode == VERTICAL) { pg = new PixelGrabber(image, 0, 0, width, h, pix, offset, width); offset += width * h; } else { pg = new PixelGrabber(image, 0, 0, width, height, pix, offset, w); } try { pg.grabPixels(); } catch (InterruptedException ie) { ie.printStackTrace(); } if (mode == RANDOM) break; } for (int i = 0; i < width * height; i++) { Color col = ((pix[i] & 0xFF000000) == 0)?rectColor:new Color(pix[i]); int idx = pvec.indexOf(col); if (idx >= 0) { pcol[i] = (Color)pvec.elementAt(idx); } else { pcol[i] = col; pvec.addElement(col); } } calcGridArea(); offScreen.clipRect(gridArea.x, gridArea.y, gridArea.width, gridArea.height); offScreen.setColor(gridColor); offScreen.fillRect(gridArea.x, gridArea.y, gridArea.width, gridArea.height); initGridArea(); onScreen.drawImage(offImage, 0, 0, null); onScreen.clipRect(gridArea.x, gridArea.y, gridArea.width, gridArea.height); } while (true) { switch (mode) { case HORIZONTAL: drawHorizontal(gridScreen); break; case VERTICAL: drawVertical(gridScreen); break; case RANDOM: drawRandom(gridScreen); break; } offScreen.drawImage(gridImage, gridArea.x, gridArea.y, null); onScreen.drawImage(offImage, 0, 0, null); try { thread.sleep(interval); } catch (InterruptedException e) { e.printStackTrace(); } } } }