import java.awt.*; import java.awt.image.*; /*********************************************************************** * * A station clock applet, drawn with anti-aliased graphics. * This applet uses the AntiAliasingFilter class to draw a clock. * *

* Home page: www.source-code.biz
* Copyright 1997-2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.
* License: This is "Open Source" software and released under the GNU/GPL license. * It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.
* *

* Version history:
* 1997-07-01 Christian d'Heureuse (chdh): Module created.
* 2003-06-30 chdh: Revision.
* ***********************************************************************/ public class ClockApplet extends java.applet.Applet implements Runnable { private String clockLabel = "source-code.biz"; private Color bgColor; private int aaScalingFactor; // anti-aliasing scaling factor private Color secPtrColor = new Color(0xCC,0x00,0x00); private Color borderColor = new Color(0xC0,0xC0,0xC0); private Thread thread; private Image staticImg; private Image dynImg; private int r; private int centerX; private int centerY; private void abend (String msg) { throw new RuntimeException(getClass().getName()+": "+msg); } private void drawRadial (Graphics g, double alpha, int r1, int r2, int width1, int width2) { double sin = Math.sin(alpha); double cos = Math.cos(alpha); double pm1X = sin * r1; double pm1Y = cos * r1; double pm2X = sin * r2; double pm2Y = cos * r2; double pxr[] = new double[4]; double pyr[] = new double[4]; pxr[0] = pm1X - cos*width1/2; pyr[0] = pm1Y + sin*width1/2; pxr[3] = pm1X + cos*width1/2; pyr[3] = pm1Y - sin*width1/2; pxr[1] = pm2X - cos*width2/2; pyr[1] = pm2Y + sin*width2/2; pxr[2] = pm2X + cos*width2/2; pyr[2] = pm2Y - sin*width2/2; int pxi[] = new int[4]; int pyi[] = new int[4]; for (int i=0; i<4; i++) { pxi[i] = centerX + (int)Math.round(pxr[i]); pyi[i] = centerY - (int)Math.round(pyr[i]); } g.fillPolygon (pxi,pyi,4); } private void drawRadialFcirc (Graphics g, double alpha, int r1, int circR) { int p0X = (int)Math.round( centerX + Math.sin(alpha) * r1 ); int p0Y = (int)Math.round( centerY - Math.cos(alpha) * r1 ); g.fillOval (p0X-circR,p0Y-circR,2*circR,2*circR); } private void drawClockLabel (Graphics g) { g.setColor (borderColor); int fontSize = r*20/200; Font f = new Font("Helvetica",Font.PLAIN,fontSize); g.setFont (f); FontMetrics fm = g.getFontMetrics(); g.drawString (clockLabel,centerX-fm.stringWidth(clockLabel)/2,centerY+r/2); } private void drawFilledCircle (Graphics g, int r, Color c) { g.setColor (c); g.fillOval (centerX-r,centerY-r,2*r,2*r); } private void drawStaticImage (Graphics g, int width, int height) { r = Math.min(width,height) * 7 / 16; centerX = width/2; centerY = height/2; g.setColor (bgColor); g.fillRect (0,0,width,height); int borderWidth = r / 54; // drawFilledCircle (g,r+borderWidth+borderWidth,new Color(0xf0,0xf0,0xf0)); drawFilledCircle (g,r+borderWidth,borderColor); drawFilledCircle (g,r,Color.white); g.setColor (Color.black); for (int i=0; i<60; i++) { boolean big = i % 5 == 0; int rlength = big ? r*10/44 : r*3/44; rlength = Math.max(1,rlength); int rwidth = big ? r*3/44 : r/44; rwidth = Math.max(1,rwidth); int r2 = r*42/44; drawRadial (g,2*Math.PI/60*i,r2-rlength,r2,rwidth,rwidth); } drawClockLabel (g); } private void generateStaticImage (int width, int height) { staticImg = createImage(width,height); Graphics g = staticImg.getGraphics(); drawStaticImage (g,width,height); g.dispose(); } private void drawDynamicImage (Graphics g, int hour, int min, int sec) { g.setColor (Color.black); drawRadial (g,2*Math.PI*((hour%12)*60+min)/(12*60),-r*10/44,r*27/44,r*5/44,r*4/44); drawRadial (g,2*Math.PI*min/60,-r*10/44,r*40/44,r*9/88,r*3/44); g.setColor (secPtrColor); int r_1_44 = Math.max(1,r*1/44); drawRadial (g,2*Math.PI*sec/60,-r*14/44,r*27/44,r_1_44,r_1_44); drawRadialFcirc (g,2*Math.PI/60*sec,r*27/44,r*9/88); } private Image genImg (int width, int height, int hour, int min, int sec) { int aaWidth = width * aaScalingFactor; int aaHeight = height * aaScalingFactor; if (staticImg == null || staticImg.getWidth(null)!=aaWidth || staticImg.getHeight(null)!=aaHeight) { generateStaticImage (aaWidth,aaHeight); dynImg = createImage(aaWidth,aaHeight); } Graphics g = dynImg.getGraphics(); g.drawImage (staticImg,0,0,null); drawDynamicImage (g,hour,min,sec); g.dispose(); if (aaScalingFactor <= 1) return dynImg; // AreaAveragingScaleFilter aaFilter = new AreaAveragingScaleFilter(width,height); // ReplicateScaleFilter aaFilter = new ReplicateScaleFilter(width,height); AntiAliasingFilter aaFilter = new AntiAliasingFilter(aaScalingFactor); ImageProducer aaProd = new FilteredImageSource(dynImg.getSource(),aaFilter); Image outImg = createImage(aaProd); return outImg; } private void getTimeNew (int[] time) { java.util.GregorianCalendar cal = new java.util.GregorianCalendar(); time[0] = cal.get(cal.HOUR_OF_DAY); time[1] = cal.get(cal.MINUTE); time[2] = cal.get(cal.SECOND); } public void paint (Graphics g) { int time[] = new int[3]; getTimeNew (time); Image img = genImg(getSize().width,getSize().height,time[0],time[1],time[2]); g.drawImage (img,0,0,null); } public void update (Graphics g) { paint (g); } public void run() { while (thread == Thread.currentThread()) { int secOffs = (int) (System.currentTimeMillis() % 1000); int delayT = 1100 - secOffs; try { Thread.sleep (delayT); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } repaint(); }} public void start() { if (thread == null) { thread = new Thread(this); thread.start(); }} public void stop() { thread = null; } public String getAppletInfo() { return "2003-06-30, Christian d'Heureuse (www.source-code.biz)"; } public void setBgColor (String s) { try { bgColor = new Color(Integer.parseInt(s,16)); } catch (Exception e) { abend ("invalid bgColor parameter ("+e.getMessage()+")"); } repaint(); } public void setAaScalingFactor (String s) { try { aaScalingFactor = Integer.parseInt(s); } catch (Exception e) { abend ("invalid aaScalingFactor parameter ("+e.getMessage()+")"); } repaint(); } private void getParms() { bgColor = Color.white; String s = getParameter("bgColor"); if (s != null) setBgColor (s); aaScalingFactor = 1; s = getParameter("aaScalingFactor"); if (s != null) setAaScalingFactor (s); } public void init() { getParms(); setBackground (bgColor); } };