Java by Example - digital clocks, HTML page parameters

back 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 next

Displaying a simple digital clock is not difficult. The following code demonstrates this. You need an offscreen image for flicker free animation though. with Date today=new Date(); we create an object (a variable) of the class Date. To access it, we have to import java.util.* With getSeconds() etc. we retrieve the seconds of the current time as an integer. This is transformed into a String and displayed. We redraw everything 10 times a second, to get the precise seconds jump.

//Sourcecode

import java.awt.*;
import java.applet.*;
//we need to import the util package for the time functions
import java.util.*;

public class Project18 extends Applet implements Runnable
{
    Thread runner;
    Image Buffer;
    Graphics gBuffer;

    public void init()
    {
        //create off-screen image we can draw to
        Buffer=createImage(size().width,size().height);
        gBuffer=Buffer.getGraphics();
    }

    public void start()
    {
        if (runner == null)
        {
            runner = new Thread (this);
            runner.start();
        }
    }

    public void stop()
    {
        if (runner != null)
        {
            runner.stop();
            runner = null;
        }
    }

    public void run()
    {
        while(true)
        {
            //halt the thread for 100 ms here
            try {runner.sleep(100);}
            catch (Exception e) { }

            repaint();
        }
    }

    public void update(Graphics g)
    {
        paint(g);
    }

    public void paint (Graphics g)
    {
        //create a new time object
        Date today=new Date();

        //get the seconds, minutes and hours
        int sec=today.getSeconds();
        int min=today.getMinutes();
        int hour=today.getHours();

        String secStr, minStr, hourStr;

        //copy the time integers to our string objects
        //if values are less than 10 we add a 0
        if(hour<10)
            hourStr="0"+hour;
        else
            hourStr=""+hour;

        if(min<10)
            minStr="0"+min;
        else
            minStr=""+min;

        if(sec<10)
            secStr="0"+sec;
        else
            secStr=""+sec;

        //repaint the background black
        gBuffer.setColor(Color.black);
        gBuffer.fillRect(0,0,size().width,size().height);

        //set a new font we create "on the fly"
        gBuffer.setFont(new Font("Helvetica", Font.BOLD,65));
        gBuffer.setColor(Color.green);
        gBuffer.drawString(hourStr+":"+minStr+":"+secStr,20,73);

        //copy the buffer to the screen (no flicker!)
        g.drawImage (Buffer,0,0, this);
    }
}

In the following applet code we introduce parameters, which pass values to your applet from the embedding HTML page. So you can change to behavior, colors etc. of your applet before it is started to custimize it at the user's will. In this applet we make the background color and the foreground color customizable (pass the colors as hexadecimal values, like in HTML code). Additionally you can change the font size (so you can adjust the font to the size of the applet) and whether you prefer 12 hour (U.S.) format or military (European) format. The four applets you can see here use all the same class file, but different parameters. See the sourcecode of this HTML page, to see the details of how this is done.

//Sourcecode

import java.awt.*;
import java.applet.*;
//we need to import the util package for the time functions
import java.util.*;

public class Project19 extends Applet implements Runnable
{
    Thread runner;
    Image Buffer;
    Graphics gBuffer;
    Color bgColor, fgColor;
    int fontSize;
    int format24;

    public void init()
    {
        //create off-screen image we can draw to
        Buffer=createImage(size().width,size().height);
        gBuffer=Buffer.getGraphics();

        //Interprete the parameters from the HTML page

        //read the fontSize parameter
        String clockSizeStr=getParameter("font_size");
        //we have to convert the String to an integer, base is 10 (decimal)
        fontSize=Integer.parseInt(clockSizeStr, 10);

        format24=Integer.parseInt(getParameter("format24"), 10);

        //read the background color parameter
        String bgColorStr=getParameter("bg_color");
        int intvalue;
        //convert the String to an integer, base is 16 (hexadecimal)
        intvalue=Integer.parseInt(bgColorStr, 16);

        bgColor=(new Color(intvalue));

        //read the foreground color parameter
        String fgColorStr=getParameter("fg_color");
        intvalue=Integer.parseInt(fgColorStr, 16);

        fgColor=(new Color(intvalue));
    }

    public void start()
    {
        if (runner == null)
        {
            runner = new Thread (this);
            runner.start();
        }
    }

    public void stop()
    {
        if (runner != null)
        {
            runner.stop();
            runner = null;
        }
    }

    public void run()
    {
        while(true)
        {
            //halt the thread for 100 ms here
            try {runner.sleep(100);}
            catch (Exception e) { }

            repaint();
        }
    }

    public void update(Graphics g)
    {
        paint(g);
    }

