001//****************************************************************************** 002// BinaryClockApp.java: Applet 003// 004//****************************************************************************** 005package ca.bc.webarts.tools; 006 007import java.applet.*; 008import java.awt.*; 009import java.util.Calendar; 010//import BinaryClockAppFrame; 011 012//============================================================================== 013// Main Class for applet BinaryClockApp 014// 015//============================================================================== 016/** 017 * Description of the Class 018 * 019 * @author TGutwin 020 */ 021public class BinaryClockApp extends Applet implements Runnable 022{ 023 /** Description of the Field */ 024 public boolean showText = false; 025 /** Description of the Field */ 026 private boolean leftToRight = false; 027 /** The colour of an on bit. */ 028 private Color onColour = Color.BLUE.darker(); 029 /** The colour of an on bit. */ 030 private Color offColour = Color.cyan;//Color.BLUE.darker(); 031 /** Description of the Field */ 032 int x; 033 /** Description of the Field */ 034 int y; 035 /** Description of the Field */ 036 private Calendar now, newnow; 037 /** Description of the Field */ 038 private Image backBuffer; 039 /** Description of the Field */ 040 private Graphics bg; 041 /** Description of the Field */ 042 private Font font; 043 /** Description of the Field */ 044 private String decimalTime; 045 046 // THREAD SUPPORT: 047 // m_BinclockApp is the Thread object for the applet 048 //-------------------------------------------------------------------------- 049 /** Description of the Field */ 050 private Thread clockThread = null; 051 052 // STANDALONE APPLICATION SUPPORT: 053 // m_fStandAlone will be set to true if applet is run standalone 054 //-------------------------------------------------------------------------- 055 /** Description of the Field */ 056 private boolean m_fStandAlone = false; 057 058 // BinclockApp Class Constructor 059 //-------------------------------------------------------------------------- 060 /** Constructor for the BinaryClockApp object */ 061 public BinaryClockApp() { } 062 063 // STANDALONE APPLICATION SUPPORT 064 // The main() method acts as the applet's entry point when it is run 065 // as a standalone application. It is ignored if the applet is run from 066 // within an HTML page. 067 //-------------------------------------------------------------------------- 068 069 /** 070 * STANDALONE APPLICATION SUPPORT 071 * The main() meth; 072 int height= 10od acts as the applet's entry point when it is run 073 * as a standalone application. It is ignored if the applet is run from 074 * within an HTML page. 075 * 076 * @param args Description of the Parameter 077 */ 078 public static void main(String args[]) 079 { 080 // Create Toplevel Window to contain applet BinclockApp 081 //---------------------------------------------------------------------- 082 BinaryClockAppFrame frame = new BinaryClockAppFrame("Binary Clock"); 083 084 // The following code starts the applet running within the frame window. 085 // It also calls GetParameters() to retrieve parameter values from the 086 // command line, and sets m_fStandAlone to true to prevent init() from 087 // trying to get them from the HTML page. 088 //---------------------------------------------------------------------- 089 BinaryClockApp applet_BinclockApp = new BinaryClockApp(); 090 091 if (applet_BinclockApp.showText) 092 { 093 frame.setBounds(100, 100, 260, 180); 094 } 095 else 096 { 097 frame.setBounds(100, 100, 134, 90); 098 } 099 100 // Must show Frame before we size it so getInset() will return valid values 101 //---------------------------------------------------------------------- 102 frame.show(); 103 104 frame.add("Center", applet_BinclockApp); 105 applet_BinclockApp.m_fStandAlone = true; 106 107 applet_BinclockApp.init(); 108 applet_BinclockApp.start(); 109 frame.show(); 110 } 111 112 // APPLET INFO SUPPORT: 113 // The getAppletInfo() method returns a string describing the applet's 114 // author, copyright date, or miscellaneous information. 115 //-------------------------------------------------------------------------- 116 /** 117 * Gets the appletInfo attribute of the BinaryClockApp object 118 * 119 * @return The appletInfo value 120 */ 121 public String getAppletInfo() 122 { 123 return "Name: BinaryClock\r\n" + 124 "Author: David Binard (mailto:binard@california.com)\n" + 125 "Date: 08/20/98\n" + 126 "Description: Binary Clock Animation\n"; 127 } 128 129 130 // The init() method is called by the AWT when an applet is first loaded or 131 // reloaded. Override this method to perform whatever initialization your 132 // applet needs, such as initializing data structures, loading images or 133 // fonts, creating frame windows, setting the layout manager, or adding UI 134 // components. 135 //-------------------------------------------------------------------------- 136 /** Description of the Method */ 137 public void init() 138 { 139 // If you use a ResourceWizard-generated "control creator" class to 140 // arrange controls in your applet, you may want to call its 141 // CreateControls() method from within this method. Remove the following 142 // call to setSize() before adding the call to CreateControls(); 143 // CreateControls() does its own resizing. 144 //---------------------------------------------------------------------- 145 setSize(getSize().width, getSize().height); 146 font = new Font("Helvetica", Font.PLAIN, 11); 147 try 148 { 149 backBuffer = createImage(getSize().width, getSize().height); 150 bg = backBuffer.getGraphics(); 151 } 152 catch (Exception e) 153 { 154 bg = null; 155 } 156 ; 157 158 // TODO: Place additional initialization code here 159 } 160 161 // Place additional applet clean up code here. destroy() is called when 162 // when you applet is terminating and being unloaded. 163 //------------------------------------------------------------------------- 164 /** Description of the Method */ 165 public void destroy() 166 { 167 // TODO: Place applet cleanup code here 168 } 169 170 171 // The start() method is called when the page containing the applet 172 // first appears on the screen. The AppletWizard's initial implementation 173 // of this method starts execution of the applet's thread. 174 //-------------------------------------------------------------------------- 175 /** Description of the Method */ 176 public void start() 177 { 178 now = Calendar.getInstance(); 179 newnow = Calendar.getInstance(); 180 if (clockThread == null) 181 { 182 clockThread = new Thread(this, "Binclock"); 183 clockThread.start(); 184 } 185 // TODO: Place additional applet start code here 186 } 187 188 // The stop() method is called when the page containing the applet is 189 // no longer on the screen. The AppletWizard's initial implementation of 190 // this method stops execution of the applet's thread. 191 //-------------------------------------------------------------------------- 192 /** Description of the Method */ 193 public void stop() 194 { 195 if (clockThread != null) 196 { 197 clockThread.stop(); 198 clockThread = null; 199 } 200 201 // TODO: Place additional applet stop code here 202 } 203 204 // THREAD SUPPORT 205 // The run() method is called when the applet's thread is started. If 206 // your applet performs any ongoing activities without waiting for user 207 // input, the code for implementing that behavior typically goes here. For 208 // example, for an applet that performs animation, the run() method controls 209 // the display of images. 210 //-------------------------------------------------------------------------- 211 /** Main processing method for the BinaryClockApp object */ 212 public void run() 213 { 214 // loop terminates when clockThread is set to null in stop() 215 while (Thread.currentThread() == clockThread) 216 { 217 repaint(); 218 // loop until the time changes by one second 219 // the sleeps are here to reduce CPU usage 220 while (now.get(Calendar.SECOND) == newnow.get(Calendar.SECOND)) 221 { 222 try 223 { 224 clockThread.sleep(200); 225 } 226 catch (Exception e) 227 { 228 } 229 ; 230 newnow = Calendar.getInstance(); 231 } 232 } 233 } 234 235 236 /** 237 * Description of the Method 238 * 239 * @param g Description of the Parameter 240 */ 241 public void update(Graphics g) 242 { 243 if (bg == null) 244 {// no backgound buffer 245 repaintClock(g); 246 } 247 else 248 { 249 repaintClock(bg); 250 g.drawImage(backBuffer, 0, 0, this); 251 showStatus("Decimal time: " + decimalTime); 252 } 253 } 254 255 256 /** 257 * Description of the Method 258 * 259 * @param value Description of the Parameter 260 * @return Description of the Return Value 261 */ 262 public String calc_bits(int value) 263 { 264 int bit; 265 int filter = 32; 266 StringBuffer bitString = new StringBuffer("00"); 267 for (bit = 3; bit <= 8; bit++) 268 { 269 if (value >= filter) 270 { 271 bitString.append('1'); 272 value -= filter; 273 } 274 else 275 { 276 bitString.append('0'); 277 } 278 filter = filter - (filter / 2); 279 } 280 return bitString.toString(); 281 } 282 283 284 /** 285 * Description of the Method 286 * 287 * @param value Description of the Parameter 288 * @return Description of the Return Value 289 */ 290 public String lpad(int value) 291 { 292 String mystring = "00"; 293 if (value <= 9) 294 { 295 mystring = "0" + Integer.toString(value); 296 } 297 else 298 { 299 mystring = Integer.toString(value); 300 } 301 return mystring; 302 } 303 304 305 /** 306 * Description of the Method 307 * 308 * @param value Description of the Parameter 309 * @return Description of the Return Value 310 */ 311 public String to_octal(int value) 312 { 313 String octal = (value / 8) + "" + (value % 8); 314 return octal; 315 } 316 317 318 /** 319 * Description of the Method 320 * 321 * @param value Description of the Parameter 322 * @return Description of the Return Value 323 */ 324 public String to_alpha_hex(int value) 325 { 326 if (value < 10) 327 { 328 return Integer.toString(value); 329 } 330 else if (value == 10) 331 { 332 return "A"; 333 } 334 else if (value == 11) 335 { 336 return "B"; 337 } 338 else if (value == 12) 339 { 340 return "C"; 341 } 342 else if (value == 13) 343 { 344 return "D"; 345 } 346 else if (value == 14) 347 { 348 return "E"; 349 } 350 else if (value == 15) 351 { 352 return "F"; 353 } 354 else 355 { 356 return "0"; 357 } 358 } 359 360 361 /** 362 * Description of the Method 363 * 364 * @param value Description of the Parameter 365 * @return Description of the Return Value 366 */ 367 public String to_hex(int value) 368 { 369 String hex = to_alpha_hex(value / 16) + "" + to_alpha_hex(value % 16); 370 return hex; 371 } 372 373 // TODO: Place additional applet code here 374 375 /** 376 * Description of the Method 377 * 378 * @param g Description of the Parameter 379 */ 380 private void repaintClock(Graphics g) 381 { 382 now = Calendar.getInstance(); 383 int hours = now.get(Calendar.HOUR_OF_DAY); 384 int mins = now.get(Calendar.MINUTE); 385 int secs = now.get(Calendar.SECOND); 386 decimalTime = lpad(hours) + ":" + lpad(mins) + ":" + lpad(secs); 387 String hourBits = calc_bits(hours); 388 String minBits = calc_bits(mins); 389 String secBits = calc_bits(secs); 390 // Clear Background 391 g.setColor(Color.LIGHT_GRAY); 392 g.fillRect(0, 0, getSize().width, getSize().height); 393 394 if (showText) 395 { 396 // Draw text Clock 397 g.setFont(font); 398 g.setColor(Color.black); 399 x = 0; 400 y = 80; 401 g.drawString("Hours", x + 80, y); 402 g.drawString("Minutes", x + 135, y); 403 g.drawString("Seconds", x + 192, y); 404 y += 15; 405 g.drawString("Decimal time", x, y); 406 y += 15; 407 g.drawString("Octal time", x, y); 408 y += 15; 409 g.drawString("Hex time", x, y); 410 y += 15; 411 g.drawString("Binary time", x, y); 412 g.setColor(Color.blue); 413 y -= 45; 414 g.drawString(lpad(hours), x + 88, y); 415 g.drawString(lpad(mins), x + 148, y); 416 g.drawString(lpad(secs), x + 208, y); 417 y += 15; 418 g.drawString(to_octal(hours), x + 88, y); 419 g.drawString(to_octal(mins), x + 148, y); 420 g.drawString(to_octal(secs), x + 208, y); 421 y += 15; 422 g.drawString(to_hex(hours), x + 88, y); 423 g.drawString(to_hex(mins), x + 148, y); 424 g.drawString(to_hex(secs), x + 208, y); 425 y += 15; 426 g.drawString(hourBits, x + 70, y); 427 g.drawString(minBits, x + 130, y); 428 g.drawString(secBits, x + 190, y); 429 } 430 431 int spacing = 5; 432 int width= 10; 433 int height= 15; 434 if (leftToRight) 435 { 436 x = spacing; 437 y = spacing; 438 drawBits(hourBits, g, x, y); 439 y += height + spacing; 440 drawBits(minBits, g, x, y); 441 y += height + spacing; 442 drawBits(secBits, g, x, y); 443 //y += 20; 444 } 445 else 446 { 447 x = spacing; 448 y = spacing; 449 drawBits(hourBits, g, x, y, 10, 15, spacing, true ); 450 x += width + spacing; 451 drawBits(minBits, g, x, y, 10, 15, spacing, true); 452 x += width + spacing; 453 drawBits(secBits, g, x, y, 10, 15, spacing, true); 454 } 455 } 456 457 458 /** 459 * Draws rectangles 10 wide and 15 high representing the bit pattern passed in 460 * 461 * @param bits the bit pattern to draw 462 * @param g Description of the Parameter 463 * @param x the start x position 464 * @param y the start y position 465 */ 466 private void drawBits(String bits, Graphics g, int x, int y) 467 { 468 drawBits(bits, g, x, y, 10, 15, 5, false); 469 } 470 471 472 /** 473 * Draws rectangles representing the bit pattern passed in 474 * 475 * @param bits the bit pattern to draw 476 * @param g Description of the Parameter 477 * @param x the start x position 478 * @param y the start y position 479 * @param dx delta x 480 * @param dy delta y 481 * @param spacing the distance between the blocks 482 */ 483 private void drawBits(String bits, Graphics g, int x, int y, int dx, int dy, int spacing, boolean vertical) 484 { 485 for (int i = 0; i < 8; i++) 486 { 487 if (bits.charAt(i) == '0') 488 { 489 g.setColor(offColour); 490 } 491 else 492 { 493 g.setColor(onColour); 494 } 495 g.fillRect(x, y, dx, dy); 496 if (vertical) 497 y += dy + spacing; 498 else 499 x += dx + spacing; 500 } 501 } 502} 503