1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 *   - Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 *
11 *   - Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 *
15 *   - Neither the name of Oracle nor the names of its
16 *     contributors may be used to endorse or promote products derived
17 *     from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * This source code is provided to illustrate the usage of a given feature
34 * or technique and has been deliberately simplified. Additional steps
35 * required for a production-quality application, such as security checks,
36 * input validation and proper error handling, might not be present in
37 * this sample code.
38 */
39
40
41
42import java.applet.Applet;
43import java.awt.Color;
44import java.awt.Font;
45import java.awt.Graphics;
46import java.text.SimpleDateFormat;
47import java.util.Date;
48import java.util.Locale;
49
50
51/**
52 * Time!
53 *
54 * @author Rachel Gollub
55 * @author Daniel Peek replaced circle drawing calculation, few more changes
56 */
57@SuppressWarnings("serial")
58public class Clock extends Applet implements Runnable {
59
60    private volatile Thread timer;       // The thread that displays clock
61    private int lastxs, lastys, lastxm,
62            lastym, lastxh, lastyh;  // Dimensions used to draw hands
63    private SimpleDateFormat formatter;  // Formats the date displayed
64    private String lastdate;             // String to hold date displayed
65    private Font clockFaceFont;          // Font for number display on clock
66    private Date currentDate;            // Used to get date to display
67    private Color handColor;             // Color of main hands and dial
68    private Color numberColor;           // Color of second hand and numbers
69    private int xcenter = 80, ycenter = 55; // Center position
70
71    @Override
72    public void init() {
73        lastxs = lastys = lastxm = lastym = lastxh = lastyh = 0;
74        formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss yyyy",
75                Locale.getDefault());
76        currentDate = new Date();
77        lastdate = formatter.format(currentDate);
78        clockFaceFont = new Font("Serif", Font.PLAIN, 14);
79        handColor = Color.blue;
80        numberColor = Color.darkGray;
81
82        try {
83            setBackground(new Color(Integer.parseInt(getParameter("bgcolor"),
84                    16)));
85        } catch (NullPointerException e) {
86        } catch (NumberFormatException e) {
87        }
88        try {
89            handColor = new Color(Integer.parseInt(getParameter("fgcolor1"),
90                    16));
91        } catch (NullPointerException e) {
92        } catch (NumberFormatException e) {
93        }
94        try {
95            numberColor = new Color(Integer.parseInt(getParameter("fgcolor2"),
96                    16));
97        } catch (NullPointerException e) {
98        } catch (NumberFormatException e) {
99        }
100        resize(300, 300);              // Set clock window size
101    }
102
103    /**
104     * Paint is the main part of the program
105     */
106    @Override
107    public void update(Graphics g) {
108        int xh, yh, xm, ym, xs, ys;
109        int s = 0, m = 10, h = 10;
110        String today;
111
112        currentDate = new Date();
113
114        formatter.applyPattern("s");
115        try {
116            s = Integer.parseInt(formatter.format(currentDate));
117        } catch (NumberFormatException n) {
118            s = 0;
119        }
120        formatter.applyPattern("m");
121        try {
122            m = Integer.parseInt(formatter.format(currentDate));
123        } catch (NumberFormatException n) {
124            m = 10;
125        }
126        formatter.applyPattern("h");
127        try {
128            h = Integer.parseInt(formatter.format(currentDate));
129        } catch (NumberFormatException n) {
130            h = 10;
131        }
132
133        // Set position of the ends of the hands
134        xs = (int) (Math.cos(s * Math.PI / 30 - Math.PI / 2) * 45 + xcenter);
135        ys = (int) (Math.sin(s * Math.PI / 30 - Math.PI / 2) * 45 + ycenter);
136        xm = (int) (Math.cos(m * Math.PI / 30 - Math.PI / 2) * 40 + xcenter);
137        ym = (int) (Math.sin(m * Math.PI / 30 - Math.PI / 2) * 40 + ycenter);
138        xh = (int) (Math.cos((h * 30 + m / 2) * Math.PI / 180 - Math.PI / 2)
139                * 30
140                + xcenter);
141        yh = (int) (Math.sin((h * 30 + m / 2) * Math.PI / 180 - Math.PI / 2)
142                * 30
143                + ycenter);
144
145        // Get the date to print at the bottom
146        formatter.applyPattern("EEE MMM dd HH:mm:ss yyyy");
147        today = formatter.format(currentDate);
148
149        g.setFont(clockFaceFont);
150        // Erase if necessary
151        g.setColor(getBackground());
152        if (xs != lastxs || ys != lastys) {
153            g.drawLine(xcenter, ycenter, lastxs, lastys);
154            g.drawString(lastdate, 5, 125);
155        }
156        if (xm != lastxm || ym != lastym) {
157            g.drawLine(xcenter, ycenter - 1, lastxm, lastym);
158            g.drawLine(xcenter - 1, ycenter, lastxm, lastym);
159        }
160        if (xh != lastxh || yh != lastyh) {
161            g.drawLine(xcenter, ycenter - 1, lastxh, lastyh);
162            g.drawLine(xcenter - 1, ycenter, lastxh, lastyh);
163        }
164
165        // Draw date and hands
166        g.setColor(numberColor);
167        g.drawString(today, 5, 125);
168        g.drawLine(xcenter, ycenter, xs, ys);
169        g.setColor(handColor);
170        g.drawLine(xcenter, ycenter - 1, xm, ym);
171        g.drawLine(xcenter - 1, ycenter, xm, ym);
172        g.drawLine(xcenter, ycenter - 1, xh, yh);
173        g.drawLine(xcenter - 1, ycenter, xh, yh);
174        lastxs = xs;
175        lastys = ys;
176        lastxm = xm;
177        lastym = ym;
178        lastxh = xh;
179        lastyh = yh;
180        lastdate = today;
181        currentDate = null;
182    }
183
184    @Override
185    public void paint(Graphics g) {
186        g.setFont(clockFaceFont);
187        // Draw the circle and numbers
188        g.setColor(handColor);
189        g.drawArc(xcenter - 50, ycenter - 50, 100, 100, 0, 360);
190        g.setColor(numberColor);
191        g.drawString("9", xcenter - 45, ycenter + 3);
192        g.drawString("3", xcenter + 40, ycenter + 3);
193        g.drawString("12", xcenter - 5, ycenter - 37);
194        g.drawString("6", xcenter - 3, ycenter + 45);
195
196        // Draw date and hands
197        g.setColor(numberColor);
198        g.drawString(lastdate, 5, 125);
199        g.drawLine(xcenter, ycenter, lastxs, lastys);
200        g.setColor(handColor);
201        g.drawLine(xcenter, ycenter - 1, lastxm, lastym);
202        g.drawLine(xcenter - 1, ycenter, lastxm, lastym);
203        g.drawLine(xcenter, ycenter - 1, lastxh, lastyh);
204        g.drawLine(xcenter - 1, ycenter, lastxh, lastyh);
205    }
206
207    @Override
208    public void start() {
209        timer = new Thread(this);
210        timer.start();
211    }
212
213    @Override
214    public void stop() {
215        timer = null;
216    }
217
218    @Override
219    @SuppressWarnings("SleepWhileHoldingLock")
220    public void run() {
221        Thread me = Thread.currentThread();
222        while (timer == me) {
223            try {
224                Thread.sleep(100);
225            } catch (InterruptedException e) {
226            }
227            repaint();
228        }
229    }
230
231    @Override
232    public String getAppletInfo() {
233        return "Title: A Clock \n"
234                + "Author: Rachel Gollub, 1995 \n"
235                + "An analog clock.";
236    }
237
238    @Override
239    public String[][] getParameterInfo() {
240        String[][] info = {
241            { "bgcolor", "hexadecimal RGB number",
242                "The background color. Default is the color of your browser." },
243            { "fgcolor1", "hexadecimal RGB number",
244                "The color of the hands and dial. Default is blue." },
245            { "fgcolor2", "hexadecimal RGB number",
246                "The color of the second hand and numbers. Default is dark gray." }
247        };
248        return info;
249    }
250}
251