Created
September 5, 2018 03:53
-
-
Save SwingGuy1024/7b8e52c24d1e8f1425a83b27a86a99e5 to your computer and use it in GitHub Desktop.
Clock for System Tray.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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