Skip to content

Instantly share code, notes, and snippets.

@SwingGuy1024
Created September 5, 2018 03:53
Show Gist options
  • Save SwingGuy1024/7b8e52c24d1e8f1425a83b27a86a99e5 to your computer and use it in GitHub Desktop.
Save SwingGuy1024/7b8e52c24d1e8f1425a83b27a86a99e5 to your computer and use it in GitHub Desktop.
Clock for System Tray.
package com.mm.exp.clock;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public final class PacificTime {
private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("PST");
private final Dimension center;
private Line2D hourHand;
private Line2D minuteHand;
private Line2D hourTic;
private volatile Calendar cal = new GregorianCalendar();
private final Shape circle;
private final Stroke half = new BasicStroke(0.5f);
private final Stroke one = new BasicStroke(1.0f);
private final DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
private static TrayIcon icon;
private static Dimension size;
private static final double twoPi = 2.0 * Math.PI;
private static final long delay = 60000L;
private static final Color transparent = new Color(0, 0, 0, 0);
public static void main(String[] args) throws AWTException {
SystemTray systemTray = SystemTray.getSystemTray();
size = systemTray.getTrayIconSize();
PacificTime pacificTime = new PacificTime();
Image image = makeImage(pacificTime);
pacificTime.previousImage = image;
icon = new TrayIcon(image);
icon.setToolTip(pacificTime.getToolTipText());
addMenu(icon);
systemTray.add(icon);
startThread(pacificTime);
}
private PacificTime() {
center = new Dimension(size.width/2, size.height/2);
circle = new Arc2D.Double(1.0, 1.0, size.getWidth()-2.0, size.getHeight()-2.0, 0.0, 360.0, Arc2D.OPEN);
double minHandLength = ((double) (size.height - 2) / 2.0) * 0.9;
double hourHandLength = minHandLength * 0.7;
hourHand = new Line2D.Double(0.0, 0.0, 0.0, -hourHandLength);
minuteHand = new Line2D.Double(0.0, 0.0, 0.0, -minHandLength);
hourTic = new Line2D.Double(0.0, minHandLength, 0.0, (size.getHeight()/2.0));
cal.setTimeZone(TIME_ZONE);
format.setTimeZone(TIME_ZONE);
}
private void paintIcon(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2.setColor(transparent);
g2.fillRect(0, 0, getIconWidth(), getIconHeight());
g2.setColor(Color.WHITE);
g2.fill(circle);
g2.setStroke(half);
g2.setColor(Color.lightGray);
g2.draw(circle);
int hour = cal.get(Calendar.HOUR);
int min = cal.get(Calendar.MINUTE);
double fullHour = ((double) hour + ((double) min / 60.0))/12.0;
double fullMinute = (double) min / 60.0;
double minAngle = fullMinute * twoPi;
double hourAngle = fullHour * twoPi;
drawHands(g2, minAngle, hourAngle);
}
private static void addMenu(TrayIcon icon) {
PopupMenu popupMenu = new PopupMenu();
icon.setPopupMenu(popupMenu);
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener((e) -> SystemTray.getSystemTray().remove(icon));
popupMenu.add(exitItem);
}
private void drawHands(Graphics2D g2, double minAngle, double hourAngle) {
AffineTransform savedTransform = g2.getTransform();
g2.translate(center.width, center.height);
g2.setStroke(half);
g2.setColor(Color.BLACK);
double hourTicAngle = twoPi/12.0;
for (int ii=0; ii<12; ++ii) {
g2.draw(hourTic);
g2.rotate(hourTicAngle);
}
g2.rotate(minAngle);
g2.setStroke(one);
g2.draw(minuteHand);
g2.rotate(hourAngle - minAngle);
g2.setColor(Color.RED);
g2.draw(hourHand);
g2.setTransform(savedTransform);
}
private Image previousImage = null;
private static Image makeImage(PacificTime icon) {
Image image = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g2 = image.getGraphics();
icon.paintIcon(g2);
g2.dispose();
return image;
}
private String getToolTipText() {
Date date = new Date();
cal.setTime(date);
return format.format(cal.getTime());
}
private static int getIconWidth() {
return size.width;
}
private static int getIconHeight() {
return size.height;
}
private static void startThread(final PacificTime pacificTime) {
Thread thread = new Thread(pacificTime::timerLoop);
thread.setDaemon(true);
thread.start();
}
private void timerLoop() {
//noinspection InfiniteLoopStatement
while (true) {
long delta = delay - (System.currentTimeMillis() % delay); // millis remaining in current minute
try {
//noinspection BusyWait
Thread.sleep(delta);
} catch (InterruptedException ignored) { }
icon.setToolTip(getToolTipText());
Image prior = previousImage;
Image current = makeImage(this);
icon.setImage(current);
prior.flush();
previousImage = current;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment