Java by Example - digital clocks, HTML page parameters
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);
}
}
|
|