    public void paint (Graphics g)
    {
        //create a new time object
        Date today=new Date();

        //get the seconds, minutes and hours
        int sec=today.getSeconds();
        int min=today.getMinutes();
        int hour=today.getHours();

        String secStr, minStr, hourStr;

        //copy the time integers to our string objects
        //if values are less than 10 we add a 0

        //12 hour US time format with AM and PM
        boolean am;

        if(hour<12)
            am=true;
        else
            am=false;

        if(format24==0&&hour>12)
            hour-=12;

        if(hour<10)
            hourStr="0"+hour;
        else
            hourStr=""+hour;

        if(min<10)
            minStr="0"+min;
        else
            minStr=""+min;

        if(sec<10)
            secStr="0"+sec;
        else
            secStr=""+sec;

        //repaint the background in the background color
        gBuffer.setColor(bgColor);
        gBuffer.fillRect(0,0,size().width,size().height);

        //draw a thin frame in the foreground color
        gBuffer.setColor(fgColor);
        gBuffer.drawRect(0,0,size().width-1,size().height-1);

        String outputString=hourStr+":"+minStr+":"+secStr;

        if(format24==0)
        {
            if(am==true)
                outputString+=" AM";
            else
                outputString+=" PM";
        }

        Font clockFont=new Font("Helvetica", Font.BOLD, fontSize);

        //measure the size of the string to center it
        FontMetrics fm = gBuffer.getFontMetrics(clockFont);
        int stringWidth=fm.stringWidth(outputString);
        int stringHeight=gBuffer.getFontMetrics().getAscent()-fontSize/4;

        //set the font and the foreground color
        gBuffer.setFont(clockFont);
        gBuffer.setColor(fgColor);

        //center the string inside the applet
        gBuffer.drawString(outputString,
                 (size().width-stringWidth)/2, (size().height+stringHeight)/2);

        //copy the buffer to the screen (no flicker!)
        g.drawImage (Buffer,0,0, this);
    }
}

This advanced digital clock uses GIF digits to display the time. Also we implemented blinking dots, to make it even prettier. To tell which digit GIFs we have to draw, we pass a substring from the string, containing hour, minute or second to a little method which draws the correct digit in the right position for us. Always try to split your code into as many logical functions (methods) as possible!

//Sourcecode

import java.awt.*;
import java.applet.*;
//we need to import the util package for the time functions
import java.util.*;

public class Project20 extends Applet implements Runnable
{
    Thread runner;
    Image Buffer;
    Image Digits[];
    Graphics gBuffer;
    int oldSec, ticker;
    boolean dotFlash, flash;

    public Image loadImage(String img)
    {
        Image image=getImage(getDocumentBase(),img);
        MediaTracker tracker=new MediaTracker(this);
        tracker.addImage(image,0);
        try{tracker.waitForID(0);}
        catch(InterruptedException e){}
        return image;
    }

    public void init()
    {
        Digits=new Image[12];

        //we load our digit images
        for(int i=0;i<10;i++)
            Digits[i]=loadImage("digits/"+i+".gif");

        Digits[10]=loadImage("digits/dot_p.gif");
        Digits[11]=loadImage("digits/dot_a.gif");

        //create off-screen image we can draw to
        Buffer=createImage(size().width,size().height);
        gBuffer=Buffer.getGraphics();
    }

    public void start()
    {
        if (runner == null)
        {
            runner = new Thread (this);
            runner.start();
        }
    }

    public void stop()
    {
        if (runner != null)
        {
            runner.stop();
            runner = null;
        }
    }

    public void run()
    {
        while(true)
        {
            //halt the thread for 50 ms here
            try {runner.sleep(50);}
            catch (Exception e) { }

            repaint();
        }
    }

    public void update(Graphics g)
    {
        paint(g);
    }

    public void drawDigit(int digit, int x)
    {
        gBuffer.drawImage(Digits[digit],x,5,this);
    }

    public void paint (Graphics g)
    {
        //create a new time object
        Date today=new Date();

        //get the seconds, minutes and hours
        int sec=today.getSeconds();
        int min=today.getMinutes();
        int hour=today.getHours();

        if(flash)
        {
            ticker++;

            if(ticker>9)
            {
                ticker=0;
                flash=false;
            }
        }

        if(sec!=oldSec)
        {
            dotFlash=true;
            oldSec=sec;
            flash=true;
        }
        else if(flash==false)
            dotFlash=false;

        String secStr, minStr, hourStr;

        //copy the time integers to our string objects
        //if values are less than 10 we add a 0
        if(hour<10)
            hourStr="0"+hour;
        else
            hourStr=""+hour;

        if(min<10)
            minStr="0"+min;
        else
            minStr=""+min;

        if(sec<10)
            secStr="0"+sec;
        else
            secStr=""+sec;

        //fill the background
        gBuffer.setColor(new Color(105,0,0));
        gBuffer.fillRect(0,0,size().width,size().height);

        //draw a thin frame
        gBuffer.setColor(new Color(255,105,40));
        gBuffer.drawRect(0,0,size().width-1,size().height-1);

        //we draw our digits from our method drawDigit
        drawDigit(Integer.parseInt(hourStr.substring(0,1)),5);
        drawDigit(Integer.parseInt(hourStr.substring(1,2)),35);

        drawDigit(Integer.parseInt(minStr.substring(0,1)),72);
        drawDigit(Integer.parseInt(minStr.substring(1,2)),102);

        drawDigit(Integer.parseInt(secStr.substring(0,1)),139);
        drawDigit(Integer.parseInt(secStr.substring(1,2)),169);

        //the blinking dots
        if(dotFlash)
        {
            gBuffer.drawImage(Digits[11],65,5,this);
            gBuffer.drawImage(Digits[11],132,5,this);
        }
        else
        {
            gBuffer.drawImage(Digits[10],65,5,this);
            gBuffer.drawImage(Digits[10],132,5,this);
        }

        //copy the buffer to the screen (no flicker!)
        g.drawImage (Buffer,0,0, this);
    }
}

