Public Member Functions | |
void | debugMsg (String msg) |
void | quit () |
void | actionPerformed (ActionEvent e) |
void | paintComponent (Graphics g) |
URL | getURL (String msg, String pattern) |
Static Public Member Functions | |
int | getUInt (String msg, String pattern) |
Package Functions | |
JWPPanelSS (JFrame f, String slide, String debug, String ctl, String base, String fetch, boolean app) | |
Package Attributes | |
JFrame | frame |
boolean | isApplet |
Timer | timer |
Toolkit | tk |
String | baseURL |
URL | orig_ctlURL |
URL | orig_slideURL |
URL | urlCtl |
URL | urlSlide |
int | fetchTime |
boolean | debugMode |
URLConnection | c |
int | countSlide = 0 |
int | countCtl = 0 |
boolean | advancedMode |
Image | img |
MediaTracker | tracker = new MediaTracker(this) |
boolean | fastMode = false |
BufferedReader | in |
String | str |
int | jwpVersion |
long | lastSeq = -1 |
int | seq |
JPopupMenu | menu = new JPopupMenu("Popup Menu") |
JCheckBoxMenuItem | decorateItem |
JCheckBoxMenuItem | fillItem = new JCheckBoxMenuItem("Fill Image to Window") |
boolean | bResizeToFill = false |
boolean | bDecorate |
JDialog | infoDialog |
JLabel | infoLabel |
JButton | moreButton |
This is the main part of this program. A Timer task is performed repeatedly to get control parameters from ctlURL, and new slide is feteched if needed.
Definition at line 243 of file JWebPresenterSS.java.
|
Constructor: initializations.
Definition at line 432 of file JWebPresenterSS.java. References baseURL, frame, isApplet, quit(), and tk. 00432 { 00433 frame = f; 00434 baseURL = (base==null)?"":base; // non-null for simplicity. 00435 isApplet = app; 00436 tk = Toolkit.getDefaultToolkit(); 00437 00438 // Add a hide/exit method: ESC key. This seems not work, why?!! 00439 addKeyListener(new KeyAdapter() { 00440 public void keyPressed(KeyEvent e) { 00441 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 00442 quit(); 00443 } 00444 } 00445 }); 00446 00447 // Mouse triple (not double to avoid mistake) clicks can also quit. 00448 addMouseListener(new MouseAdapter() { 00449 public void mouseClicked(MouseEvent e) { 00450 // 2004-04-21, changed to > 2 to reduce miss operation. 00451 if (e.getClickCount() > 2) { 00452 quit(); 00453 } 00454 } 00455 // Catch the next mouse events to show the popup menu. 00456 public void mouseReleased(MouseEvent e) { 00457 if (e.isPopupTrigger()) { 00458 menu.show(e.getComponent(), e.getX(), e.getY()); 00459 } 00460 } 00461 00462 public void mousePressed(MouseEvent e) { 00463 if (e.isPopupTrigger()) { 00464 menu.show(e.getComponent(), e.getX(), e.getY()); 00465 } 00466 } 00467 }); 00468 00469 // First, let us get the debugMode. Set false (i.e. no debug) for error. 00470 try { 00471 debugMode = (Integer.parseInt(debug) != 0); 00472 } 00473 catch (NumberFormatException e) { 00474 debugMode = false; 00475 } 00476 00477 // Get the control URL if it is valid, otherwise null. 00478 try { 00479 urlCtl = new URL(ctl); 00480 orig_ctlURL = urlCtl; // save a copy (!) to orig_ctlURL 00481 } 00482 catch (MalformedURLException e) { 00483 debugMsg("Bad or no ctlURL (" + ctl + "). Set to NONE."); 00484 orig_ctlURL = null; 00485 urlCtl = null; 00486 } 00487 00488 // Get the target URL if it is valid, otherwise null. 00489 try { 00490 urlSlide = new URL(slide); 00491 orig_slideURL = urlSlide; // save a copy. 00492 } 00493 catch (MalformedURLException e) { 00494 debugMsg("Bad or no slideURL (" + slide + "). Set to NONE."); 00495 orig_slideURL = null; 00496 urlSlide = null; 00497 } 00498 00499 // We can do nothing (thus quit) if both urlCtl and urlSlide are both null. 00500 if ((urlCtl == null) && (urlSlide == null)) { 00501 debugMsg("Oops, what can I do for null ctlURL and null slideURL?"); 00502 JButton btnQuit = new JButton("(Invalid input) Check ctlURL and slideURL! (Click to quit)"); 00503 btnQuit.addActionListener(new ActionListener() { 00504 public void actionPerformed(ActionEvent e) { 00505 quit(); 00506 } 00507 }); 00508 add(btnQuit); 00509 return; // Skip other initializations. 00510 } 00511 00512 // Get the fetchTime, set to 5s (default) for exception. 00513 try { 00514 fetchTime = Integer.parseInt(fetch) * 100; 00515 } 00516 catch (NumberFormatException e) { 00517 debugMsg("Bad or no fetchTime. Set to 5s."); 00518 fetchTime = 5000; 00519 } 00520 00521 try { 00522 debugMsg("Java version = " + System.getProperty("java.version")); 00523 } 00524 catch (SecurityException e) {} 00525 00526 debugMsg("--- Parsed parameters are as follows ---\n" + 00527 " slideURL = " + urlSlide + "\n" + 00528 " debugMode = " + debugMode + "\n" + 00529 " ctlURL = " + urlCtl + "\n" + 00530 " baseURL = " + baseURL + "\n" + 00531 " fetchTime = " + fetchTime + "ms\n" + 00532 " Parameters accepted :-)."); 00533 00534 // Add popup menu items. 00535 // Full screen menu if frame is not null 00536 if (frame != null) { 00537 menu.add(new AbstractAction("Full Screen") { 00538 public void actionPerformed(ActionEvent e) { 00539 Dimension screen = tk.getScreenSize(); 00540 bDecorate = false; // disable window docoration 00541 decorateItem.setSelected(false); 00542 bResizeToFill = false; // disable the fill option 00543 fillItem.setSelected(false); 00544 frame.dispose(); // we need this to change decoration style 00545 frame.setUndecorated(true); 00546 frame.setLocation(0, 0); 00547 frame.setSize(screen.width, screen.height); 00548 setSize(screen.width, screen.height); 00549 frame.setVisible(true); 00550 repaint(); 00551 } 00552 }); 00553 } 00554 00555 /* 2004-06-18: add a reset function which reset urlSlide and 00556 * urlCtl to orig_slideURL and orig_ctlURL. This may be helpful 00557 * in trouble, and one does not want to restart the Java VM. 00558 */ 00559 menu.add(new AbstractAction("Reset (= restore URLs to initial values)") { 00560 public void actionPerformed(ActionEvent e) { 00561 urlCtl = orig_ctlURL; 00562 urlSlide = orig_slideURL; 00563 timer.setDelay(fetchTime); // restart the timer. 00564 timer.setInitialDelay(0); 00565 timer.restart(); 00566 debugMsg("URLs resetted. Starting new fetching..."); 00567 } 00568 }); 00569 00570 /* 2004-05-21: Zoom in/out seems not useful for presentations. 00571 * Besides, they require more complicate coding, e.g., mouse handling. 00572 * Therefore I removed the not-finished zoom function. 00573 */ 00574 menu.addSeparator(); 00575 00576 // decorate/undecoreate window item 00577 if (frame != null) { 00578 decorateItem = new JCheckBoxMenuItem("Decorate Window (then resize, move, etc)"); 00579 bDecorate = !frame.isUndecorated(); 00580 decorateItem.setSelected(bDecorate); 00581 decorateItem.addActionListener(new ActionListener() { 00582 public void actionPerformed(ActionEvent e) { 00583 bDecorate = !bDecorate; 00584 frame.dispose(); 00585 frame.setUndecorated(!bDecorate); 00586 decorateItem.setSelected(bDecorate); 00587 frame.setVisible(true); 00588 repaint(); 00589 } 00590 }); 00591 menu.add(decorateItem); 00592 } 00593 00594 fillItem.setSelected(bResizeToFill); 00595 fillItem.addActionListener(new ActionListener() { 00596 public void actionPerformed(ActionEvent e) { 00597 bResizeToFill = !bResizeToFill; 00598 repaint(); 00599 } 00600 }); 00601 menu.add(fillItem); 00602 00603 JCheckBoxMenuItem fastItem = new JCheckBoxMenuItem("Fast Mode (= skip intermediate slides)"); 00604 fastItem.setSelected(fastMode); 00605 fastItem.addActionListener(new ActionListener() { 00606 public void actionPerformed(ActionEvent e) { 00607 fastMode = !fastMode; 00608 } 00609 }); 00610 menu.add(fastItem); 00611 00612 JCheckBoxMenuItem debugItem = new JCheckBoxMenuItem("Debug to Java Console"); 00613 debugItem.setSelected(debugMode); 00614 debugItem.addActionListener(new ActionListener() { 00615 public void actionPerformed(ActionEvent e) { 00616 debugMode = !debugMode; 00617 } 00618 }); 00619 menu.add(debugItem); 00620 00621 menu.addSeparator(); 00622 00623 menu.add(new AbstractAction("Information...") { 00624 public void actionPerformed(ActionEvent e) { 00625 if (infoDialog != null) infoDialog.setVisible(true); 00626 } 00627 }); 00628 00629 // quit menu is only available if frame is not null. 00630 if (frame != null) { 00631 menu.add(new AbstractAction("Quit") { 00632 public void actionPerformed(ActionEvent e) { 00633 quit(); 00634 } 00635 }); 00636 } 00637 00638 add(menu); 00639 00640 // create the information dialog. 00641 infoDialog = new JDialog(frame, "Information", true); 00642 Container con = infoDialog.getContentPane(); 00643 infoLabel = new JLabel("<HTML><BR><CENTER><B>"+JWebPresenterSS.ver 00644 +"</B></CENTER><BR></HTML>", SwingConstants.CENTER); 00645 con.add(infoLabel); 00646 JPanel pOK = new JPanel(); 00647 JButton ok = new JButton("OK"); 00648 ok.addActionListener(new ActionListener() { 00649 public void actionPerformed(ActionEvent e) { 00650 infoDialog.setVisible(false); 00651 infoLabel.setText("<HTML><BR><CENTER><B>"+JWebPresenterSS.ver 00652 +"</B></CENTER><BR></HTML>"); 00653 moreButton.setText("More..."); 00654 infoDialog.pack(); 00655 } 00656 }); 00657 pOK.add(ok); 00658 00659 moreButton = new JButton("More..."); 00660 moreButton.addActionListener(new ActionListener() { 00661 public void actionPerformed(ActionEvent e) { 00662 String command = e.getActionCommand(); 00663 00664 if (command.equals("More...")) { 00665 infoLabel.setText("<HTML><BR><CENTER><B>"+JWebPresenterSS.ver 00666 +"</B></CENTER><BR>" 00667 +"Base URL = "+baseURL+"<BR>" 00668 +"Slide URL = "+((urlSlide==null)?"N/A":urlSlide.toString())+"<BR>" 00669 +"Control URL = "+((urlCtl==null)?"N/A":urlCtl.toString())+"<BR>" 00670 +"Fetch interval = "+fetchTime+"ms<BR>" 00671 +"JWP version = "+((jwpVersion==0)?"N/A":String.valueOf(jwpVersion))+"<BR>" 00672 +"Advanced mode = "+(advancedMode?"Enabled":"Disabled")+"<BR>" 00673 +"Fetch counter (control/slide) = "+countCtl+"/"+countSlide+"<BR>" 00674 +"</HTML>"); 00675 moreButton.setText("Less..."); 00676 } 00677 else { 00678 infoLabel.setText("<HTML><BR><CENTER><B>"+JWebPresenterSS.ver 00679 +"</B></CENTER><BR></HTML>"); 00680 moreButton.setText("More..."); 00681 } 00682 infoDialog.pack(); 00683 } 00684 }); 00685 pOK.add(moreButton); 00686 00687 con.add(pOK, BorderLayout.SOUTH); 00688 infoDialog.pack(); 00689 00690 debugMsg("Initilization finished. Ready to run..."); 00691 00692 timer = new Timer(fetchTime, this); 00693 timer.setInitialDelay(0); 00694 timer.start(); 00695 }
|
|
ActionEvent hander, which can happen only for our timer event.
Definition at line 707 of file JWebPresenterSS.java. 00707 { 00708 int oldFetchTime = fetchTime; 00709 boolean succ; 00710 00711 do { 00712 debugMsg("Time stamp: " + System.currentTimeMillis()); 00713 succ = parseCommands(); // urlSlide, urlCtl, fetchTime, seq may change. 00714 } while (fastMode & succ); 00715 00716 // Reschedule if fetch interval (fetchTime) is changed. 00717 if (fetchTime != oldFetchTime) { 00718 debugMsg("Fetch timer is re-schduled to " + fetchTime + "ms."); 00719 timer.setDelay(fetchTime); // restart the timer. 00720 timer.restart(); 00721 } 00722 00723 // Skip the slide fetch if frame is non-null but not being shown. 00724 if (frame != null && !frame.isShowing()) return; 00725 00726 // 2005-05-18: notice that either urlSlide != null or urlCtl != null. 00727 // See the constructor JWPPanelSS() and parseCommands(). 00728 00729 if ((advancedMode == true) && (seq == lastSeq)) { 00730 debugMsg("Target fetch omitted due to the same sequence number."); 00731 } 00732 else { // fetch the new slide. 00733 if (urlSlide == null) return; // For a bad control parameter Slide. 00734 countSlide++; // Else fetch the slide. 00735 tracker.removeImage(img); // Remove to avoid memory leak! 00736 img = tk.createImage(urlSlide); // createImage has no cache problem 00737 tracker.addImage(img, 0); // Use tracker to watch the load. 00738 try { tracker.waitForID(0); } 00739 catch (InterruptedException ie) { 00740 debugMsg("Interrupted in loading image from "+urlSlide); 00741 tracker.removeImage(img); // For interrupted load, remove it. 00742 img = null; // And set the image to null. 00743 } 00744 if (img == null) { // For any error, 00745 debugMsg("Target fetch failed (count = " + countSlide + ")."); 00746 } else { // Otherwise, 00747 debugMsg("Target fetch succeeded (count = " + countSlide + ")."); 00748 if (advancedMode == true) { lastSeq = seq; } 00749 repaint(); 00750 } 00751 } 00752 }
|
|
The debug function (output to err if debugMode is true). Definition at line 410 of file JWebPresenterSS.java. 00410 { 00411 if (debugMode) System.err.println("(info) " + msg); 00412 }
|
|
Get the unsigned int parameter.
Definition at line 790 of file JWebPresenterSS.java. 00790 { 00791 int value = -1; // -1 shows error. 00792 00793 if (msg.startsWith(pattern+"=") == true) { 00794 try { 00795 value = Integer.parseInt(msg.substring(msg.indexOf("=")+1)); 00796 } 00797 catch (NumberFormatException e) { 00798 value = -1; // -1 means error. 00799 } 00800 } 00801 return value; 00802 }
|
|
Get the URL parameter, null for errors.
Definition at line 811 of file JWebPresenterSS.java. 00811 { 00812 URL u = null; 00813 00814 if (msg.startsWith(pattern+"=") == true) { 00815 try { u = new URL(msg.substring(msg.indexOf("=")+1)); } 00816 catch (MalformedURLException e) { u = null; } 00817 // In case of error, we try to use baseURL as the base. 00818 if (u == null) { 00819 try { 00820 u = new URL(baseURL + msg.substring(msg.indexOf("=")+1)); 00821 } 00822 catch (MalformedURLException e) { u = null; } 00823 } 00824 } 00825 return u; 00826 }
|
|
paintComponent (draw the image at the center after download finishes).
Definition at line 759 of file JWebPresenterSS.java. 00759 { 00760 super.paintComponent(g); 00761 00762 if (img == null) { // only happens for error including remote not ready. 00763 debugMsg("No image is available for painting!"); 00764 g.drawString("No image! Error or remote not ready?", 15, 15); 00765 return; 00766 } 00767 00768 if (tracker.statusAll(false) == MediaTracker.COMPLETE) { 00769 if (bResizeToFill == false) { 00770 int upper_left = (getWidth() - img.getWidth(this)) >> 1; 00771 int lower_right = (getHeight() - img.getHeight(this)) >> 1; 00772 g.drawImage(img, upper_left, lower_right, this); 00773 } else { 00774 g.drawImage(img, 0, 0, getWidth(), getHeight(), this); 00775 } 00776 } 00777 else { 00778 debugMsg("Painted image is not ready!"); 00779 g.drawString("Waiting for the load of image...", 15, 15); 00780 } 00781 }
|
|
quit function (hide the frame for applet, otherwise stop the system). Definition at line 417 of file JWebPresenterSS.java. References frame, and isApplet. Referenced by JWPPanelSS(). 00417 { 00418 if (isApplet && frame != null) frame.setVisible(false); 00419 else System.exit(0); 00420 }
|
|
Shall we use advanced mode (= skip slide with the same sequence no.)? See actionPerformed(). Definition at line 317 of file JWebPresenterSS.java. |
|
The base URL (String) for ctlURL and slideURL. Definition at line 267 of file JWebPresenterSS.java. Referenced by JWPPanelSS(). |
|
Show if we should decorate the window. 2005-01-22: all decorate related items are valid only for non-null frame. Definition at line 390 of file JWebPresenterSS.java. |
|
Show if we should resize the image to fill window. Definition at line 384 of file JWebPresenterSS.java. |
|
Connection object for getting parameters. Definition at line 302 of file JWebPresenterSS.java. |
|
Fetched counter for control parameters. Definition at line 312 of file JWebPresenterSS.java. |
|
Counter for the number of fetched slides. Definition at line 307 of file JWebPresenterSS.java. |
|
Debug mode: true to debug, false to not (2004-04-19). Definition at line 297 of file JWebPresenterSS.java. |
|
CheckBox menu item to enable/disable the decoration of window. 2005-01-22: all decorate related items are valid only for non-null frame. Definition at line 374 of file JWebPresenterSS.java. |
|
FastMode setting: if true, fetch ctlURL repeatedly until error (disregard fetchTime); If false, fetch ctlURL repeatedly according to the timer. This is useful for slow clients, who can drop slides to keep up with the latest slide. Definition at line 334 of file JWebPresenterSS.java. |
|
Fetch time interval (in ms!). Definition at line 292 of file JWebPresenterSS.java. |
|
CheckBox menu item to fill/not fill the image to window. Definition at line 379 of file JWebPresenterSS.java. |
|
Reference to my ancestor frame (null if embeded in a viewer). Definition at line 247 of file JWebPresenterSS.java. Referenced by JWPPanelSS(), and quit(). |
|
Image object to hold the target slide. Definition at line 322 of file JWebPresenterSS.java. |
|
BufferedReader for reading the control parameters from urlCtl. Definition at line 341 of file JWebPresenterSS.java. |
|
Information dialog. Definition at line 395 of file JWebPresenterSS.java. |
|
Label to show information in infoDialog. Definition at line 400 of file JWebPresenterSS.java. |
|
Am I an applet or not? Method quit() depends on it. Definition at line 252 of file JWebPresenterSS.java. Referenced by JWPPanelSS(), and quit(). |
|
Version of the command set, valid values are 1, 2... Definition at line 351 of file JWebPresenterSS.java. |
|
Previous sequence number, -1 for none (or nonexist). Definition at line 356 of file JWebPresenterSS.java. |
|
Popup menu. Definition at line 368 of file JWebPresenterSS.java. |
|
When the name is "More...", show more information. Definition at line 405 of file JWebPresenterSS.java. |
|
The original control URL (given to constructor, used for reset). Definition at line 272 of file JWebPresenterSS.java. |
|
The original slide URL (given to constructor, used for reset). Definition at line 277 of file JWebPresenterSS.java. |
|
Current sequence number, valid values are 0, 1, 2... Definition at line 361 of file JWebPresenterSS.java. |
|
Temporary one line text read from in. Definition at line 346 of file JWebPresenterSS.java. |
|
Timer object to control the refresh process. Definition at line 257 of file JWebPresenterSS.java. |
|
Default toolkit to fetch the slide. Definition at line 262 of file JWebPresenterSS.java. Referenced by JWPPanelSS(). |
|
Mediatracker to get img. Definition at line 327 of file JWebPresenterSS.java. |
|
URL for the control commands. Definition at line 282 of file JWebPresenterSS.java. |
|
URL for the slide image. Definition at line 287 of file JWebPresenterSS.java. |