package AlarmIt;
/**
* This type was created in VisualAge.
*/
import java.awt.*;
import java.util.*;
import java.applet.Applet;
/*
* Whenever changes are made to the UserPanel Class via
* the visual composition editor, the "initialization()"
* method must be changed to reflect the new applet size:
* setSize(325, 140);
* Cooresponding change must be made in this class in the
* "init()" method. Same values.
*
* Also, in UserPanel class definition, change all privates
* to public.
*/
/*
* Method 'boolean action' will launch and listen immediately.
* By default, 'init' is the first method run by an applet.
* After initialized, 'start' will be executed.
* In this class, the only purpose of
*/
public class AlarmIt extends java.applet.Applet implements Runnable{
//class variables
int timerPanel = 1;
int[] timerMode = new int[6];
long[] targetTime = new long[6];
String[] description$ = new String[6];
String[] keyedTime$ = new String[6];
//timed thread
Thread watchAlarms;
//other class types
UserPanel Panel;
PopUpError Frame;
/**
* Alarm constructor comment.
*/
public AlarmIt() {
super();
}
/**
* This method was created in VisualAge.
* @return boolean
*/
/**
* All user initiated events are caught by this routine.
* 'boolean action' is deprecated, but since it has not yet
* been removed, I have chosen to use it in this program.
* I have not yet studied the perferred method of capturing
* user initiated events.
*/
public boolean action(Event e, Object o) {
//the start button changes states during operation
//if clicked, the button must be interrogated to
//determine its current state
if(e.target.equals(Panel.ivjButtonStart)){
if (Panel.ivjButtonStart.getLabel()=="Start"){
//this is the original state
//timer is not active
doButtonStart();
}else{
//this is the altered state
//timer is active, user wants it stopped
doButtonAbort();
}
}
//call 'doMethods' based on each event
if(e.target.equals(Panel.ivjCheckboxTime)){doCheckboxTime();}
if(e.target.equals(Panel.ivjCheckboxCount)){doCheckboxCount();}
if(e.target.equals(Panel.ivjButton1)){doButton1();}
if(e.target.equals(Panel.ivjButton2)){doButton2();}
if(e.target.equals(Panel.ivjButton3)){doButton3();}
if(e.target.equals(Panel.ivjButton4)){doButton4();}
if(e.target.equals(Panel.ivjButton5)){doButton5();}
return false;
}
/**
* This method was created in VisualAge.
*/
/**
* All 'doMethods' for the buttons are the same except for
* the called button. This could probably be done more
* effeciently by creating a handeler class and assigning
* it to five elements of an object array, but this was
* easier for me, as a beginner. The other four methods (2-5)
* are not fully documented.
*/
public void doButton1() {
String a$ = null;
//call method to determine current settings
getPanelSettings();
//user clicked a button, so set panel marker
timerPanel = 1;
//Each timer label has four states. Each label has a
//different text message and background color.
//read the label below this button.
/*States:
Idle white (clear) Running green
Expired red Reset yellow
*/
a$ = Panel.ivjLabel1.getText();
//the alarm has sounded
if (a$=="Expired"){
//correct variable that should have been carried
//over from thread
timerMode[timerPanel] = -1;
//force user to view and reset panel
Panel.ivjLabel1.setText("Reset");
//change background color
Panel.ivjLabel1.setBackground(Color.yellow);
}
//the alarm has been acknowledged
if (a$=="Reset"){
//set mode to idle and clear variables
timerMode[timerPanel] = 0;
//reset text fields
keyedTime$[timerPanel] = null;
description$[timerPanel] = null;
//make panel writable
Panel.ivjTextField1.setEditable(true);
Panel.ivjTextField2.setEditable(true);
Panel.ivjCheckboxCount.setEnabled(true);
Panel.ivjCheckboxTime.setEnabled(true);
//clear checkboxes for next input
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(false);
//indicate idle state
Panel.ivjLabel1.setText("Idle");
Panel.ivjLabel1.setBackground(Color.white);
}
//call method to reflect panel change
switchPanels();
}
/**
* This method was created in VisualAge.
*/
public void doButton2() {
String a$;
//determine current settings
getPanelSettings();
//user clicked a button, so set panel marker
timerPanel = 2;
//read the label below this button
a$ = Panel.ivjLabel2.getText();
if (a$=="Expired"){
//correct variable that should have been carried
//over from thread
timerMode[timerPanel] = -1;
//force user to view and reset panel
Panel.ivjLabel2.setText("Reset");
Panel.ivjLabel2.setBackground(Color.yellow);
}
if (a$=="Reset"){
//set mode to idle and clear variables
timerMode[timerPanel] = 0;
keyedTime$[timerPanel] = null;
description$[timerPanel] = null;
//make panel writable
Panel.ivjTextField1.setEditable(true);
Panel.ivjTextField2.setEditable(true);
Panel.ivjCheckboxCount.setEnabled(true);
Panel.ivjCheckboxTime.setEnabled(true);
//clear checkboxes for next input
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(false);
//indicate idle state
Panel.ivjLabel2.setText("Idle");
Panel.ivjLabel2.setBackground(Color.white);
}
//adjust checkbox objects to reflect panel change
switchPanels();
}
/**
* This method was created in VisualAge.
*/
public void doButton3() {
String a$;
//determine current settings
getPanelSettings();
//user clicked a button, so set panel marker
timerPanel = 3;
//read the label below this button
a$ = Panel.ivjLabel3.getText();
if (a$=="Expired"){
//correct variable that should have been carried
//over from thread
timerMode[timerPanel] = -1;
//force user to view and reset panel
Panel.ivjLabel3.setText("Reset");
Panel.ivjLabel3.setBackground(Color.yellow);
}
if (a$=="Reset"){
//set mode to idle and clear variables
timerMode[timerPanel] = 0;
keyedTime$[timerPanel] = null;
description$[timerPanel] = null;
//make panel writable
Panel.ivjTextField1.setEditable(true);
Panel.ivjTextField2.setEditable(true);
Panel.ivjCheckboxCount.setEnabled(true);
Panel.ivjCheckboxTime.setEnabled(true);
//clear checkboxes for next input
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(false);
//indicate idle state
Panel.ivjLabel3.setText("Idle");
Panel.ivjLabel3.setBackground(Color.white);
}
//adjust checkbox objects to reflect panel change
switchPanels();
}
/**
* This method was created in VisualAge.
*/
public void doButton4() {
String a$;
//determine current settings
getPanelSettings();
//user clicked a button, so set panel marker
timerPanel = 4;
//read the label below this button
a$ = Panel.ivjLabel4.getText();
if (a$=="Expired"){
//correct variable that should have been carried
//over from thread
timerMode[timerPanel] = -1;
//force user to view and reset panel
Panel.ivjLabel4.setText("Reset");
Panel.ivjLabel4.setBackground(Color.yellow);
}
if (a$=="Reset"){
//set mode to idle and clear variables
timerMode[timerPanel] = 0;
keyedTime$[timerPanel] = null;
description$[timerPanel] = null;
//make panel writable
Panel.ivjTextField1.setEditable(true);
Panel.ivjTextField2.setEditable(true);
Panel.ivjCheckboxCount.setEnabled(true);
Panel.ivjCheckboxTime.setEnabled(true);
//clear checkboxes for next input
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(false);
//indicate idle state
Panel.ivjLabel4.setText("Idle");
Panel.ivjLabel4.setBackground(Color.white);
}
//adjust checkbox objects to reflect panel change
switchPanels();
}
/**
* This method was created in VisualAge.
*/
public void doButton5() {
String a$;
//determine current settings
getPanelSettings();
//user clicked a button, so set panel marker
timerPanel = 5;
//read the label below this button
a$ = Panel.ivjLabel5.getText();
if (a$=="Expired"){
//correct variable that should have been carried
//over from thread
timerMode[timerPanel] = -1;
//force user to view and reset panel
Panel.ivjLabel5.setText("Reset");
Panel.ivjLabel5.setBackground(Color.yellow);
}
if (a$=="Reset"){
//set mode to idle and clear variables
timerMode[timerPanel] = 0;
keyedTime$[timerPanel] = null;
description$[timerPanel] = null;
//make panel writable
Panel.ivjTextField1.setEditable(true);
Panel.ivjTextField2.setEditable(true);
Panel.ivjCheckboxCount.setEnabled(true);
Panel.ivjCheckboxTime.setEnabled(true);
//clear checkboxes for next input
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(false);
//indicate idle state
Panel.ivjLabel5.setText("Idle");
Panel.ivjLabel5.setBackground(Color.white);
}
//adjust checkbox objects to reflect panel change
switchPanels();
}
/**
* This method was created in VisualAge.
*/
/**
* This method resets all variables to initialized states
* prior to alarm expiration.
*/
public void doButtonAbort() {
//reset all variables
description$[timerPanel] = null;
keyedTime$[timerPanel] = null;
timerMode[timerPanel] = 0;
targetTime[timerPanel] = 0;
//since program was not designed to assign each panel to
//a unique object (shame on me), each possibility must
//be addressed individually
if (timerPanel==1) {
//clear labels text message
Panel.ivjLabel1.setText("Idle");
//clear background color
Panel.ivjLabel1.setBackground(Color.white);
}
if (timerPanel==2) {
Panel.ivjLabel2.setText("Idle");
Panel.ivjLabel2.setBackground(Color.white);
}
if (timerPanel==3) {
Panel.ivjLabel3.setText("Idle");
Panel.ivjLabel3.setBackground(Color.white);
}
if (timerPanel==4) {
Panel.ivjLabel4.setText("Idle");
Panel.ivjLabel4.setBackground(Color.white);
}
if (timerPanel==5) {
Panel.ivjLabel5.setText("Idle");
Panel.ivjLabel5.setBackground(Color.white);
}
//call method to update changes
switchPanels();
}
/**
* This method was created in VisualAge.
*/
/**
* The start button actually controls the alarms. All other
* buttons are for initializing or clear alarms. The states
* of these other objects must be checked and cleared before
* the alarm can start.
*/
public void doButtonStart() {
int th = 0,tm = 0,ts = 0;
boolean c1 = true, c2 = true;
String a$ = null;
char[] c;
//It is assumed that all objects are in an acceptable state
//until proven otherwise. All state checking will attempt
//to prove an improper condition.
boolean good = true;
//read the text from the time field
a$ = Panel.ivjTextField1.getText();
//time too short or too long
if (a$.length()!=8){
good = false;
}else{
//ensure there are only numbers in the time
c = a$.toCharArray();
if (!Character.isDigit(c[0])) {good = false;}
if (!Character.isDigit(c[1])) {good = false;}
if (!Character.isDigit(c[3])) {good = false;}
if (!Character.isDigit(c[4])) {good = false;}
if (!Character.isDigit(c[6])) {good = false;}
if (!Character.isDigit(c[7])) {good = false;}
//ensure separators are symbols
if (Character.isLetterOrDigit(c[2])) {good = false;}
if (Character.isLetterOrDigit(c[5])) {good = false;}
}
//read values of numbers
if (good){
th = Integer.parseInt(String.valueOf(a$.substring(0,2)));
tm = Integer.parseInt(String.valueOf(a$.substring(3,5)));
ts = Integer.parseInt(String.valueOf(a$.substring(6,8)));
}
//System.out.println(th+" "+c1+" "+tm+" "+c2+" "+ts);
//check to ensure number values are within limits
if (th>23 | tm>59 | ts>59 | good==false){
//either a number was out of range from this check,
//or it had failed due to a previous check, above.
good = false;
//play a sound
play(getCodeBase(),"AlarmIt/ding.au");
//show error frame defined in class created with
//ivj visual class composer
Frame = new PopUpError();
Frame.setSize(200,120);
//reassign label texts to show what caused the error
Frame.ivjLabel1.setText("Time Format Incorrect:");
Frame.ivjLabel2.setText("hh:mm:ss");
Frame.show();
}
//ensure one of the two radio buttons has been selected
//notice 'good' in this conditional: if had already
//failed due to problems above, do not show again.
if (timerMode[timerPanel] == 0 & good){
//radio buttons not clicked
good = false;
//play a sound
play(getCodeBase(),"AlarmIt/ding.au");
//show error frame as above
Frame = new PopUpError();
Frame.setSize(200,120);
//notice different text labels
Frame.ivjLabel1.setText("Must Select Mode:");
Frame.ivjLabel2.setText("Time or Count");
Frame.show();
}
//since good is still true after all checks,
//call method to execute timer
if (good) {goodStart();}
}
/**
* This method was created in VisualAge.
*/
public void doCheckboxCount() {
//initiate count mode for this panel
//set time checkbox object to false
Panel.ivjCheckboxTime.setState(false);
//set timerMode to "2" for countdown
timerMode[timerPanel] = 2;
}
/**
* This method was created in VisualAge.
*/
public void doCheckboxTime() {
//initiate alarm mode for this panel
//set time checkbox object to false
Panel.ivjCheckboxCount.setState(false);
//set timerMode to "1" for alarm timer
timerMode[timerPanel] = 1;
}
/**
* This method was created in VisualAge.
*/
public void getPanelSettings() {
//reset the mode variable so that it is forced to match
//the object state
timerMode[timerPanel] = 0;
//determine whether set for time or coundown
if (Panel.ivjCheckboxTime.getState()) {
timerMode[timerPanel] = 1;
}
if (Panel.ivjCheckboxCount.getState()) {
timerMode[timerPanel] = 2;
}
//read and store information from text fields
keyedTime$[timerPanel] = Panel.ivjTextField1.getText();
description$[timerPanel] = Panel.ivjTextField2.getText();
/*
System.out.println( Panel.ivjCheckboxTime.getState() + " " +
Panel.ivjCheckboxCount.getState());
System.out.println( timerPanel + " " +
timerMode[timerPanel] + " " +
description$[timerPanel]);
*/
}
/**
* This method was created in VisualAge.
*/
public void goodStart() {
int d = 0,h = 0,m = 0,s = 0;
int ch = 0,cm = 0,cs = 0;
int th = 0,tm = 0,ts = 0;
long millis = 0, target = 0, work = 0;
boolean c1, c2, bad = false;
String a$ = null, time$ = null;
//get time that was keyed in
a$ = Panel.ivjTextField1.getText();
keyedTime$[timerPanel] = a$;
//System.out.println("You keyed:"+a$);
//get numbers that user keyed as target
th = Integer.parseInt(String.valueOf(a$.substring(0,2)));
tm = Integer.parseInt(String.valueOf(a$.substring(3,5)));
ts = Integer.parseInt(String.valueOf(a$.substring(6,8)));
//System.out.println("Breakdown:"+th+" "+tm+" "+ts);
//load the current text into the description array
description$[timerPanel] = Panel.ivjTextField2.getText();
//get current time, standard methods
//time and date methods are notoriously deprectated
Date currentDate = new Date();
millis = currentDate.getTime();
time$ = currentDate.toString();
//System.out.println("Current date:"+currentDate);
//System.out.println("Milliseconds:"+millis);
//pull the time from the data field
time$ = time$.substring(11,19);
//get hours, minutes, seconds
//there are methods that will do this, but we're not
//suppose to use them
ch = Integer.parseInt(String.valueOf(time$.substring(0,2)));
cm = Integer.parseInt(String.valueOf(time$.substring(3,5)));
cs = Integer.parseInt(String.valueOf(time$.substring(6,8)));
//System.out.println("Breakdown:"+ch+" "+cm+" "+cs);
//which mode are the radio buttons set
/*
* Following lines supplied by code elves
*/
if (timerMode[timerPanel] == 1){
target = (th * 3600) + (tm * 60) + ts;
work = (ch * 3600) + (cm * 60) + cs;
if (target23) {h = h - 24; d = 1;}
m = tm; if (m>59) {m = m - 60; h = h + 1;}
s = ts; if (s>59) {s = s - 60; m = m + 1;}
target = (d * 86400) + (h * 3600) + (m * 60) + s;
targetTime[timerPanel] = (target * 1000) + millis;
h = th + ch; if (h>23) {h = h - 24; d = 1;}
m = tm + cm; if (m>59) {m = m - 60; h = h + 1;}
s = ts + cs; if (s>59) {s = s - 60; m = m + 1;}
}
/*
* End code elves lines
*/
//Hours, minutes, and seconds must be reconstructed into
//a string. This process must include adding zeros for
//elements less than ten. For as common a routine as time
//validation is, you'd think Sun would have included them
//in the API.
if (h<10) {time$ = "0";}else{time$="";};
time$ = time$ + String.valueOf(h) + ":";
if (m<10) {time$ = time$ + "0";}
time$ = time$ + String.valueOf(m) + ":";
if (s<10) {time$ = time$ + "0";}
time$ = time$ + String.valueOf(s) + " = ";
//show alarm expiration time in the desription field
description$[timerPanel] = time$ + description$[timerPanel];
//System.out.println(description$[timerPanel]);
//Here again, each label must be updated. Once I figure
//out how to cast objects as arrays, I won't need all these
//redundant lines of code.
if (timerPanel==1) {
Panel.ivjLabel1.setText("Running");
Panel.ivjLabel1.setBackground(Color.green);
}
if (timerPanel==2) {
Panel.ivjLabel2.setText("Running");
Panel.ivjLabel2.setBackground(Color.green);
}
if (timerPanel==3) {
Panel.ivjLabel3.setText("Running");
Panel.ivjLabel3.setBackground(Color.green);
}
if (timerPanel==4) {
Panel.ivjLabel4.setText("Running");
Panel.ivjLabel4.setBackground(Color.green);
}
if (timerPanel==5) {
Panel.ivjLabel5.setText("Running");
Panel.ivjLabel5.setBackground(Color.green);
}
//update panel with new information
switchPanels();
}
/**
* This method was created in VisualAge.
*/
public void init() {
setName("AlarmIt");
Panel = new UserPanel();
Panel.setSize(325,140);
Panel.setLayout(null);
add(Panel);
//main();
}
/**
* This method was created in VisualAge.
*/
/*
* This method does the work that is initiated by the start
* button, as captured by 'boolean action'. This is a second
* thread that is always running behind the 'boolean action'.
*/
public void run() {
long millis;
String time$;
//run thread forever
while (true){
//get current time
Date currentDate = new Date();
millis = currentDate.getTime();
time$ = currentDate.toString();
time$ = time$.substring(11,19);
//display current time as label 7 on the panel
Panel.ivjLabel7.setText(time$);
//cycle through panels, checking the state of each timer
for (int i = 1; i < 6; i++) {
//if targetTime is zero, no action is needed
if (targetTime[i]>0) {
/*
System.out.println(
"Timer"+i+": c="+millis+" t="+targetTime[i]);
*/
//this timer is active, is it expired
if (millis>=targetTime[i]) {
//expired, play alarm sound
play(getCodeBase(), "AlarmIt/return.au");
//clear the timer, or it will stack hundreds
//of sound threads per second
targetTime[i] = 0;
//set for cleanup
timerMode[i] = -1;
//System.out.println("From run: "+timerMode[1]);
//check all these things again, what a bore...
if (i==1) {
Panel.ivjLabel1.setText("Expired");
Panel.ivjLabel1.setBackground(Color.red);
}
if (i==2) {
Panel.ivjLabel2.setText("Expired");
Panel.ivjLabel2.setBackground(Color.red);
}
if (i==3) {
Panel.ivjLabel3.setText("Expired");
Panel.ivjLabel3.setBackground(Color.red);
}
if (i==4) {
Panel.ivjLabel4.setText("Expired");
Panel.ivjLabel4.setBackground(Color.red);
}
if (i==5) {
Panel.ivjLabel5.setText("Expired");
Panel.ivjLabel5.setBackground(Color.red);
}
}
}
}
//throttle down to keep from taking all systems MIPs
try{Thread.sleep(1000);} catch(InterruptedException e){}
}
}
/**
* This method was created in VisualAge.
*/
public void start() {
//cookie cutter text to execute default 'run' thread
if (watchAlarms == null);{
watchAlarms = new Thread(this);
watchAlarms.start();
}
}
/**
* This method was created in VisualAge.
*/
public void switchPanels() {
//unlock text fields for panel transition
Panel.ivjTextField1.setEditable(true);
Panel.ivjTextField2.setEditable(true);
//unlock radio buttons for panel transition
Panel.ivjCheckboxCount.setEnabled(true);
Panel.ivjCheckboxTime.setEnabled(true);
//adjust checkbox objects to reflect panel change
switch(timerMode[timerPanel]){
case (0):
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(false);
break;
case (1):
Panel.ivjCheckboxTime.setState(true);
Panel.ivjCheckboxCount.setState(false);
break;
case (2):
Panel.ivjCheckboxTime.setState(false);
Panel.ivjCheckboxCount.setState(true);
break;
}
//set fields to data stored in arrays
Panel.ivjTextField1.setText(keyedTime$[timerPanel]);
Panel.ivjTextField2.setText(description$[timerPanel]);
//lock text fields depending on mode
if (timerMode[timerPanel]!=0 & targetTime[timerPanel]>0){
//change from start to abort
Panel.ivjButtonStart.setLabel("Abort");
//alarm or countdown active
Panel.ivjTextField1.setEditable(false);
Panel.ivjTextField2.setEditable(false);
Panel.ivjCheckboxCount.setEnabled(false);
Panel.ivjCheckboxTime.setEnabled(false);
}else{
Panel.ivjButtonStart.setLabel("Start");
}
}
}