If you would like to further explore the time and date functions of Java, take a look at the API documentation or the following little demo program. The last line (weekday) makes use of a switch statement. This is often used as a shorter replacement for many if/else statements. In the brackets you put the variable (must be of type integer, short or char) which is tested in the branches of the body. Since the function getDay() returns a number in the range 0 to 6, we have to somehow convert it into the name of the corresponding weekday, so the switch statement comes in handy.

//Sourcecode

import java.awt.*;
import java.applet.*;
//we need to import the util package for the time functions
import java.util.*;

public class Project21 extends Applet implements Runnable
{
    Thread runner;
    Image Buffer;
    Graphics gBuffer;

    public void init()
    {
        //create off-screen image we can draw to
        Buffer=createImage(size().width,size().height);
        gBuffer=Buffer.getGraphics();
    }

    public void start()
    {
        if (runner == null)
        {
            runner = new Thread (this);
            runner.start();
        }
    }

    public void stop()
    {
        if (runner != null)
        {
            runner.stop();
            runner = null;
        }
    }

    public void run()
    {
        while(true)
        {
            //halt the thread for 100 ms here
            try {runner.sleep(100);}
            catch (Exception e) { }

            repaint();
        }
    }

    public void update(Graphics g)
    {
        paint(g);
    }

    public void paint (Graphics g)
    {
        //create a new time object
        Date today=new Date();

        //repaint the background green
        gBuffer.setColor(Color.green);
        gBuffer.fillRect(0,0,size().width,size().height);

        //set a new font we create "on the fly"
        gBuffer.setFont(new Font("Helvetica", Font.PLAIN,16));
        gBuffer.setColor(Color.black);

        gBuffer.drawString("toGMTString(): "+today.toGMTString(),20,20);
        gBuffer.drawString("toLocaleString(): "+today.toLocaleString(),20,40);
        gBuffer.drawString("toString(): "+today.toString(),20,60);
        gBuffer.drawString("getYear(): "+today.getYear(),20,80);
        gBuffer.drawString("getMonth(): "+today.getMonth(),20,100);
        gBuffer.drawString("getDate(): "+today.getDate(),20,120);
        gBuffer.drawString("getHours(): "+today.getHours(),20,140);
        gBuffer.drawString("getMinutes(): "+today.getMinutes(),20,160);
        gBuffer.drawString("getSeconds(): "+today.getSeconds(),20,180);
        gBuffer.drawString("getDay(): "+today.getDay(),20,200);

        switch(today.getDay())
        {
            case 0: gBuffer.drawString("Today is Sunday",20,240);
                break;
            case 1: gBuffer.drawString("Today is Monday",20,240);
                break;
            case 2: gBuffer.drawString("Today is Tuesday",20,240);
                break;
            case 3: gBuffer.drawString("Today is Wednesday",20,240);
                break;
            case 4: gBuffer.drawString("Today is Thursday",20,240);
                break;
            case 5: gBuffer.drawString("Today is Friday",20,240);
                break;
            case 6: gBuffer.drawString("Today is Saturday",20,240);
                break;
        }

        //copy the buffer to the screen
        g.drawImage (Buffer,0,0, this);
    }
}

back 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 next

0 - setup - getting your tools ready
1 - basic graphics functions
2 - simple methods and basic data types
3 - IF, ELSE and SWITCH: basic control structures
4 - introducing the operators
5 - methods with and without a return value
6 - using methods and basic mouse functions
7 - fonts, random numbers and timers
8 - flicker free graphics, GIF and JPEG display
9 - animation with GIF pictures, sprite animation
10 - loops, advanced color functions
11 - random colors and arrays
12 - digital clocks, HTML page parameters
13 - introducing classes and objects
14 - using the Vector class
15 - using mouseMove and mouseDrag
16 - keyboard commands and playing sound
17 - detecting collisions and intersections
18 - a Bouncing Balls applet
19 - fun with letters and words
20 - rotating lines and polygons
21 - sorting and shuffling


© 2000 by Johannes Wallroth
www.programming.de

watson@programming.de