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"); } } }