Java tutorial
import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.Customizer; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Calendar; import java.util.Date; import javax.swing.JButton; import javax.swing.JFrame; public class Clock extends JButton implements Customizer, Externalizable, Runnable { protected PropertyChangeSupport propertyChangeSupport; protected boolean isDigital = false; protected Calendar calendar = Calendar.getInstance(); public Clock() { propertyChangeSupport = new PropertyChangeSupport(this); setBackground(Color.white); setForeground(Color.black); (new Thread(this)).start(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeBoolean(isDigital); out.writeObject(getBackground()); out.writeObject(getForeground()); out.writeObject(getPreferredSize()); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { setDigital(in.readBoolean()); setBackground((Color) in.readObject()); setForeground((Color) in.readObject()); setPreferredSize((Dimension) in.readObject()); } public Dimension getPreferredSize() { return new Dimension(50, 50); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getMaximumSize() { return getPreferredSize(); } public void setDigital(boolean digital) { propertyChangeSupport.firePropertyChange("digital", new Boolean(isDigital), new Boolean(digital)); isDigital = digital; repaint(); } public boolean getDigital() { return isDigital; } public void addPropertyChangeListener(PropertyChangeListener lst) { if (propertyChangeSupport != null) propertyChangeSupport.addPropertyChangeListener(lst); } public void removePropertyChangeListener(PropertyChangeListener lst) { if (propertyChangeSupport != null) propertyChangeSupport.removePropertyChangeListener(lst); } public void setObject(Object bean) { } public void paintComponent(Graphics g) { super.paintComponent(g); Color colorRetainer = g.getColor(); g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight()); calendar.setTime(new Date()); // get current time int hrs = calendar.get(Calendar.HOUR_OF_DAY); int min = calendar.get(Calendar.MINUTE); g.setColor(getForeground()); if (isDigital) { String time = "" + hrs + ":" + min; g.setFont(getFont()); FontMetrics fm = g.getFontMetrics(); int y = (getHeight() + fm.getAscent()) / 2; int x = (getWidth() - fm.stringWidth(time)) / 2; g.drawString(time, x, y); } else { int x = getWidth() / 2; int y = getHeight() / 2; int rh = getHeight() / 4; int rm = getHeight() / 3; double ah = ((double) hrs + min / 60.0) / 6.0 * Math.PI; double am = min / 30.0 * Math.PI; g.drawLine(x, y, (int) (x + rh * Math.sin(ah)), (int) (y - rh * Math.cos(ah))); g.drawLine(x, y, (int) (x + rm * Math.sin(am)), (int) (y - rm * Math.cos(am))); } g.setColor(colorRetainer); } public void run() { while (true) { repaint(); try { Thread.sleep(30 * 1000); } catch (InterruptedException ex) { break; } } } public static void main(String[] a) { JFrame f = new JFrame(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Clock c = new Clock(); f.getContentPane().add("Center", c); f.pack(); f.setSize(new Dimension(300, 300)); f.show(); } }