1 package net.suberic.pooka.gui; 2 import net.suberic.pooka.Pooka; 3 import net.suberic.pooka.FolderInfo; 4 import net.suberic.pooka.MessageInfo; 5 import net.suberic.util.gui.ConfigurableAwtPopupMenu; 6 import net.suberic.util.gui.IconManager; 7 import net.suberic.util.*; 8 9 import java.util.*; 10 11 import java.awt.event.WindowAdapter ; 12 import java.awt.event.WindowEvent ; 13 import java.awt.PopupMenu ; 14 import javax.swing.*; 15 import javax.swing.SwingUtilities ; 16 import javax.swing.event.HyperlinkEvent ; 17 import javax.swing.event.HyperlinkListener ; 18 import javax.mail.event.MessageCountEvent ; 19 import java.awt.event.ActionEvent ; 20 import java.awt.event.MouseAdapter ; 21 import java.awt.event.MouseEvent ; 22 import java.awt.GraphicsDevice ; 23 import java.awt.GraphicsEnvironment ; 24 import java.awt.GraphicsConfiguration ; 25 26 import java.awt.TrayIcon ; 27 import java.awt.SystemTray ; 28 29 32 public class MessageNotificationManager implements ValueChangeListener { 33 34 public static java.awt.TrayIcon.MessageType WARNING_MESSAGE_TYPE = TrayIcon.MessageType.WARNING; 35 public static java.awt.TrayIcon.MessageType INFO_MESSAGE_TYPE = TrayIcon.MessageType.INFO; 36 37 private MainPanel mPanel; 38 private boolean mNewMessageFlag = false; 39 private TrayIcon mTrayIcon = null; 40 private Map<String , List<MessageInfo>> mNewMessageMap; 41 private int mNewMessageCount = 0; 42 private RecentMessageMenu mRecentMessageMenu; 43 44 private Action[] mOfflineActions; 45 private Action[] mOnlineActions; 46 47 private String mStandardTitle = Pooka.getProperty("Title", "Pooka"); 49 private String mNewMessageTitle = Pooka.getProperty("Title.withNewMessages", "* Pooka *"); 50 51 private ImageIcon mStandardIcon = null; 52 private ImageIcon mNewMessageIcon = null; 53 private ImageIcon mStandardTrayIcon = null; 54 private ImageIcon mNewMessageTrayIcon = null; 55 56 private boolean mShowNewMailMessage = true; 57 private boolean mAlwaysDisplay = true; 58 private boolean mIconShowing = false; 59 private boolean mBlinkNewMail = false; 60 61 private boolean messageDisplaying = false; 62 private Thread messageDisplayThread = null; 63 64 67 public MessageNotificationManager() { 68 mNewMessageMap = new HashMap<String , List<MessageInfo>>(); 69 70 mOfflineActions = new Action[] { 71 new NewMessageAction(), 72 new PreferencesAction(), 73 new ExitPookaAction(), 74 new StartPookaAction() 75 }; 76 77 mOnlineActions = new Action[] { 78 new NewMessageAction(), 79 new PreferencesAction(), 80 new ExitPookaAction(), 81 new ClearStatusAction() 82 }; 83 84 setupImages(); 86 87 configureTrayIcon(); 89 90 Pooka.getResources().addValueChangeListener(this, "Pooka.trayIcon.enabled"); 93 Pooka.getResources().addValueChangeListener(this, "Pooka.trayIcon.showNewMailMessage"); 94 Pooka.getResources().addValueChangeListener(this, "Pooka.trayIcon.alwaysDisplay"); 95 Pooka.getResources().addValueChangeListener(this, "Pooka.trayIcon.show"); 96 } 97 98 101 void configureTrayIcon() { 102 if (Pooka.getProperty("Pooka.trayIcon.enabled", "true").equalsIgnoreCase("true")) { 103 try { 104 mTrayIcon = new TrayIcon (mStandardTrayIcon.getImage()); 105 mTrayIcon.setImageAutoSize(true); 106 108 mTrayIcon.setPopupMenu(createPopupMenu()); 109 mTrayIcon.addActionListener(new AbstractAction() { 110 public void actionPerformed(ActionEvent e) { 111 if (getMainPanel() != null) { 113 mTrayIcon.displayMessage("Pooka", createStatusMessage(), INFO_MESSAGE_TYPE); 114 } else { 116 startMainWindow(); 117 } 118 } 119 }); 120 mTrayIcon.addMouseListener(new MouseAdapter () { 121 public void mouseClicked(java.awt.event.MouseEvent me) { 122 if ((!me.isPopupTrigger()) && ! messageDisplaying) { 123 JDialog dialog = createMessageDialog(); 124 java.awt.GraphicsEnvironment ge = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(); 126 java.awt.GraphicsDevice [] gs = ge.getScreenDevices(); 127 for (int i = 0; i < gs.length; i++) { 128 } 130 dialog.setLocation(me.getX(), me.getY()); 131 dialog.setVisible(true); 132 messageDisplaying = true; 133 } 134 } 135 }); 136 143 if (mAlwaysDisplay) { 144 SystemTray.getSystemTray().add(mTrayIcon); 145 mIconShowing = true; 146 } 147 } catch (Error e) { 148 System.err.println("Error starting up tray icon: " + e.getMessage()); 149 e.printStackTrace(); 150 } catch (Exception exc) { 151 System.err.println("Error starting up tray icon: " + exc.getMessage()); 152 exc.printStackTrace(); 153 } 154 setShowNewMailMessage(Pooka.getProperty("Pooka.trayIcon.showNewMailMessage", "true").equalsIgnoreCase("true")); 155 setAlwaysDisplay(Pooka.getProperty("Pooka.trayIcon.alwaysDisplay", "true").equalsIgnoreCase("true")); 156 157 } else if (mTrayIcon != null) { 158 SystemTray.getSystemTray().remove(mTrayIcon); 160 mTrayIcon = null; 161 mIconShowing = false; 162 } 163 } 164 165 168 void setupImages() { 169 IconManager iconManager; 170 if (Pooka.getUIFactory() != null) { 171 iconManager = Pooka.getUIFactory().getIconManager(); 172 } else { 173 iconManager = IconManager.getIconManager(Pooka.getResources(), "IconManager._default"); 174 } 175 176 177 mStandardIcon = iconManager.getIcon(Pooka.getProperty("Pooka.standardIcon", "PookaIcon")); 178 setCurrentIcon(mStandardIcon); 179 180 mStandardTrayIcon = iconManager.getIcon(Pooka.getProperty("Pooka.standardTrayIcon", "PookaTrayIcon")); 181 182 mNewMessageIcon = iconManager.getIcon(Pooka.getProperty("Pooka.newMessageIcon", "EnvelopeOpen")); 183 184 mNewMessageTrayIcon = iconManager.getIcon(Pooka.getProperty("Pooka.newMessageIcon", "NewMessageTray")); 185 186 } 187 188 193 194 public void valueChanged(String pChangedValue) { 195 if (pChangedValue.equals("Pooka.trayIcon.enabled")) { 196 configureTrayIcon(); 197 } else if (pChangedValue.equals("Pooka.trayIcon.showNewMailMessage")) { 198 setShowNewMailMessage(Pooka.getProperty("Pooka.trayIcon.showNewMailMessage", "true").equalsIgnoreCase("true")); 199 } else if (pChangedValue.equals("Pooka.trayIcon.alwaysDisplay")) { 200 setAlwaysDisplay(Pooka.getProperty("Pooka.trayIcon.alwaysDisplay", "true").equalsIgnoreCase("true")); 201 SwingUtilities.invokeLater(new Runnable () { 202 public void run() { 203 updateStatus(); 204 } 205 }); 206 } 207 } 208 209 213 protected void updateStatus() { 214 synchronized(this) { 215 if (getNewMessageFlag()) { 216 if (getMainPanel() != null) { 218 getMainPanel().getParentFrame().setTitle(mNewMessageTitle); 219 } 220 setCurrentIcon(getNewMessageIcon()); 221 if (getTrayIcon() != null) { 222 getTrayIcon().setImage(mNewMessageTrayIcon.getImage()); 223 if (! mIconShowing) { 224 try { 225 SystemTray.getSystemTray().add(mTrayIcon); 226 mIconShowing = true; 227 } catch (Exception exc) { 228 System.err.println("Error starting up tray icon: " + exc.getMessage()); 229 exc.printStackTrace(); 230 } 231 } 232 } 233 } else { 234 if (getMainPanel() != null) { 235 getMainPanel().getParentFrame().setTitle(mStandardTitle); 236 } 237 238 if (mAlwaysDisplay) { 239 if (! mIconShowing) { 240 try { 241 SystemTray.getSystemTray().add(mTrayIcon); 242 mIconShowing = true; 243 } catch (Exception exc) { 244 System.err.println("Error starting up tray icon: " + exc.getMessage()); 245 exc.printStackTrace(); 246 } 247 } 248 } else { 249 if (mIconShowing) { 250 SystemTray.getSystemTray().remove(mTrayIcon); 251 mIconShowing = false; 252 } 253 } 254 255 setCurrentIcon(getStandardIcon()); 256 if (getTrayIcon() != null) 257 getTrayIcon().setImage(mStandardTrayIcon.getImage()); 258 } 259 } } 261 262 266 void bringToFront() { 267 Pooka.getMainPanel().getParentFrame().toFront(); 271 } 273 274 277 public synchronized void clearNewMessageFlag() { 278 boolean doUpdate = mNewMessageFlag; 279 mNewMessageFlag = false; 280 mNewMessageCount = 0; 281 if (getRecentMessageMenu() != null) 282 getRecentMessageMenu().reset(); 283 284 mNewMessageMap = new HashMap<String , List<MessageInfo>>(); 285 if (mTrayIcon != null) { 286 mTrayIcon.setToolTip("Pooka: No new messages."); 287 } 288 if (doUpdate) { 289 updateStatus(); 291 } 292 } 293 294 297 public synchronized void notifyNewMessagesReceived(MessageCountEvent e, String pFolderId) { 298 mNewMessageCount+= e.getMessages().length; 300 List<MessageInfo> newMessageList = mNewMessageMap.get(pFolderId); 301 if (newMessageList == null) { 302 newMessageList = new ArrayList<MessageInfo>(); 303 } 304 305 StringBuffer infoLines = new StringBuffer (); 309 try { 310 FolderInfo folder = Pooka.getStoreManager().getFolderById(pFolderId); 311 if (folder != null) { 312 for (int i = 0; i < e.getMessages().length; i++) { 313 MessageInfo current = folder.getMessageInfo(e.getMessages()[i]); 314 newMessageList.add(current); 315 if (i < 3) 316 infoLines.append("From: " + current.getMessageProperty("From") + ", Subj: " + current.getMessageProperty("Subject") + "\r\n\r\n"); 317 else if (i == 3) 318 infoLines.append("..."); 319 } 320 } 321 } catch (javax.mail.MessagingException me) { 322 me.printStackTrace(); 324 } 325 mNewMessageMap.put(pFolderId, newMessageList); 327 328 final String fDisplayMessage = new String (e.getMessages().length + " messages received in " + pFolderId + "\r\n\r\n" + infoLines.toString()); 330 final String fToolTip = "Pooka: " + mNewMessageCount + " new messages."; 331 boolean doUpdateStatus = false; 332 if (! mNewMessageFlag) { 333 mNewMessageFlag = true; 334 doUpdateStatus = true; 335 } 336 337 final boolean fUpdateStatus = doUpdateStatus; 338 339 SwingUtilities.invokeLater(new Runnable () { 340 public void run() { 341 if (fUpdateStatus) 342 updateStatus(); 343 344 if (mTrayIcon != null) { 345 mTrayIcon.setToolTip(fToolTip); 346 if (mShowNewMailMessage) { 347 mTrayIcon.displayMessage("New Messages", fDisplayMessage, INFO_MESSAGE_TYPE); 348 } 349 if (mBlinkNewMail) { 350 Runnable runMe = new Runnable () { 351 public void run() { 352 Runnable removeMe = new Runnable () { 353 public void run() { 354 synchronized(MessageNotificationManager.this) { 355 if (mNewMessageFlag) { 356 if (getTrayIcon() != null) 357 getTrayIcon().setImage(null); 358 } 359 } 360 } 361 }; 362 363 Runnable showMe = new Runnable () { 364 public void run() { 365 synchronized(MessageNotificationManager.this) { 366 if (getTrayIcon() != null) 367 getTrayIcon().setImage(getNewMessageIcon().getImage()); 368 } 369 } 370 }; 371 372 try { 373 for (int i = 0; i < 3; i++) { 374 SwingUtilities.invokeLater(removeMe); 375 Thread.currentThread().sleep(1000); 376 SwingUtilities.invokeLater(showMe); 377 Thread.currentThread().sleep(1000); 378 } 379 } catch (Exception e) { 380 381 } 382 } 383 }; 384 385 Thread blinkThread = new Thread (runMe); 386 blinkThread.setPriority(Thread.NORM_PRIORITY); 387 blinkThread.start(); 388 } 389 } 390 } 391 }); 392 393 if (getRecentMessageMenu() != null) 394 getRecentMessageMenu().reset(); 395 } 396 397 400 public synchronized void removeFromNewMessages(MessageInfo pMessageInfo) { 401 String folderId = pMessageInfo.getFolderInfo().getFolderID(); 402 List<MessageInfo> newMessageList = mNewMessageMap.get(folderId); 403 if (newMessageList != null) { 404 newMessageList.remove(pMessageInfo); 405 mNewMessageCount --; 406 if (mNewMessageCount == 0) 407 clearNewMessageFlag(); 408 } 409 410 if (getRecentMessageMenu() != null) 411 getRecentMessageMenu().reset(); 412 413 } 414 415 418 public PopupMenu createPopupMenu() { 419 ConfigurableAwtPopupMenu popupMenu = new ConfigurableAwtPopupMenu(); 420 popupMenu.configureComponent("MessageNotificationManager.popupMenu", Pooka.getResources()); 421 popupMenu.setActive(getActions()); 422 return popupMenu; 423 } 424 425 428 public String createStatusMessage() { 429 StringBuffer buffer = new StringBuffer (); 430 buffer.append("Pooka\n"); 431 if (mNewMessageMap.isEmpty()) { 432 buffer.append("No new messages."); 433 } else { 434 Iterator<String > folders = mNewMessageMap.keySet().iterator(); 435 while (folders.hasNext()) { 436 String current = folders.next(); 437 buffer.append(current + ": " + mNewMessageMap.get(current).size() + " new messages.\n"); 438 } 439 } 440 441 return buffer.toString(); 442 } 443 444 447 void startMainWindow() { 448 net.suberic.pooka.messaging.PookaMessageSender sender = new net.suberic.pooka.messaging.PookaMessageSender(); 449 try { 450 sender.openConnection(); 451 if (sender.checkVersion()) { 452 sender.sendStartPookaMessage(); 453 } 454 } catch (Exception exc) { 455 if (mTrayIcon != null) 456 mTrayIcon.displayMessage("Error", "Error sending new message: " + exc, WARNING_MESSAGE_TYPE); 457 } finally { 458 if (sender != null && sender.isConnected()) 459 sender.closeConnection(); 460 } 461 } 462 463 466 public Action[] getActions() { 467 if (getMainPanel() == null) 468 return mOfflineActions; 469 else 470 return mOnlineActions; 471 } 472 473 476 public ImageIcon getStandardIcon() { 477 return mStandardIcon; 478 } 479 480 483 public ImageIcon getNewMessageIcon() { 484 return mNewMessageIcon; 485 } 486 487 490 public void setCurrentIcon(ImageIcon newIcon) { 491 if (getMainPanel() != null) 495 getMainPanel().getParentFrame().setIconImage(newIcon.getImage()); 496 } 497 498 501 public TrayIcon getTrayIcon() { 502 return mTrayIcon; 503 } 504 505 508 public MainPanel getMainPanel() { 509 return mPanel; 510 } 511 512 WindowAdapter mAdapter = null; 513 516 public void setMainPanel(MainPanel pPanel) { 517 if (mPanel != pPanel) { 518 if (pPanel != null) { 519 pPanel.getParentFrame().removeWindowListener(mAdapter); 520 mAdapter = null; 521 } 522 mPanel = pPanel; 523 524 if (mPanel != null) { 525 mAdapter = new WindowAdapter () { 526 public void windowActivated(WindowEvent e) { 527 clearNewMessageFlag(); 528 } 529 }; 530 mPanel.getParentFrame().addWindowListener(mAdapter); 531 SwingUtilities.invokeLater(new Runnable () { 532 public void run() { 533 updateStatus(); 534 } 535 }); 536 } 537 } 538 539 if (mTrayIcon != null) 540 mTrayIcon.setPopupMenu(createPopupMenu()); 541 542 } 544 545 553 public boolean displayMessage(String pTitle, String pMessage, TrayIcon.MessageType pType) { 554 if (mTrayIcon != null && mShowNewMailMessage) { 555 mTrayIcon.displayMessage(pTitle, pMessage, pType); 556 return true; 557 } else { 558 return false; 559 } 560 } 561 562 565 public JDialog createMessageDialog() { 566 HashMap<String , MessageInfo> messageMap = new HashMap<String , MessageInfo>(); 567 Box messageBox = new Box(BoxLayout.Y_AXIS); 568 Box headerBox = new Box(BoxLayout.X_AXIS); 569 570 JTextPane headerPane = new JTextPane(); 572 headerPane.setContentType("text/html"); 573 headerPane.setText("<html><body style=\" font-size: 9px; \"><b>Pooka</b></body></html> "); 574 headerPane.setEditable(false); 575 576 headerBox.add(headerPane); 577 JButton closeButton = new JButton(javax.swing.plaf.metal.MetalIconFactory.getInternalFrameCloseIcon(5)); 578 closeButton.setMinimumSize(new java.awt.Dimension (15,15)); 579 closeButton.setPreferredSize(new java.awt.Dimension (15,15)); 580 closeButton.setMaximumSize(new java.awt.Dimension (15,15)); 581 headerBox.add(closeButton); 582 583 messageBox.add(headerBox); 584 585 StringBuffer textBuffer = new StringBuffer (); 586 textBuffer.append("<html><body style=\" font-size: 9px; \">"); 588 if (! mNewMessageMap.isEmpty()) { 589 textBuffer.append("<ul>"); 590 Iterator<String > folderIds = mNewMessageMap.keySet().iterator(); 591 while (folderIds.hasNext()) { 592 textBuffer.append("<li>"); 593 String folderId = folderIds.next(); 594 textBuffer.append(folderId); 595 textBuffer.append("<ul>"); 596 Iterator<MessageInfo> messageIter = mNewMessageMap.get(folderId).iterator(); 597 int counter = 0; 598 while (messageIter.hasNext()) { 599 try { 600 MessageInfo messageInfo = messageIter.next(); 601 String messageUri = "mailopen://" + folderId + "/" + counter++; 602 textBuffer.append("<li><a href = \"" + messageUri + "\">"); 603 messageMap.put(messageUri, messageInfo); 604 textBuffer.append("From: " + messageInfo.getMessageProperty("From") + ", Subj: " + messageInfo.getMessageProperty("Subject")); 605 textBuffer.append("</a></li>"); 606 } catch (Exception e) { 607 textBuffer.append("<li>Error: " + e.getMessage() + "</li>"); 608 } 609 } 610 textBuffer.append("</ul>"); 611 textBuffer.append("</li>"); 612 } 613 614 textBuffer.append("</ul>"); 615 } else { 616 textBuffer.append("No new messages."); 617 } 618 textBuffer.append("</body></html>"); 619 620 final HashMap<String , MessageInfo> fMessageMap = messageMap; 621 622 JTextPane pookaMessage = new JTextPane(); 624 pookaMessage.setContentType("text/html"); 625 pookaMessage.setText(textBuffer.toString()); 626 627 messageBox.add(pookaMessage); 628 629 final JDialog dialog = new JDialog(); 630 pookaMessage.setEditable(false); 631 dialog.add(messageBox); 633 dialog.setUndecorated(true); 634 dialog.pack(); 635 644 closeButton.addActionListener(new AbstractAction() { 645 public void actionPerformed(ActionEvent e) { 646 dialog.setVisible(false); 647 dialog.dispose(); 648 messageDisplaying = false; 649 } 650 }); 651 652 pookaMessage.addHyperlinkListener(new HyperlinkListener () { 653 public void hyperlinkUpdate(HyperlinkEvent e) { 654 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 655 java.net.URL url = e.getURL(); 657 if (e.getDescription().startsWith("close")) { 660 dialog.setVisible(false); 661 dialog.dispose(); 662 messageDisplaying = false; 663 } else if (e.getDescription().startsWith("mailopen://")) { 664 MessageInfo openMessage = fMessageMap.get(e.getDescription()); 665 try { 666 MessageProxy proxy = openMessage.getMessageProxy(); 667 MessageUI mui = Pooka.getUIFactory().createMessageUI(proxy, new NewMessageFrame(new NewMessageProxy(new net.suberic.pooka.NewMessageInfo(new javax.mail.internet.MimeMessage (Pooka.getDefaultSession()))))); 668 mui.openMessageUI(); 669 removeFromNewMessages(openMessage); 671 } catch (Exception ex) { 672 ex.printStackTrace(); 673 } 674 } 675 } 676 } 677 }); 678 679 messageDisplayThread = new Thread (new Runnable () { 680 public void run() { 681 try { 682 Thread.currentThread().sleep(5000); 683 } catch(Exception e) { 684 } 685 if (messageDisplaying) { 686 dialog.setVisible(false); 687 dialog.dispose(); 688 messageDisplaying = false; 689 } 690 } 691 }); 692 693 messageDisplayThread.start(); 694 695 return dialog; 696 697 } 698 699 702 public boolean getNewMessageFlag() { 703 return mNewMessageFlag; 704 } 705 706 710 public boolean getShowNewMailMessage() { 711 return mShowNewMailMessage; 712 } 713 714 718 public void setShowNewMailMessage(boolean pShowNewMailMessage) { 719 mShowNewMailMessage = pShowNewMailMessage; 720 } 721 722 726 public boolean getAlwaysDisplay() { 727 return mAlwaysDisplay; 728 } 729 730 734 public void setAlwaysDisplay(boolean pAlwaysDisplay) { 735 mAlwaysDisplay = pAlwaysDisplay; 736 } 737 738 741 public Map<String , List<MessageInfo>> getNewMessageMap() { 742 return mNewMessageMap; 743 } 744 745 748 void setRecentMessageMenu(RecentMessageMenu pRecentMessageMenu) { 749 mRecentMessageMenu = pRecentMessageMenu; 750 } 751 752 755 RecentMessageMenu getRecentMessageMenu() { 756 return mRecentMessageMenu; 757 } 758 759 761 class NewMessageAction extends AbstractAction { 762 763 NewMessageAction() { 764 super("message-new"); 765 } 766 767 public void actionPerformed(ActionEvent e) { 768 net.suberic.pooka.messaging.PookaMessageSender sender = new net.suberic.pooka.messaging.PookaMessageSender(); 770 try { 771 sender.openConnection(); 772 if (sender.checkVersion()) { 773 sender.openNewEmail(null, null); 774 } 775 } catch (Exception exc) { 776 if (mTrayIcon != null) 777 mTrayIcon.displayMessage("Error", "Error sending new message: " + exc, WARNING_MESSAGE_TYPE); 778 } finally { 779 if (sender != null && sender.isConnected()) 780 sender.closeConnection(); 781 } 782 } 783 } 784 785 class OpenMessageAction extends AbstractAction { 786 787 MessageInfo mMessageInfo; 788 789 OpenMessageAction(MessageInfo pMessageInfo) { 790 super("message-new"); 791 792 mMessageInfo = pMessageInfo; 793 } 794 795 public void actionPerformed(ActionEvent e) { 796 798 try { 799 MessageProxy proxy = mMessageInfo.getMessageProxy(); 800 MessageUI mui = Pooka.getUIFactory().createMessageUI(proxy, new NewMessageFrame(new NewMessageProxy(new net.suberic.pooka.NewMessageInfo(new javax.mail.internet.MimeMessage (Pooka.getDefaultSession()))))); 801 mui.openMessageUI(); 802 removeFromNewMessages(mMessageInfo); 804 } catch (Exception ex) { 805 ex.printStackTrace(); 806 } 807 } 808 } 809 810 class ClearStatusAction extends AbstractAction { 811 812 ClearStatusAction() { 813 super("status-clear"); 814 } 815 816 public void actionPerformed(ActionEvent e) { 817 clearNewMessageFlag(); 818 } 819 } 820 821 class PreferencesAction extends AbstractAction { 822 823 PreferencesAction() { 824 super("file-preferences"); 825 } 826 827 public void actionPerformed(ActionEvent e) { 828 } 830 } 831 832 class StartPookaAction extends AbstractAction { 833 834 StartPookaAction() { 835 super("file-start"); 836 } 837 838 public void actionPerformed(ActionEvent e) { 839 if (getMainPanel() != null) 840 bringToFront(); 841 else { 842 startMainWindow(); 843 } 844 } 845 } 846 847 class ExitPookaAction extends AbstractAction { 848 849 ExitPookaAction() { 850 super("file-exit"); 851 } 852 853 public void actionPerformed(ActionEvent e) { 854 if (getMainPanel() != null) 855 getMainPanel().exitPooka(false); 856 else 857 Pooka.exitPooka(0, this); 858 } 859 } 860 861 } 862 | Popular Tags |