--- a/components/visual-panels/core/src/java/util/com/oracle/solaris/vp/util/swing/time/AnalogClock.java Tue Dec 16 05:53:51 2014 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1203 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-package com.oracle.solaris.vp.util.swing.time;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.geom.*;
-import java.awt.image.BufferedImage;
-import java.beans.*;
-import java.util.Calendar;
-import javax.swing.*;
-import org.jdesktop.animation.timing.*;
-import com.oracle.solaris.vp.util.misc.finder.Finder;
-import com.oracle.solaris.vp.util.swing.*;
-
-@SuppressWarnings({"serial"})
-public class AnalogClock extends JPanel implements MouseListener,
- MouseMotionListener, TimingTarget {
-
- //
- // Static data
- //
-
- private static final int _DIAMETER = 150;
-
- //
- // Instance data
- //
-
- private TimeModel model;
- private TimeSelectionModel selModel;
-
- private PropertyChangeListener timeListener =
- new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- timeChanged();
- }
- };
-
- // Cached images to speed up repaints
- private BufferedImage baseImage;
- private BufferedImage timeImage;
- private BufferedImage centerImage;
-
- private int frameWidth;
- private Point centerPoint;
- private Point mousePoint;
- private boolean interactive;
- private boolean useToolTips;
- private SunIcon sunIcon = new SunIcon();
- private MoonIcon moonIcon = new MoonIcon();
- private StarIcon starIcon = new StarIcon();
- private Shape amPm;
- private Point hourPoint;
- private Point minPoint;
- private Point secPoint;
-
- private Animator amPmAnimator = new Animator(300, this);
- private float amPmAnimOffset;
- private int amPmAnimFactor;
-
- // UI prefs
- private Color centerColor = Color.black;
- private Color frameColor = ColorUtil.darker(
- UIManager.getColor("Panel.background"), .2f);
- private Color faceColor = Color.white;
- private Color hourHandColor = Color.black;
- private Color hourMarkColor = Color.black;
- private float lightAngle = (float)Math.toRadians(122);
- private Color minuteHandColor = Color.black;
- private Color minuteMarkColor = Color.gray;
- private Color secondHandColor = Color.red.darker();
- private Color highlightColor = new Color(0, 0, 204);
- private Color amColor = new Color(148, 188, 246);
- private Color pmColor = new Color(0, 0, 78);
-
- //
- // Constructors
- //
-
- /**
- * Constructs an {@code AnalogClock} for the given model.
- */
- public AnalogClock(TimeModel model) {
- setTimeModel(model);
- setTimeSelectionModel(new SimpleTimeSelectionModel());
- setOpaque(false);
- setPreferredDiameter(_DIAMETER);
- }
-
- /**
- * Constructs an {@code AnalogClock} with a zero {@link
- * TimeModel#getTimeOffset offset} from the system clock.
- */
- public AnalogClock() {
- this(new SimpleTimeModel());
- }
-
- //
- // MouseListener methods
- //
-
- @Override
- public void mouseClicked(MouseEvent e) {
- int selectedField = selModel.getSelectedField();
- if (selectedField == Calendar.AM_PM && GUIUtil.isUnmodifiedClick(e, 1))
- {
- amPmAnimOffset = (float)Math.PI;
-
- amPmAnimFactor = model.getCalendar().get(
- selectedField) == Calendar.AM ? 1 : -1;
-
- // 43200000 = 1000 * 60 * 60 * 12 = milliseconds in 12-hour change
- long delta = amPmAnimFactor * 43200000;
- model.setTimeOffset(model.getTimeOffset() + delta);
-
- amPmAnimator.start();
- }
- }
-
- @Override
- public void mouseEntered(MouseEvent e) {
- }
-
- @Override
- public void mouseExited(MouseEvent e) {
- mousePoint = null;
- repaint();
- }
-
- @Override
- public void mousePressed(MouseEvent e) {
- mousePoint = null;
- repaint();
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- mouseMoved(e);
- }
-
- //
- // MouseMotionListener methods
- //
-
- @Override
- public void mouseDragged(MouseEvent e) {
- int selectedField = selModel.getSelectedField();
- if (selectedField != Calendar.HOUR &&
- selectedField != Calendar.MINUTE &&
- selectedField != Calendar.SECOND) {
- return;
- }
-
- Point centerPoint = this.centerPoint;
- Point dragPoint = e.getPoint();
- int dY = centerPoint.y - dragPoint.y;
- int dX = dragPoint.x - centerPoint.x;
- float angle = (float)Math.atan2(dY, dX);
-
- int newVal;
- int period;
-
- if (selectedField == Calendar.HOUR) {
- newVal = (int)radiansToHour(angle);
- period = 12;
- } else {
- newVal = (int)radiansToMin(angle);
- period = 60;
- }
-
- Calendar cal = model.getCalendar();
- int curVal = cal.get(selectedField);
- int factor = (newVal - curVal + period) % period;
- if (factor >= period / 2) {
- factor -= period;
- }
-
- long timeOffset = model.getTimeOffset() + factor *
- timeFieldToMillis(selectedField);
- model.setTimeOffset(timeOffset);
- }
-
- @Override
- public void mouseMoved(MouseEvent e) {
- mousePoint = e.getPoint();
- repaint();
- }
-
- //
- // TimingTarget methods
- //
-
- @Override
- public void begin() {
- }
-
- @Override
- public void end() {
- }
-
- @Override
- public void repeat() {
- }
-
- @Override
- public void timingEvent(float fraction) {
- amPmAnimOffset = amPmAnimFactor * (float)Math.PI * (1 - fraction);
- timeImage = null;
- repaint();
- }
-
- //
- // JComponent methods
- //
-
- @Override
- protected void paintComponent(Graphics g1) {
- super.paintComponent(g1);
-
- Graphics2D g = (Graphics2D)g1;
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
-
- Insets insets = getInsets();
- int width = getWidth() - insets.left - insets.right;
- int height = getHeight() - insets.top - insets.bottom;
-
- if (width <= 0 || height <= 0) {
- return;
- }
-
- // TimeModel is square
- int diameter = Math.min(width, height);
-
- int diff = height - width;
- int hDiff = diff / 2;
- if (diff > 0) {
- diameter = width;
- insets.top += hDiff;
- insets.bottom += diff - hDiff;
- } else if (diff < 0) {
- diameter = height;
- insets.left -= hDiff;
- insets.right -= diff - hDiff;
- }
-
- g.translate(insets.left, insets.top);
-
- createBaseImage(diameter);
- g.drawImage(baseImage, 0, 0, null);
-
- g.translate(frameWidth, frameWidth);
-
- diameter -= 2 * frameWidth;
- int radius = Math.round(diameter/ 2f);
-
- createTimeImage(diameter);
- g.drawImage(timeImage, 0, 0, null);
-
- Point centerPoint = new Point(radius, radius);
- Point mousePoint = this.mousePoint;
-
- if (mousePoint != null) {
- int selectedField = -1;
- mousePoint = (Point)mousePoint.clone();
- mousePoint.translate(-frameWidth - insets.left,
- -frameWidth - insets.top);
-
- Line2D line = new Line2D.Float();
-
- line.setLine(centerPoint, hourPoint);
- double hourDist = line.ptSegDist(mousePoint);
-
- line.setLine(centerPoint, minPoint);
- double minDist = line.ptSegDist(mousePoint);
-
- line.setLine(centerPoint, secPoint);
- double secDist = line.ptSegDist(mousePoint);
-
- // Is the mouse close enough to a hand to call it selected?
- double closest = Math.min(hourDist, Math.min(minDist, secDist));
- if (closest / diameter <= .02f) {
- if (hourDist == closest) {
- selectedField = Calendar.HOUR;
- drawHourHand(g, diameter, centerPoint, hourPoint);
- } else if (minDist == closest) {
- selectedField = Calendar.MINUTE;
- drawMinuteHand(g, diameter, centerPoint, minPoint);
- } else {
- selectedField = Calendar.SECOND;
- drawSecondHand(g, diameter, centerPoint, secPoint);
- }
- } else if (amPm.contains(mousePoint)) {
- selectedField = Calendar.AM_PM;
- }
-
- setSelectedField(selectedField);
- }
-
- createCenterImage(diameter);
- g.drawImage(centerImage, 0, 0, null);
-
- centerPoint.translate(frameWidth + insets.left,
- frameWidth + insets.top);
-
- this.centerPoint = centerPoint;
-
- g.translate(-frameWidth - insets.left, -frameWidth - insets.top);
- }
-
- //
- // AnalogClock methods
- //
-
- protected float amPmToRadians() {
- Calendar cal = model.getCalendar();
- int hour = cal.get(Calendar.HOUR);
- int minute = cal.get(Calendar.MINUTE);
- int second = cal.get(Calendar.SECOND);
- int amPm = cal.get(Calendar.AM_PM);
- return amPmToRadians(amPm, hour, minute, second);
- }
-
- protected Shape drawAmPm(Graphics2D g, int diameter) {
- // Create shapes
-
- float outerMargin = diameter * .17f;
- float innerMargin = diameter * .105f;
-
- diameter -= Math.round(2 * outerMargin);
- float radius = diameter / 2f;
-
- int offset = Math.round(outerMargin);
- g.translate(offset, offset);
-
- Arc2D.Float outer = new Arc2D.Float(0, 0,
- diameter, diameter, 0, 180, Arc2D.OPEN);
-
- int innerDiam = Math.round(2 * innerMargin);
- Arc2D.Float inner = new Arc2D.Float(radius - innerMargin,
- radius - innerMargin, innerDiam, innerDiam, 180, -180, Arc2D.OPEN);
-
- Line2D.Float[] lines = {
- new Line2D.Float(outer.getEndPoint(), inner.getStartPoint()),
- new Line2D.Float(inner.getEndPoint(), outer.getStartPoint()),
- };
-
- GeneralPath window = new GeneralPath(outer);
- window.append(lines[0], true);
- window.append(inner, true);
- window.append(lines[1], true);
- window.closePath();
-
- // Fill background
-
- float angle = (float)Math.PI - amPmToRadians() - amPmAnimOffset;
- float cos = (float)Math.cos(angle);
- float sin = (float)Math.sin(angle);
- float xDelta = radius * cos;
- float yDelta = radius * sin;
-
- g.setPaint(new GradientPaint(
- Math.round(radius + xDelta), Math.round(radius + yDelta), amColor,
- Math.round(radius - xDelta), Math.round(radius - yDelta), pmColor));
- g.fill(window);
-
- // Paint icons
-
- Shape clip = g.getClip();
- g.setClip(window);
-
- float arcWidth = radius - innerMargin;
- float midPointToCtr = innerMargin + arcWidth * .5f;
- int sunIconDiam = (int)(arcWidth * .7f);
- float sunIconRad = sunIconDiam / 2f;
- xDelta = midPointToCtr * cos;
- yDelta = midPointToCtr * sin;
-
- sunIcon.setDiameter(sunIconDiam);
- sunIcon.paintIcon(this, g, Math.round(radius + xDelta - sunIconRad),
- Math.round(radius + yDelta - sunIconRad));
-
- int moonIconDiam = (int)(sunIconDiam * sunIcon.getOrbSizePercentage());
- float moonIconRad = moonIconDiam / 2f;
-
- moonIcon.setDiameter(moonIconDiam);
- moonIcon.paintIcon(this, g, Math.round(radius - xDelta - moonIconRad),
- Math.round(radius - yDelta - moonIconRad));
-
- int starIconDiam = (int)(moonIconDiam * .4f);
- float starIconRad = starIconDiam / 2f;
-
- starIcon.setDiameter(starIconDiam);
-
- // Angle (degree) offset from moon, percent distance between arcs
- float[] starData = {
- -48f, .55f,
- -30f, .22f,
- -25f, .7f,
- 5f, .85f,
- 20f, .25f,
- 25f, .65f,
- 45f, .35f,
- };
-
- for (int i = 0; i < starData.length; i += 2) {
- float starAngle = (float)Math.toRadians(starData[i]);
- float starDist = innerMargin + arcWidth * starData[i + 1];
-
- int x = Math.round(radius - starDist *
- (float)Math.cos(angle + starAngle) - starIconRad);
-
- int y = Math.round(radius - starDist *
- (float)Math.sin(angle + starAngle) - starIconRad);
-
- starIcon.paintIcon(this, g, x, y);
- }
-
- g.setClip(clip);
-
- // Paint inset border
-
- Stroke stroke = g.getStroke();
- g.setStroke(new BasicStroke(diameter / 80));
-
- cos = (float)Math.cos(lightAngle);
- sin = (float)Math.sin(lightAngle);
- xDelta = radius * cos;
- yDelta = radius * sin;
-
- Color color = Color.gray;
- Color shadow = ColorUtil.darker(color, .25f);
- Color light = ColorUtil.darker(Color.white, .25f);
-
- g.setPaint(new GradientPaint(radius + xDelta, radius - yDelta, shadow,
- radius - xDelta, radius + yDelta, light, false));
- g.draw(outer);
-
- xDelta = innerMargin * cos;
- yDelta = innerMargin * sin;
-
- g.setPaint(new GradientPaint(radius + xDelta, radius - yDelta, light,
- radius - xDelta, radius + yDelta, shadow, false));
- g.draw(inner);
-
- float theta = lightAngle - (float)Math.PI / 2f;
- float pct = (1 - (float)Math.cos(theta)) / 2f;
-
- g.setColor(ColorUtil.blend(light, shadow, pct));
- g.draw(lines[0]);
- g.draw(lines[1]);
-
- g.setStroke(stroke);
- g.translate(-offset, -offset);
-
- Shape shape = AffineTransform.getTranslateInstance(offset, offset).
- createTransformedShape(window);
-
- return shape;
- }
-
- protected void drawCenterDot(Graphics2D g, int diameter) {
- float radius = diameter / 2f;
- int dotDiam = Math.round(diameter * .06f);
- float dotRadius = dotDiam / 2f;
- float pctFromCtr = .75f;
- float distFromCtr = dotRadius * pctFromCtr;
- float xCenter = radius + distFromCtr * (float)Math.cos(lightAngle);
- float yCenter = radius - distFromCtr * (float)Math.sin(lightAngle);
-
- Color focusColor = ColorUtil.lighter(centerColor, .65f);
- float[] fractions = {0.0f, 1.0f};
- Color[] colors = {focusColor, centerColor};
- RadialGradientPaint paint = new RadialGradientPaint(
- xCenter, yCenter, dotRadius, fractions, colors,
- MultipleGradientPaint.CycleMethod.NO_CYCLE);
- g.setPaint(paint);
- int coord = Math.round(radius - dotRadius);
- g.fillOval(coord, coord, dotDiam, dotDiam);
- }
-
- protected void drawFace(Graphics2D g, int diameter) {
- g.setColor(faceColor);
- g.fillOval(0, 0, diameter, diameter);
- }
-
- protected int drawFrame(Graphics2D g, int diameter) {
- // Draw outline
- int frameWidth = 0;
- float radius = diameter / 2f;
-
- float cos = (float)Math.cos(lightAngle);
- float sin = (float)Math.sin(lightAngle);
- float pctFromEdge = .67f;
- float xStart = radius * (1 + cos);
- float yStart = radius * (1 - sin);
- float xEnd = radius * (1 + pctFromEdge * cos);
- float yEnd = radius * (1 - pctFromEdge * sin);
-
- g.setPaint(new GradientPaint(xStart, yStart,
- ColorUtil.darker(Color.white, .25f), xEnd, yEnd,
- ColorUtil.darker(frameColor, .25f), false));
- g.fillOval(frameWidth, frameWidth, diameter, diameter);
-
- // Draw outer edge
- int gap = Math.round(diameter * .006f);
- frameWidth += gap;
- diameter -= 2 * gap;
- radius = diameter / 2f;
-
- xStart = radius * (1 + cos);
- yStart = radius * (1 - sin);
- xEnd = radius * (1 + pctFromEdge * cos);
- yEnd = radius * (1 - pctFromEdge * sin);
-
- g.setPaint(new GradientPaint(xStart, yStart, Color.white, xEnd, yEnd,
- frameColor, false));
- g.fillOval(frameWidth, frameWidth, diameter, diameter);
-
- // Draw inner edge
- gap = Math.round(diameter * .025f);
- frameWidth += gap;
- diameter -= 2 * gap;
- radius = diameter / 2f;
-
- cos = (float)Math.cos(lightAngle + Math.PI);
- sin = (float)Math.sin(lightAngle + Math.PI);
- pctFromEdge = .5f;
- xStart = radius * (1 + cos);
- yStart = radius * (1 - sin);
- xEnd = radius * (1 + pctFromEdge * cos);
- yEnd = radius * (1 - pctFromEdge * sin);
-
- g.setPaint(new GradientPaint(xStart, yStart,
- ColorUtil.lighter(frameColor, .55f), xEnd, yEnd, frameColor,
- false));
- g.fillOval(frameWidth, frameWidth, diameter, diameter);
-
- gap = Math.round(diameter * .011f);
- frameWidth += gap;
-
- return frameWidth;
- }
-
- protected void drawHand(Graphics2D g, Color color, float handWidth,
- Point p1, Point p2) {
-
- Stroke stroke = g.getStroke();
- g.setStroke(new BasicStroke(handWidth, BasicStroke.CAP_ROUND,
- BasicStroke.JOIN_MITER));
-
- g.setColor(color);
- g.drawLine(p1.x, p1.y, p2.x, p2.y);
-
- g.setStroke(stroke);
- }
-
- protected Point drawHand(Graphics2D g, Color color, float handWidth,
- float handLength, float angle, int diameter) {
-
- float radius = diameter / 2f;
- float cos = (float)Math.cos(angle);
- float sin = (float)Math.sin(angle);
- int x = Math.round(radius + handLength * cos);
- int y = Math.round(radius - handLength * sin);
-
- // Shadow
- float offset = diameter * .02f;
- cos = (float)Math.cos(lightAngle + Math.PI);
- sin = (float)Math.sin(lightAngle + Math.PI);
- int xOffset = Math.round(offset * cos);
- int yOffset = -Math.round(offset * sin);
-
- drawHand(g, ColorUtil.alpha(Color.black, .2f), handWidth,
- new Point((int)radius + xOffset, (int)radius + yOffset),
- new Point(x + xOffset, y + yOffset));
-
- // Hand
- Point p = new Point(x, y);
- drawHand(g, color, handWidth, new Point((int)radius, (int)radius), p);
-
- return p;
- }
-
- protected void drawHourHand(Graphics2D g, int diameter, Point p1,
- Point p2) {
- drawHand(g, highlightColor, diameter * .02f, p1, p2);
- }
-
- protected Point drawHourHand(Graphics2D g, int diameter) {
- return drawHand(g, hourHandColor, diameter * .02f, diameter * .275f,
- hourToRadians(), diameter);
- }
-
- protected void drawHourMarks(Graphics2D g, int diameter) {
- float markWidth = diameter * .015f;
- float markLength = diameter * .04f;
- float pctFromCtr = .9f;
- float radius = diameter / 2f;
-
- Stroke stroke = g.getStroke();
- g.setStroke(new BasicStroke(markWidth, BasicStroke.CAP_ROUND,
- BasicStroke.JOIN_MITER));
- g.setColor(hourMarkColor);
-
- float angleConst = (float)Math.PI / 6f;
- float distFromCtrStart = radius * pctFromCtr;
- float distFromCtrEnd = distFromCtrStart - markLength;
-
- for (int i = 0; i < 12; i++) {
- float angle = i * angleConst;
- float cos = (float)Math.cos(angle);
- float sin = (float)Math.sin(angle);
-
- int xStart = Math.round(radius + distFromCtrStart * cos);
- int yStart = Math.round(radius - distFromCtrStart * sin);
-
- int xEnd = Math.round(radius + distFromCtrEnd * cos);
- int yEnd = Math.round(radius - distFromCtrEnd * sin);
-
- g.drawLine(xStart, yStart, xEnd, yEnd);
- }
-
- g.setStroke(stroke);
- }
-
- protected void drawMinuteHand(Graphics2D g, int diameter, Point p1,
- Point p2) {
- drawHand(g, highlightColor, diameter * .02f, p1, p2);
- }
-
- protected Point drawMinuteHand(Graphics2D g, int diameter) {
- return drawHand(g, minuteHandColor, diameter * .02f, diameter * .405f,
- minToRadians(), diameter);
- }
-
- protected void drawMinuteMarks(Graphics2D g, int diameter) {
- float markWidth = diameter * .009f;
- float markLength = diameter * .015f;
- float pctFromCtr = .9f;
- float radius = diameter / 2f;
-
- Stroke stroke = g.getStroke();
- g.setStroke(new BasicStroke(markWidth, BasicStroke.CAP_ROUND,
- BasicStroke.JOIN_MITER));
- g.setColor(minuteMarkColor);
-
- float angleConst = (float)Math.PI / 30f;
- float distFromCtrStart = radius * pctFromCtr;
- float distFromCtrEnd = distFromCtrStart - markLength;
-
- for (int i = 0; i < 60; i++) {
- if (i % 5 != 0) {
- float angle = i * angleConst;
- float cos = (float)Math.cos(angle);
- float sin = (float)Math.sin(angle);
-
- int xStart = Math.round(radius + distFromCtrStart * cos);
- int yStart = Math.round(radius - distFromCtrStart * sin);
-
- int xEnd = Math.round(radius + distFromCtrEnd * cos);
- int yEnd = Math.round(radius - distFromCtrEnd * sin);
-
- g.drawLine(xStart, yStart, xEnd, yEnd);
- }
- }
-
- g.setStroke(stroke);
- }
-
- protected void drawSecondHand(Graphics2D g, int diameter, Point p1,
- Point p2) {
- drawHand(g, highlightColor, diameter * .011f, p1, p2);
- }
-
- protected Point drawSecondHand(Graphics2D g, int diameter) {
- return drawHand(g, secondHandColor, diameter * .011f,
- diameter * .405f, secToRadians(), diameter);
- }
-
- protected void drawShadow(Graphics2D g, int diameter) {
- // This puts the shadow around the entire face, which also looks nice
- // float offset = 0f;
- // float[] fractions = {0f, .95f, 1f};
-
- float radius = diameter / 2f;
- Color shadow = Color.black;
- Color focus = ColorUtil.alpha(Color.black, 0f);
- float[] fractions = {0f, .94f, 1f};
- Color[] colors = {focus, focus, shadow};
-
- float cos = (float)Math.cos(lightAngle + Math.PI);
- float sin = (float)Math.sin(lightAngle + Math.PI);
- float offset = radius * .02f;
- float xOffset = offset * cos;
- float yOffset = -offset * sin;
- RadialGradientPaint paint = new RadialGradientPaint(radius + xOffset,
- radius + yOffset, radius + offset, fractions, colors,
- MultipleGradientPaint.CycleMethod.NO_CYCLE);
-
- g.setPaint(paint);
- g.fillOval(0, 0, diameter, diameter);
- }
-
- /**
- * Gets the color at the AM end of the AM-PM gradient.
- */
- public Color getAmColor() {
- return amColor;
- }
-
- /**
- * Gets the {@code Animator} the controls the animation of the interactive
- * change from AM to PM and back.
- */
- public Animator getAmPmAnimator() {
- return amPmAnimator;
- }
-
- /**
- * Gets the color of the center dial of the clock.
- */
- public Color getCenterColor() {
- return centerColor;
- }
-
- /**
- * Gets the color of the face of the clock.
- */
- public Color getFaceColor() {
- return faceColor;
- }
-
- /**
- * Gets the color of the outer frame of the clock.
- */
- public Color getFrameColor() {
- return frameColor;
- }
-
- /**
- * Gets the color to use when highlighting a hand.
- */
- public Color getHighlightColor() {
- return highlightColor;
- }
-
- public Color getHourHandColor() {
- return hourHandColor;
- }
-
- /**
- * Gets the color of the hour mark on the clock face.
- */
- public Color getHourMarkColor() {
- return hourMarkColor;
- }
-
- /**
- * Gets the angle of the light, in radians, with 0 at three o'clock, shining
- * onto the clock.
- */
- public float getLightAngle() {
- return lightAngle;
- }
-
- public Color getMinuteHandColor() {
- return minuteHandColor;
- }
-
- /**
- * Gets the color of the minute mark on the clock face.
- */
- public Color getMinuteMarkColor() {
- return minuteMarkColor;
- }
-
- /**
- * Gets the color at the PM end of the AM-PM gradient.
- */
- public Color getPmColor() {
- return pmColor;
- }
-
- public Color getSecondHandColor() {
- return secondHandColor;
- }
-
- public TimeModel getTimeModel() {
- return model;
- }
-
- public TimeSelectionModel getTimeSelectionModel() {
- return selModel;
- }
-
- /**
- * Gets whether to use instructional tooltips over the interactive portions
- * of the clock.
- */
- public boolean getUseToolTips() {
- return useToolTips;
- }
-
- protected float hourToRadians() {
- Calendar cal = model.getCalendar();
- int hour = cal.get(Calendar.HOUR);
- int minute = cal.get(Calendar.MINUTE);
- int second = cal.get(Calendar.SECOND);
- return hourToRadians(hour, minute, second);
- }
-
- /**
- * Gets whether this {@code AnalogClock}'s time can be set by dragging the
- * hands.
- */
- public boolean isInteractive() {
- return interactive;
- }
-
- protected float minToRadians() {
- Calendar cal = model.getCalendar();
- int minute = cal.get(Calendar.MINUTE);
- int second = cal.get(Calendar.SECOND);
- return minToRadians(minute, second);
- }
-
- protected float secToRadians() {
- Calendar cal = model.getCalendar();
- int second = cal.get(Calendar.SECOND);
- return secToRadians(second);
- }
-
- /**
- * Sets the color at the AM end of the AM-PM gradient.
- */
- public void setAmColor(Color amColor) {
- this.amColor = amColor;
- repaint();
- }
-
- /**
- * Sets the color of the center dial of the clock.
- */
- public void setCenterColor(Color centerColor) {
- this.centerColor = centerColor;
- repaint();
- }
-
- /**
- * Sets the preferred widht and height of this {@code AnalogClock} to {@code
- * diameter}.
- */
- public void setPreferredDiameter(int diameter) {
- setPreferredSize(new Dimension(diameter, diameter));
- }
-
- /**
- * Sets the color of the face of the clock.
- */
- public void setFaceColor(Color faceColor) {
- this.faceColor = faceColor;
- baseImage = null;
- repaint();
- }
-
- /**
- * Sets the color of the outer frame of the clock.
- */
- public void setFrameColor(Color frameColor) {
- this.frameColor = frameColor;
- baseImage = null;
- repaint();
- }
-
- /**
- * Sets the color to use when highlighting a hand.
- */
- public void setHighlightColor(Color highlightColor) {
- this.highlightColor = highlightColor;
- }
-
- public void setHourHandColor(Color hourHandColor) {
- this.hourHandColor = hourHandColor;
- repaint();
- }
-
- /**
- * Sets the color of the hour mark on the clock face.
- */
- public void setHourMarkColor(Color hourMarkColor) {
- this.hourMarkColor = hourMarkColor;
- baseImage = null;
- repaint();
- }
-
- /**
- * Sets whether this {@code AnalogClock}'s time can be set by dragging the
- * hands.
- */
- public void setInteractive(boolean interactive) {
- if (this.interactive != interactive) {
- this.interactive = interactive;
- if (interactive) {
- addMouseListener(this);
- addMouseMotionListener(this);
- } else {
- removeMouseListener(this);
- removeMouseMotionListener(this);
- mousePoint = null;
- }
- }
- }
-
- /**
- * Sets the angle of the light, in radians, with 0 at three o'clock, shining
- * onto the clock.
- */
- public void setLightAngle(float lightAngle) {
- this.lightAngle = lightAngle;
- baseImage = null;
- timeImage = null;
- centerImage = null;
- repaint();
- }
-
- public void setMinuteHandColor(Color minuteHandColor) {
- this.minuteHandColor = minuteHandColor;
- repaint();
- }
-
- /**
- * Sets the color of the minute mark on the clock face.
- */
- public void setMinuteMarkColor(Color minuteMarkColor) {
- this.minuteMarkColor = minuteMarkColor;
- baseImage = null;
- repaint();
- }
-
- /**
- * Sets the color at the PM end of the AM-PM gradient.
- */
- public void setPmColor(Color pmColor) {
- this.pmColor = pmColor;
- repaint();
- }
-
- public void setSecondHandColor(Color secondHandColor) {
- this.secondHandColor = secondHandColor;
- repaint();
- }
-
- public void setTimeModel(TimeModel model) {
- if (this.model != model) {
- if (this.model != null) {
- this.model.removePropertyChangeListener(timeListener);
- }
-
- model.addPropertyChangeListener(TimeModel.PROPERTY_TIME,
- timeListener);
-
- this.model = model;
- timeChanged();
- }
- }
-
- public void setTimeSelectionModel(TimeSelectionModel selModel) {
- this.selModel = selModel;
- }
-
- /**
- * Sets whether to use instructional tooltips over the interactive portions
- * of the clock.
- */
- public void setUseToolTips(boolean useToolTips) {
- if (this.useToolTips != useToolTips) {
- this.useToolTips = useToolTips;
- setToolTipText();
- }
- }
-
- //
- // Private methods
- //
-
- private void createBaseImage(int diameter) {
- if (baseImage == null || baseImage.getWidth() != diameter) {
- baseImage = new BufferedImage(diameter, diameter,
- BufferedImage.TYPE_INT_ARGB);
-
- Graphics2D g = baseImage.createGraphics();
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
-
- frameWidth = drawFrame(g, diameter);
- diameter -= 2 * frameWidth;
-
- g.translate(frameWidth, frameWidth);
-
- drawFace(g, diameter);
- drawHourMarks(g, diameter);
- drawMinuteMarks(g, diameter);
- drawShadow(g, diameter);
-
- g.translate(-frameWidth, -frameWidth);
- }
- }
-
- private void createCenterImage(int diameter) {
- if (centerImage == null || centerImage.getWidth() != diameter) {
- centerImage = new BufferedImage(diameter, diameter,
- BufferedImage.TYPE_INT_ARGB);
-
- Graphics2D g = centerImage.createGraphics();
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
-
- drawCenterDot(g, diameter);
- }
- }
-
- private void createTimeImage(int diameter) {
- if (timeImage == null || timeImage.getWidth() != diameter) {
- timeImage = new BufferedImage(diameter, diameter,
- BufferedImage.TYPE_INT_ARGB);
-
- Graphics2D g = timeImage.createGraphics();
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
-
- amPm = drawAmPm(g, diameter);
- hourPoint = drawHourHand(g, diameter);
- minPoint = drawMinuteHand(g, diameter);
- secPoint = drawSecondHand(g, diameter);
- }
- }
-
- private void setSelectedField(int selectedField) {
- setCursor(selectedField == -1 ? null :
- Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
- selModel.setSelectedField(selectedField);
-
- setToolTipText();
- }
-
- private void setToolTipText() {
- String resource = null;
-
- if (useToolTips) {
- switch (selModel.getSelectedField()) {
- case Calendar.AM_PM:
- resource = "time.tooltip.ampm";
- break;
-
- case Calendar.HOUR:
- resource = "time.tooltip.hour";
- break;
-
- case Calendar.MINUTE:
- resource = "time.tooltip.minute";
- break;
-
- case Calendar.SECOND:
- resource = "time.tooltip.second";
- break;
- }
- }
-
- setToolTipText(resource == null ? null : Finder.getString(resource));
- }
-
- private void timeChanged() {
- timeImage = null;
- repaint();
- }
-
- //
- // Static methods
- //
-
- public static float amPmToRadians(int amPm, int hour, int minute,
- int second) {
-
- hour = (hour % 12) + (amPm == Calendar.PM ? 12 : 0);
- return (6 - (hour + minute / 60f + second / 3600f)) * (float)Math.PI /
- 12f;
- }
-
- public static float hourToRadians(int hour, int minute, int second) {
- return (15 - (hour + minute / 60f + second / 3600f)) * (float)Math.PI /
- 6f;
- }
-
- public static float minToRadians(int minute, int second) {
- return (75 - (minute + second / 60f)) * (float)Math.PI / 30f;
- }
-
- public static float radiansToHour(float radians) {
- float value = (-6 * radians / (float)Math.PI) + 3;
- if (value < 1) {
- value += 12;
- }
- return value;
- }
-
- public static float radiansToMin(float radians) {
- float value = (-30 * radians / (float)Math.PI) + 15;
- if (value < 0) {
- value += 60;
- }
- return value;
- }
-
- public static float secToRadians(int second) {
- return (75 - second) * (float)Math.PI / 30f;
- }
-
- /**
- * Converts {@code Calendar} time fields to milliseconds.
- *
- * @param calendarField
- * {@code Calendar.MILLISECOND},
- * {@code Calendar.SECOND},
- * {@code Calendar.MINUTE},
- * {@code Calendar.HOUR},
- * {@code Calendar.HOUR_OF_DAY}, or
- * {@code Calendar.AM_PM},
- *
- * @return the number of milliseconds in a unit of the given field, or
- * zero if {@code calendarField} is not any of the allowed
- * fields
- */
- public static long timeFieldToMillis(int calendarField) {
- long millis = 0;
- switch (calendarField) {
- case Calendar.MILLISECOND:
- millis = 1;
- break;
-
- case Calendar.SECOND:
- millis = 1000;
- break;
-
- case Calendar.MINUTE:
- millis = 60000;
- break;
-
- case Calendar.HOUR:
- case Calendar.HOUR_OF_DAY:
- millis = 3600000;
- break;
-
- case Calendar.AM_PM:
- millis = 43200000;
- break;
- }
-
- return millis;
- }
-
- public static void main(String args[]) {
- AnalogClock clock = new AnalogClock();
- clock.setInteractive(true);
- clock.setPreferredDiameter(300);
-
- TimeModelUpdater updater = new TimeModelUpdater(clock.getTimeModel());
- updater.start();
-
- JFrame frame = new JFrame();
- Container c = frame.getContentPane();
- c.setLayout(new BorderLayout());
- c.add(clock, BorderLayout.CENTER);
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- frame.pack();
- frame.setVisible(true);
- }
-}