Java tutorial
/* * Adito * * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.adito.agent.client.gui.swt; import java.io.IOException; import java.io.InputStream; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tray; import org.eclipse.swt.widgets.TrayItem; import com.maverick.http.HttpAuthenticator; import com.adito.agent.client.ActionCallback; import com.adito.agent.client.Agent; import com.adito.agent.client.AgentAction; import com.adito.agent.client.AgentClientGUI; import com.adito.agent.client.Console; import com.adito.agent.client.PortMonitor; import com.adito.agent.client.TaskProgress; import com.adito.agent.client.util.BrowserLauncher; /** * {@link AbstractAWTGUI} implementation that uses the system tray API provided * with SWT. */ public class SWTSystemTrayGUI implements AgentClientGUI { // #ifdef DEBUG static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory .getLog(SWTSystemTrayGUI.class); // #endif final int IDLE_ICON = 0; final int TX_ICON = 1; final int RX_ICON = 2; final int TXRX_ICON = 3; final int DISCONNECTED_ICON = 4; /** * Default timeout */ public final static int DEFAULT_TIMEOUT = 10000; // Private instance variables private Image[] icons; private Tray tray; private TrayItem trayItem; private Display display; private Agent agent; private Menu popupMenu; private Shell shell; private Object initLock = new Object() { }; private SWTBalloonWindow balloon; private Label messageLabel; private PortMonitor portMonitor; private PopupTimer popupTimer; private Console console; private int menuIdx = 0; private Hashtable menuLookup = new Hashtable(); private Hashtable menuItemLookup = new Hashtable(); /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#init(com.adito.vpn.client.VPNClientGUIListener) */ public void init(Agent agent) { this.agent = agent; Thread t = new Thread() { public void run() { doInit(); eventLoop(); } }; t.start(); synchronized (initLock) { try { initLock.wait(); } catch (InterruptedException e) { } } } public Menu getMenu() { return popupMenu; } public Agent getAgent() { return agent; } public Display getDisplay() { return display; } public Shell getShell() { return shell; } protected void doInit() { // display = new Display(); shell = new Shell(display); // Load the icons icons = new Image[5]; icons[IDLE_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-idle.gif"); //$NON-NLS-1$ icons[TX_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-tx.gif"); //$NON-NLS-1$ icons[RX_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-rx.gif"); //$NON-NLS-1$ icons[TXRX_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-txrx.gif"); //$NON-NLS-1$ icons[DISCONNECTED_ICON] = loadImage(SWTSystemTrayGUI.class, "/images/tray-disconnecting.gif"); //$NON-NLS-1$ // Create the menu popupMenu = new Menu(shell, SWT.POP_UP); MenuItem open = new MenuItem(popupMenu, SWT.PUSH); open.setText(Messages.getString("GUI.menu.openBrowser")); //$NON-NLS-1$ open.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { openBrowser(null); } }); // #ifdef DEBUG MenuItem console = new MenuItem(popupMenu, SWT.PUSH); console.setText(Messages.getString("GUI.menu.debugConsole")); //$NON-NLS-1$ console.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { getConsole().show(); } }); // #endif MenuItem ports = new MenuItem(popupMenu, SWT.PUSH); ports.setText(Messages.getString("GUI.menu.tunnelMonitor")); //$NON-NLS-1$ ports.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { getPortMonitor().setVisible(!getPortMonitor().isVisible()); } }); MenuItem about = new MenuItem(popupMenu, SWT.PUSH); about.setText(Messages.getString("GUI.menu.about")); //$NON-NLS-1$ about.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { about(); } }); // Create the menu items new MenuItem(popupMenu, SWT.SEPARATOR); MenuItem exit = new MenuItem(popupMenu, SWT.PUSH); exit.setText(Messages.getString("GUI.menu.exit")); //$NON-NLS-1$ exit.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { exit(); } }); // Create the tray item tray = display.getSystemTray(); if (tray == null) { // #ifdef DEBUG log.error("The system tray is not available"); // #endif } else { // Create the icon trayItem = new TrayItem(tray, SWT.NONE); trayItem.setToolTipText(Messages.getString("GUI.appName")); trayItem.addListener(SWT.Show, new Listener() { public void handleEvent(Event event) { } }); trayItem.addListener(SWT.Hide, new Listener() { public void handleEvent(Event event) { } }); trayItem.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { } }); trayItem.addListener(SWT.DefaultSelection, new Listener() { public void handleEvent(Event event) { } }); trayItem.addListener(SWT.MenuDetect, new Listener() { public void handleEvent(Event event) { popupMenu.setVisible(true); } }); trayItem.setImage(icons[IDLE_ICON]); } } void about() { final Image image = loadImage(SWTSystemTrayGUI.class, "/images/frame-agent.png"); SWTAboutDialog about = new SWTAboutDialog(shell, Messages.getString("About.close"), Messages.getString("About.title"), image, MessageFormat.format(Messages.getString("About.message"), new Object[] { agent.getServerVersion() }), Messages.getString("About.description"), Messages.getString("About.copyright"), Messages.getString("About.link")); if (agent.getState() != Agent.STATE_DISCONNECTED) { Composite shell = about.getAccessory(); Composite c = new Composite(shell, 0); GridLayout gridLayout = new GridLayout(); c.setLayout(gridLayout); Label host = new Label(c, SWT.WRAP); host.setText( MessageFormat.format(Messages.getString("About.host"), new Object[] { agent.getAditoHost() })); GridData data = new GridData(); data.horizontalAlignment = GridData.BEGINNING; data.grabExcessHorizontalSpace = true; host.setLayoutData(data); Label port = new Label(c, SWT.WRAP); port.setText(MessageFormat.format(Messages.getString("About.port"), new Object[] { String.valueOf(agent.getAditoPort()) })); data = new GridData(); data.horizontalAlignment = GridData.BEGINNING; data.grabExcessHorizontalSpace = true; port.setLayoutData(data); Label username = new Label(c, SWT.WRAP); username.setText(MessageFormat.format(Messages.getString("About.username"), new Object[] { agent.getUsername() })); data = new GridData(); data.horizontalAlignment = GridData.BEGINNING; data.grabExcessHorizontalSpace = true; username.setLayoutData(data); Label serverVersion = new Label(c, SWT.WRAP); serverVersion.setText(MessageFormat.format(Messages.getString("About.serverVersion"), new Object[] { agent.getServerVersion() })); data = new GridData(); data.horizontalAlignment = GridData.BEGINNING; data.grabExcessHorizontalSpace = true; serverVersion.setLayoutData(data); Label agentVersion = new Label(c, SWT.WRAP); agentVersion.setText(MessageFormat.format(Messages.getString("About.agentVersion"), new Object[] { agent.getClientVersion() })); data = new GridData(); data.horizontalAlignment = GridData.BEGINNING; data.grabExcessHorizontalSpace = true; agentVersion.setLayoutData(data); } about.open(); } /* * (non-Javadoc) * * @see com.adito.agent.client.AgentClientGUI#openBrowser(java.lang.String) */ public void openBrowser(String path) { try { String browserPath = "https://" + agent.getAditoHost() + ":" + agent.getAditoPort() + //$NON-NLS-1$ //$NON-NLS-2$ (path == null ? "" : ("/" + path)); // #ifdef DEBUG log.info("Opening browser to " + browserPath); // #endif BrowserLauncher.openURL(browserPath); } catch (IOException ioe) { // #ifdef DEBUG log.error(ioe); // #endif } } void eventLoop() { synchronized (initLock) { initLock.notify(); } while (true) { if (!display.readAndDispatch()) display.sleep(); } } /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#showIdle() */ public void showIdle() { setImage(icons[IDLE_ICON]); } /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#showDisconnected() */ public void showDisconnected() { setImage(icons[DISCONNECTED_ICON]); } /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#showTx() */ public void showTx() { setImage(icons[TX_ICON]); } /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#showRx() */ public void showRx() { setImage(icons[RX_ICON]); } /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#showTxRx() */ public void showTxRx() { setImage(icons[TXRX_ICON]); } void setImage(final Image image) { display.asyncExec(new Runnable() { public void run() { trayItem.setImage(image); } }); } /* * (non-Javadoc) * * @see com.adito.vpn.client.VPNClientGUI#setInfo(java.lang.String) */ public void setInfo(final String info) { display.asyncExec(new Runnable() { public void run() { trayItem.setToolTipText(info); } }); } protected Image loadImage(Class clazz, String path) { InputStream stream = clazz.getResourceAsStream(path); return stream == null ? null : new Image(display, stream); } public boolean confirm(final int dialogType, final String okText, final String cancelText, final String title, final String message) { final List l = new ArrayList(); display.syncExec(new Runnable() { public void run() { int type = SWT.ICON_QUESTION; if (dialogType == INFORMATION) { type = SWT.ICON_INFORMATION; } else if (dialogType == ERROR) { type = SWT.ICON_ERROR; } else if (dialogType == WARNING) { type = SWT.ICON_WARNING; } MessageBox messageBox = new MessageBox(shell, type | SWT.OK | (cancelText != null ? SWT.CANCEL : 0)); messageBox.setText(title); messageBox.setMessage(message); int buttonID = messageBox.open(); switch (buttonID) { case SWT.OK: l.add(Boolean.TRUE); default: l.add(Boolean.FALSE); } } }); return ((Boolean) l.get(0)).booleanValue(); } /* * (non-Javadoc) * * @see com.adito.agent.client.AgentClientGUI#error(java.lang.String, * java.lang.String, java.lang.String, java.lang.String, * java.lang.Throwable) */ public boolean error(String okText, String cancelText, String title, String message, Throwable ex) { return confirm(ERROR, okText, cancelText, title, message); } /* * (non-Javadoc) * * @see com.adito.agent.client.AgentClientGUI#getConsole() */ public synchronized Console getConsole() { if (console == null) { console = new SWTConsoleOutputStream( "true".equals(System.getProperty("console.toSysOut", "false")) ? System.out : null, this); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } return console; } /* * (non-Javadoc) * * @see com.adito.agent.client.AgentClientGUI#createTaskProgress(java.lang.String, * java.lang.String, long, boolean) */ public TaskProgress createTaskProgress(String message, String note, long maxValue, boolean allowCancel) { return new SWTProgressDialog(this, (int) maxValue, allowCancel, message, note); } /* * (non-Javadoc) * * @see com.adito.agent.client.AgentClientGUI#popup(com.adito.agent.client.AgentClientGUI.ActionCallback, * java.lang.String, java.lang.String, java.lang.String, int) */ public void popup(final ActionCallback callback, final String message, final String title, final String imageName, final int timeout) { display.syncExec(new Runnable() { public void run() { if (popupTimer != null) { popupTimer.setBalloon(null); } popupTimer = new PopupTimer(); if (balloon != null && !balloon.getShell().isDisposed()) { balloon.setVisible(false); } balloon = new SWTBalloonWindow(display, SWT.ON_TOP | SWT.TITLE | SWT.CLOSE); balloon.setAutoLocation(SWT.BOTTOM | SWT.RIGHT); balloon.setLocation(56, 56); balloon.setAnchor(SWT.BOTTOM | SWT.RIGHT); balloon.setAutoAnchor(false); balloon.getContents().setLayout(new FillLayout()); balloon.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { // #ifdef DEBUG log.debug("Balloon selected"); // #endif if (callback != null) { callback.actionPerformed(); } balloon.close(); } }); messageLabel = new Label(balloon.getContents(), SWT.WRAP); messageLabel.setForeground(balloon.getShell().getForeground()); messageLabel.setBackground(balloon.getShell().getBackground()); balloon.addSelectionControl(messageLabel); balloon.setText(title); // balloon.setText(title); messageLabel.setText(message == null ? "<No message supplied>" : message); messageLabel.setSize(messageLabel.computeSize(300, SWT.DEFAULT)); Composite c = balloon.getContents(); Point messageSize = messageLabel.getSize(); Image image = imageName != null ? loadImage(SWTSystemTrayGUI.class, "/images/" + imageName + ".png") : null; if (image != null) { balloon.setImage(image); c.setSize(messageSize.x, messageSize.y); } else { c.setSize(messageSize); } if (!balloon.getShell().getVisible()) { balloon.setVisible(true); } if (timeout != 0) { popupTimer.setBalloon(balloon); display.timerExec(timeout == -1 ? DEFAULT_TIMEOUT : timeout, popupTimer); } } }); } public PortMonitor getPortMonitor() { if (portMonitor == null) { createPortMonitor(); } return portMonitor; } public boolean promptForCredentials(final boolean proxy, final HttpAuthenticator authenticator) { return ((Boolean) SWTRunner.syncExec(display, new SWTRunner() { public Object doRun() { return new Boolean(SWTAuthenticationDialog.promptForCredentials(proxy, shell, authenticator, null)); } })).booleanValue(); } public void dispose() { shell.getDisplay().syncExec(new Runnable() { public void run() { if (tray != null) { trayItem.dispose(); tray.dispose(); } getPortMonitor().dispose(); getConsole().dispose(); } }); } public void addMenu(final String name) { display.syncExec(new Runnable() { public void run() { if (menuIdx == 0) { new MenuItem(popupMenu, SWT.SEPARATOR, 0); } MenuItem item = new MenuItem(popupMenu, SWT.CASCADE, menuIdx); menuIdx++; item.setText(name); Menu menu = new Menu(popupMenu); item.setMenu(menu); menuLookup.put(name, menu); menuItemLookup.put(name, item); } }); } public void removeMenu(final String name) { display.syncExec(new Runnable() { public void run() { Menu menu = (Menu) menuLookup.get(name); MenuItem menuItem = (MenuItem) menuItemLookup.get(name); if (menu != null) { menu.dispose(); menuItem.dispose(); menuLookup.remove(name); menuItemLookup.remove(name); } } }); } public void clearMenu(final String name) { display.syncExec(new Runnable() { public void run() { Menu menu = (Menu) menuLookup.get(name); if (menu != null) { while (menu.getItemCount() > 0) { menu.getItem(0).dispose(); } } } }); } public boolean isMenuExists(String name) { return menuLookup.containsKey(name); } public void addMenuItem(String name, final AgentAction action) { // #ifdef DEBUG log.debug("Adding menu item " + action.getAction() + " to " + name); // #endif final Menu parentMenu = name == null ? popupMenu : (Menu) menuLookup.get(name); if (parentMenu == null) { // #ifdef DEBUG log.error("No parent menu item " + name + " for " + action.getAction()); // #endif return; } display.syncExec(new Runnable() { public void run() { MenuItem item = new MenuItem(parentMenu, SWT.PUSH); item.setText(action.getAction()); item.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { action.actionPerformed(); } }); } }); } public void addMenuSeperator(String name) { final Menu parentMenu = name == null ? popupMenu : (Menu) menuLookup.get(name); if (parentMenu == null) return; display.syncExec(new Runnable() { public void run() { new MenuItem(parentMenu, SWT.SEPARATOR); } }); } protected void createPortMonitor() { display.syncExec(new Runnable() { public void run() { portMonitor = new SWTPortMonitor(SWTSystemTrayGUI.this); } }); } protected void exit() { agent.disconnect(); } class PopupTimer implements Runnable { private SWTBalloonWindow balloon; public void setBalloon(SWTBalloonWindow balloon) { this.balloon = balloon; } public void run() { display.syncExec(new Runnable() { public void run() { if (balloon != null && !balloon.getShell().isDisposed()) { balloon.setVisible(false); } } }); } } }