/*** * Windows Tray Icon * ----------------- * * Written by Jan Struyf * * jan.struyf@cs.kuleuven.ac.be * http://jeans.studentenweb.org/java/trayicon/trayicon.html * * Please mail me if you * - 've found bugs * - like this program * - don't like a particular feature * - would like something to be modified * * I always give it my best shot to make a program useful and solid, but * remeber that there is absolutely no warranty for using this program as * stated in the following terms: * * THERE IS NO WARRANTY FOR THIS PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE * LAW. THE COPYRIGHT HOLDER AND/OR OTHER PARTIES WHO MAY HAVE MODIFIED THE * PROGRAM, PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS * TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE * PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, * REPAIR OR CORRECTION. * * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL ANY COPYRIGHT HOLDER, * OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM, * BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE * PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED * INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE * PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER * PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * May the Force be with you... Just compile it & use it! */ package demo.awt; import java.awt.*; import java.awt.event.*; import java.io.*; import com.jeans.trayicon.*; // Demo app for Java Tray Icon public class TestTrayIcon extends Frame { public final static int ENABLE_ITEM = 0; public final static int BOLD_ITEM = 1; public final static int CHECK_ITEM = 2; // App uses 4 icons private TrayIconButton icon[]; // Buttons for exit, hide window and about box private Button exit_bt, hide_bt, about_bt; public TestTrayIcon() throws TrayIconException, InterruptedException { // Create new frame with title super("Test Icon"); setBackground(SystemColor.control); // Set callback method to send windows messages through Tray Icon library (see WindowsMessageCallback) WindowsTrayIcon.setWindowsMessageCallback(new WindowsMessageCallback()); // Layout stuff setLayout(new GridLayout(0,1,3,3)); // Load 16x16 icon gif setIconImage(loadImage("Duke16.gif")); // Create 4 checkboxes with icons: Printer, Battery, France & MS-DOS icon = new TrayIconButton[4]; add(icon[0] = new TrayIconButton("Duke",loadImage("Duke16.gif"),16,16)); add(icon[1] = new TrayIconButton("Printer",loadImage("Printer.gif"),16,16)); add(icon[2] = new TrayIconButton("France",loadImage("France.gif"),16,16)); add(icon[3] = new TrayIconButton("MS-DOS",loadImage("MsDos.gif"),16,16)); // Tray Icon left mouse button event restores the main window (make it visible again/requests focus RestoreListener listener = new RestoreListener(false); for (int k = 0; k < 4; k++) icon[k].addActionListener(listener); // Panel with exit, hide & about button - With hide you can hide the main window and restore it // by clicking on one of the Tray Icons Panel panel = new Panel(); panel.setLayout(new GridLayout(1,0,3,3)); panel.add(exit_bt = new Button("Exit")); exit_bt.addActionListener(new ExitListener()); panel.add(hide_bt = new Button("Hide")); hide_bt.addActionListener(new HideListener()); panel.add(about_bt = new Button("About")); about_bt.addActionListener(new AboutListener()); // Each icon has it's own popup menu // Because the menu's contain state information, you can't use the same menu for different icons) icon[0].setPopup(makePopup()); icon[1].setPopup(makePopup()); icon[2].setPopup(makePopup()); icon[3].setPopup(makePopup()); add(panel); pack(); validate(); // Exit if click on close button addWindowListener(new ExitWindowListener()); } // Create the popup menu for each Tray Icon (on right mouse click) public TrayIconPopup makePopup() { // Make new popup menu TrayIconPopup popup = new TrayIconPopup(); // Add show, about, submenu, separator & exit item TrayIconPopupSimpleItem item = new TrayIconPopupSimpleItem("&Show"); item.setDefault(true); // Each menu item can have it's own ActionListener item.addActionListener(new RestoreListener(true)); popup.addMenuItem(item); item = new TrayIconPopupSimpleItem("&About"); item.addActionListener(new AboutListener()); popup.addMenuItem(item); // Create a submenu with title enable and items check 1 & check 2 TrayIconPopup sub = new TrayIconPopup("&Options"); // Create and add two checkbox menu items TrayIconPopupCheckItem test = new TrayIconPopupCheckItem("Test"); sub.addMenuItem(test); sub.addMenuItem(new TrayIconPopupSeparator()); TrayIconPopupCheckItem ena = new TrayIconPopupCheckItem("Enable Test"); ena.addActionListener(new ChangeMenuListener(test, ENABLE_ITEM)); ena.setCheck(true); sub.addMenuItem(ena); TrayIconPopupCheckItem bold = new TrayIconPopupCheckItem("Bold Test"); bold.addActionListener(new ChangeMenuListener(test, BOLD_ITEM)); sub.addMenuItem(bold); TrayIconPopupCheckItem check = new TrayIconPopupCheckItem("Check Test"); check.addActionListener(new ChangeMenuListener(test, CHECK_ITEM)); test.addActionListener(new ChangeMenuListener(check, CHECK_ITEM)); sub.addMenuItem(check); // Add submenu to the main menu popup.addMenuItem(sub); // Add a separator popup.addMenuItem(new TrayIconPopupSeparator()); // Add exit item item = new TrayIconPopupSimpleItem("E&xit"); item.addActionListener(new ExitListener()); popup.addMenuItem(item); return popup; } // Load a gif image (used for loading the 16x16 icon gifs) public static Image loadImage(String fileName) { return Toolkit.getDefaultToolkit().getImage("demo"+File.separator+"images"+File.separator+fileName); } // Main proc public static void main(String[] args) { try { String appName = "TestTray"; // First check if there's another instance of our app running by sending a windows message // to a hidden icon window "TestTray" - each Tray Icon app has a hidden window that receives // the mouse/menu messages for it's Tray Icons long result = WindowsTrayIcon.sendWindowsMessage(appName, 1234); if (result != -1) { // If window exists, there's already an instance of our app running // Print message and exit (other app will restore its window when receiving // our message - see WindowsMessageCallback System.out.println("Already running other instance of "+appName+" (returns: "+result+")"); return; } // Init the Tray Icon library given the name for the hidden window WindowsTrayIcon.initTrayIcon(appName); // Show our main window TestTrayIcon test = new TestTrayIcon(); TestTrayIcon.centerDialog(test); test.show(); } catch (TrayIconException e) { System.out.println("Error: "+e.getMessage()); } catch (InterruptedException e) { } } public void doExit() { System.out.println("Exit selected."); // Free all Tray Icon resources - always call this on exit WindowsTrayIcon.cleanUp(); // Exit application System.exit(0); } public void doHide(boolean exitOnFail) { System.out.println("Hide selected."); // Check if there's a Tray Icon visible // Hide works only when there's an icon in the system tray boolean visible = true; for (int k = 0; k < 4; k++) { if (icon[k].testVisible()) visible = false; } setVisible(visible); if (visible == true) { System.out.println("Hide works only when there's an icon in the system tray."); if (exitOnFail) doExit(); } } public static void centerDialog(Window frame) { Dimension dialogSize = frame.getSize(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation(screenSize.width/2 - dialogSize.width/2, screenSize.height/2 - dialogSize.height/2); } // Callback listener handles incomming windows messages. In this demo, a windows message is send when the // user tries to start a second instance of the demo app. You can try this one by opening two MS-DOS prompts // and say in each one "java demo.awt.TestTrayIcon" // MS-DOS 1: // C:\TrayIcon>java demo.awt.TestTrayIcon // ... // Other instance started (parameter: 1234) // // MS-DOS 2: // C:\TrayIcon>java demo.awt.TestTrayIcon // Already running other instance of TestTray (returns: 4321) private class WindowsMessageCallback implements TrayIconCallback { public int callback(int param) { // Param contains the integer value send with sendWindowsMessage(appName, param) System.out.println("Other instance started (parameter: "+param+")"); setVisible(true); requestFocus(); // Return integer value to other process return 4321; } } // Callback listener handles exit button / exit popup menu private class ExitListener implements ActionListener { public void actionPerformed(ActionEvent evt) { doExit(); } } // Callback listener handles restore (click left on any icon / show popup menu) private class RestoreListener implements ActionListener { protected boolean from_menu; public RestoreListener(boolean fromMenu) { from_menu = fromMenu; } public void actionPerformed(ActionEvent evt) { if (from_menu) System.out.println("Restore selected.."); else System.out.println("Tray icon button pressed.."); // Make main window visible if it was hidden setVisible(true); // Request input focus requestFocus(); } } // Callback listener for hide button private class HideListener implements ActionListener { public void actionPerformed(ActionEvent evt) { doHide(false); } } // Callback listener handles about button private class AboutListener implements ActionListener { public void actionPerformed(ActionEvent evt) { System.out.println("About selected.."); TrayAboutBox box = new TrayAboutBox(TestTrayIcon.this); centerDialog(box); box.show(); } } // Callback listener handles window close button private class ExitWindowListener extends WindowAdapter { public void windowClosing(WindowEvent evt) { // Free all Tray Icon resources - always call this on exit WindowsTrayIcon.cleanUp(); System.exit(0); } } // Callback listener handles restore (click left on any icon / show popup menu) private class ChangeMenuListener implements ActionListener { protected TrayIconPopupCheckItem m_Item; protected int m_Change; public ChangeMenuListener(TrayIconPopupCheckItem item, int change) { m_Item = item; m_Change = change; } public void actionPerformed(ActionEvent evt) { TrayIconPopupCheckItem source = (TrayIconPopupCheckItem)evt.getSource(); boolean value = source.getCheck(); switch (m_Change) { case ENABLE_ITEM: m_Item.setEnabled(value); break; case BOLD_ITEM: m_Item.setDefault(value); break; case CHECK_ITEM: m_Item.setCheck(value); break; } } } } // Panel with checkbox, string and icon class TrayIconButton extends Panel { // The checkbox for enabling this Tray Icon Checkbox button; // The Tray Icon's class WindowsTrayIcon icon; // Create new panel with checkbox, string and icon // Name = Printer/France/Battery/MS-DOS // Image = 16x16 Icon gif // Wd = 16, Hi = 16 public TrayIconButton(String name, Image image, int wd, int hi) throws TrayIconException, InterruptedException { setLayout(new BorderLayout(3,3)); // Add icon image in ImageDisplayer add(new ImageDisplayer(image, wd, hi), BorderLayout.EAST); // Add checkbox for enabling Tray Icon add(button = new Checkbox(name), BorderLayout.CENTER); button.addItemListener(new ToggleListener()); // Create Tray Icon and set tooltip icon = new WindowsTrayIcon(image, wd, hi); icon.setToolTipText(name); } // Add popup menu to Tray Icon public void setPopup(TrayIconPopup popup) { icon.setPopup(popup); } // Add action listener to Tray Icon public void addActionListener(ActionListener listener) { icon.addActionListener(listener); } // Icon visible? public boolean testVisible() { return icon.isVisible(); } // Listener for checkbox // Make icon visible/invisible depending on checkbox state private class ToggleListener implements ItemListener { public void itemStateChanged(ItemEvent evt) { icon.setVisible(evt.getStateChange() == ItemEvent.SELECTED); } } } // Canvas for displaying images with given size class ImageDisplayer extends Canvas { // The image to display Image image; // The images size int wd, hi; // Create new canvas with given image and size public ImageDisplayer(Image image, int wd, int hi) { this.image = image; this.wd = wd; this.hi = hi; } // Pref size for layout manager public Dimension getPreferredSize() { return new Dimension(wd, hi); } // Min size for layout manager public Dimension getMinimumSize() { return new Dimension(wd, hi); } // Redraw image (don't clear background first!) public void update(Graphics g) { paint(g); } // Redraw image public void paint(Graphics g) { g.drawImage(image, 0, 0, this); } }