SWTClock.java

package com.nokia.example;

/*
 * Copyright © 2011 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ercp.swt.mobile.MobileShell;

public class SWTClock extends SWTMIDlet {

    Display display;
    MobileShell shell;
    Canvas canvas;
    Button exitButton;
    int exitButtonH;
    int h = -1;
    Image imgClock;
    Point imgClockSize;
    Image imgExit;
    Image imgH;
    Point imgHSize;
    Image imgM;
    Point imgMSize;
    Image imgS;
    Point imgSSize;
    int m = -1;
    int s = -1;

    protected void runUI(Display display) {
        this.display = display;

        shell = new MobileShell(display);
        shell.setFullScreenMode(true);

        // Create the clock image
        imgClock = new Image(display, getClass().getResourceAsStream(
                "/clock.png"));
        Rectangle r = imgClock.getBounds();
        imgClockSize = new Point(r.width, r.height);

        // Create the Canvas which will draw the clock.
        canvas = new Canvas(shell, SWT.NONE);
        canvas.addPaintListener(new PaintListener() {

            public void paintControl(PaintEvent e) {
                Rectangle r = canvas.getClientArea();
                if (imgClock != null) {
                    e.gc.drawImage(imgClock, (r.width - imgClockSize.x) / 2,
                            (r.height - imgClockSize.y) / 2);
                }
                if (imgH != null) {
                    e.gc.drawImage(imgH, (r.width - imgHSize.x) / 2,
                            (r.height - imgHSize.y) / 2);
                }
                if (imgM != null) {
                    e.gc.drawImage(imgM, (r.width - imgMSize.x) / 2,
                            (r.height - imgMSize.y) / 2);
                }
                if (imgS != null) {
                    e.gc.drawImage(imgS, (r.width - imgSSize.x) / 2,
                            (r.height - imgSSize.y) / 2);
                }
            }
        });
        canvas.addDisposeListener(new DisposeListener() {

            public void widgetDisposed(DisposeEvent e) {
                disposeResources();
            }
        });

        // Create the exit Button.
        imgExit = new Image(display, getClass().getResourceAsStream("/exit.png"));
        exitButton = new Button(shell, SWT.PUSH);
        exitButton.setImage(imgExit);
        exitButton.addSelectionListener(new SelectionListener() {

            public void widgetDefaultSelected(SelectionEvent e) {
            }

            public void widgetSelected(SelectionEvent e) {
                exit();
            }
        });
        exitButtonH = exitButton.computeSize(-1, -1).y;

        // Layout everything while hidden, then show the app.
        layout();
        shell.open();

        // For the benefit of the automatic start screen, produce the first
        // drawn screen without the arms.
        flush();

        // Start the timer that will repeatedly request a redraw every second.
        Timer t = new Timer();
        t.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                try {
                    SWTClock.this.display.syncExec(new Runnable() {

                        public void run() {
                            update();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 0, 1000);

        // Start listening to UI orientation changes for layout updates.
        shell.addControlListener(new ControlListener() {

            public void controlMoved(ControlEvent e) {
            }

            public void controlResized(ControlEvent e) {
                layout();
            }
        });
    }

    private void disposeResources() {
        if (imgClock != null) {
            imgClock.dispose();
        }
        if (imgExit != null) {
            imgExit.dispose();
        }
        if (imgH != null) {
            imgH.dispose();
        }
        if (imgM != null) {
            imgM.dispose();
        }
        if (imgS != null) {
            imgS.dispose();
        }
    }

    private void flush() {
        while (display.readAndDispatch())
            ;
    }

    private void layout() {
        Rectangle rect = shell.getClientArea();

        if (rect.width < rect.height) {
            canvas.setSize(rect.width, rect.height - exitButtonH);
            exitButton.setBounds(0, rect.height - exitButtonH, rect.width,
                    exitButtonH);
        } else {
            canvas.setSize(rect.width - exitButtonH, rect.height);
            exitButton.setBounds(rect.width - exitButtonH, 0, exitButtonH,
                    rect.height);
        }
    }

    private void update() {
        if (canvas == null || canvas.isDisposed()) {
            return;
        }

        Calendar cal = Calendar.getInstance();
        int m = cal.get(Calendar.MINUTE);
        int h = cal.get(Calendar.HOUR);
        if (h == 12) {
            h = 0;
        }
        h = h * 5 + m / 12;
        if (h == 60) {
            h = 0;
        }
        int s = cal.get(Calendar.SECOND);

        boolean changed = false;
        if (this.h != h) {
            this.h = h;
            if (imgH != null) {
                imgH.dispose();
            }
            imgH = new Image(display, getClass().getResourceAsStream(
                    "/h" + h + ".png"));
            if (imgHSize == null) {
                Rectangle r = imgH.getBounds();
                imgHSize = new Point(r.width, r.height);
            }
            changed = true;
        }
        if (this.m != m) {
            this.m = m;
            if (imgM != null) {
                imgM.dispose();
            }
            imgM = new Image(display, getClass().getResourceAsStream(
                    "/m" + m + ".png"));
            if (imgMSize == null) {
                Rectangle r = imgM.getBounds();
                imgMSize = new Point(r.width, r.height);
            }
            changed = true;
        }
        if (this.s != s) {
            this.s = s;
            if (imgS != null) {
                imgS.dispose();
            }
            imgS = new Image(display, getClass().getResourceAsStream(
                    "/s" + s + ".png"));
            if (imgSSize == null) {
                Rectangle r = imgS.getBounds();
                imgSSize = new Point(r.width, r.height);
            }
            changed = true;
        }

        if (changed) {
            canvas.redraw();
        }
    }
}