00001 package edu.stanford.hci.r3.actions.remote;
00002
00003 import java.awt.AWTException;
00004 import java.awt.BorderLayout;
00005 import java.awt.CheckboxMenuItem;
00006 import java.awt.Font;
00007 import java.awt.Image;
00008 import java.awt.MenuItem;
00009 import java.awt.PopupMenu;
00010 import java.awt.SystemTray;
00011 import java.awt.TrayIcon;
00012 import java.awt.event.ActionEvent;
00013 import java.awt.event.ActionListener;
00014
00015 import javax.swing.BorderFactory;
00016 import javax.swing.JButton;
00017 import javax.swing.JFrame;
00018 import javax.swing.JLabel;
00019 import javax.swing.JPanel;
00020
00021 import edu.stanford.hci.r3.PaperToolkit;
00022 import edu.stanford.hci.r3.util.WindowUtils;
00023 import edu.stanford.hci.r3.util.components.SuperJTextField;
00024 import edu.stanford.hci.r3.util.graphics.ImageCache;
00025 import edu.stanford.hci.r3.util.networking.ClientServerType;
00026
00046 public class ActionReceiverTrayApp {
00047
00048 private static final String DESCRIPTION = "Action Receiver (right-click for options; double-click to turn ON/OFF)\n";
00049
00050 private static final String DIRECTIONS_FOR_SETTING_LIST_OF_TRUSTED_CLIENTS = "<html>Enter a comma-separated list of trusted machines. "
00051 + "You may use whole or partial <b>DNS names</b> or <b>IP Addresses</b>.<br/>"
00052 + "\tExample: <b>localhost, .stanford.edu, 192.168, 128.123.*.*</b><br/><br/>"
00053 + "Press Enter to save the value. Then, double click the Action Receiver "
00054 + "(Saturn icon) in your System Tray to connect.</html>";
00055
00056 private static final String START_MSG = "Start the Action Receiver";
00057
00058 private static final String STATUS_OFF = "The Action Receiver is off.";
00059
00063 private static final String STATUS_ON = "The Action Receiver is now running.";
00064
00068 private static final String STOP_MSG = "Stop the Action Receiver";
00069
00074 public static void main(String[] args) {
00075 new ActionReceiverTrayApp();
00076 }
00077
00081 private ActionReceiver actionReceiver;
00082
00086 private String currentStatus;
00087
00091 private ActionListener iconListener;
00092
00096 private Image imageOFF;
00097
00101 private Image imageON;
00102
00106 private MenuItem onOffItem;
00107
00111 private boolean receiverRunning = false;
00112
00113 private CheckboxMenuItem setShowConnectionMessageItem;
00114
00118 private TrayIcon trayIcon;
00119
00123 private JFrame trustedClientsFrame;
00124
00128 private SuperJTextField trustedClientsTextField;
00129
00133 public ActionReceiverTrayApp() {
00134
00135 PaperToolkit.initializeLookAndFeel();
00136
00137
00138 if (!SystemTray.isSupported()) {
00139 System.err.println("The System Tray is not supported. "
00140 + "Exiting the ActionReceiverTrayApp.");
00141 return;
00142 }
00143
00144
00145 imageON = ImageCache.loadBufferedImage(ActionReceiverTrayApp.class
00146 .getResource("/icons/planet.png"));
00147 imageOFF = ImageCache.loadBufferedImage(ActionReceiverTrayApp.class
00148 .getResource("/icons/planetOff.png"));
00149
00150
00151 currentStatus = STATUS_OFF;
00152
00153
00154 trayIcon = new TrayIcon(imageOFF, DESCRIPTION + currentStatus, getPopupMenu());
00155 trayIcon.setImageAutoSize(true);
00156 trayIcon.addActionListener(getToggleServerStateListener());
00157
00158 try {
00159 SystemTray.getSystemTray().add(trayIcon);
00160 } catch (AWTException e) {
00161 e.printStackTrace();
00162 }
00163
00164
00165 trustedClientsFrame = new JFrame("Action Receiver Application");
00166 trustedClientsFrame.setContentPane(getMainPanel());
00167 trustedClientsFrame.pack();
00168 trustedClientsFrame.setLocation(WindowUtils.getWindowOrigin(trustedClientsFrame,
00169 WindowUtils.DESKTOP_CENTER));
00170 trustedClientsFrame.setVisible(true);
00171 }
00172
00173 private ActionReceiverConnectionListener getConnectionListener() {
00174 return new ActionReceiverConnectionListener() {
00175 public void newConnectionFrom(String hostName, String ipAddr) {
00176 if (setShowConnectionMessageItem.getState()) {
00177 trayIcon.displayMessage("New Connection", hostName + ipAddr + " has connected.",
00178 TrayIcon.MessageType.INFO);
00179 }
00180 }
00181 };
00182 }
00183
00187 private ActionListener getExitListener() {
00188 return new ActionListener() {
00189 public void actionPerformed(ActionEvent ae) {
00190 System.out.println("Exiting the Action Receiver Tray App...");
00191 SystemTray.getSystemTray().remove(trayIcon);
00192 System.exit(0);
00193 }
00194 };
00195 }
00196
00202 private JPanel getMainPanel() {
00203 final JPanel mainPanel = new JPanel();
00204 mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
00205 mainPanel.setLayout(new BorderLayout());
00206
00207
00208 trustedClientsTextField = new SuperJTextField("localhost", 30);
00209 trustedClientsTextField.addActionListener(new ActionListener() {
00210 public void actionPerformed(ActionEvent ae) {
00211 trustedClientsFrame.setVisible(false);
00212 }
00213 });
00214 trustedClientsTextField.setBorder(BorderFactory.createCompoundBorder(trustedClientsTextField
00215 .getBorder(), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
00216
00217
00218 final JLabel message = new JLabel(DIRECTIONS_FOR_SETTING_LIST_OF_TRUSTED_CLIENTS);
00219 message.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));
00220 message.setFont(new Font("Tahoma", Font.PLAIN, 16));
00221
00222 final JPanel controls = new JPanel();
00223 controls.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
00224 controls.setLayout(new BorderLayout());
00225 JButton hideButton = new JButton("Start Running and Minimize to the Tray");
00226 hideButton.addActionListener(new ActionListener() {
00227 public void actionPerformed(ActionEvent arg0) {
00228 trustedClientsFrame.setVisible(false);
00229 startRunning();
00230 }
00231 });
00232 final JButton exitButton = new JButton("Exit the Action Receiver");
00233 exitButton.addActionListener(getExitListener());
00234 controls.add(hideButton, BorderLayout.CENTER);
00235 controls.add(exitButton, BorderLayout.EAST);
00236
00237
00238 mainPanel.add(trustedClientsTextField, BorderLayout.CENTER);
00239 mainPanel.add(message, BorderLayout.NORTH);
00240 mainPanel.add(controls, BorderLayout.SOUTH);
00241 return mainPanel;
00242 }
00243
00247 private PopupMenu getPopupMenu() {
00248 final PopupMenu popup = new PopupMenu("Action Receiver Options");
00249
00250
00251 final MenuItem exitItem = new MenuItem("Exit");
00252 exitItem.addActionListener(getExitListener());
00253
00254
00255 onOffItem = new MenuItem(START_MSG);
00256 onOffItem.addActionListener(getToggleServerStateListener());
00257
00258
00259 final MenuItem setTrustedClientsItem = new MenuItem("Set Trusted Clients");
00260 setTrustedClientsItem.addActionListener(new ActionListener() {
00261 public void actionPerformed(ActionEvent ae) {
00262 trustedClientsFrame.setVisible(true);
00263 }
00264 });
00265
00266 setShowConnectionMessageItem = new CheckboxMenuItem("Show Message When Clients Connect");
00267
00268 popup.add(setTrustedClientsItem);
00269 popup.add(onOffItem);
00270 popup.add(setShowConnectionMessageItem);
00271 popup.add(new MenuItem("-"));
00272 popup.add(exitItem);
00273
00274 return popup;
00275 }
00276
00281 private ActionListener getToggleServerStateListener() {
00282 if (iconListener == null) {
00283 iconListener = new ActionListener() {
00284 public void actionPerformed(ActionEvent ae) {
00285 if (receiverRunning) {
00286 trayIcon.displayMessage("Action Receiver is Offline",
00287 "Not listening for new actions.", TrayIcon.MessageType.INFO);
00288 actionReceiver.stopDaemon();
00289 currentStatus = STATUS_OFF;
00290 trayIcon.setImage(imageOFF);
00291 onOffItem.setLabel(START_MSG);
00292 receiverRunning = false;
00293 } else {
00294 startRunning();
00295 }
00296 trayIcon.setToolTip(DESCRIPTION + currentStatus);
00297 }
00298
00299 };
00300 }
00301 return iconListener;
00302 }
00303
00307 private void startRunning() {
00308 String trustedClientsList = trustedClientsTextField.getText();
00309 String[] clientNames = trustedClientsList.split(",");
00310 for (int i = 0; i < clientNames.length; i++) {
00311 clientNames[i] = clientNames[i].trim();
00312 }
00313
00314 actionReceiver = new ActionReceiver(ActionReceiver.DEFAULT_JAVA_PORT, ClientServerType.JAVA,
00315 clientNames);
00316
00317 actionReceiver.setConnectionListener(getConnectionListener());
00318
00319
00320 actionReceiver.addActionHandler(new ActionHandler());
00321
00322 final String hostAddress = actionReceiver.getHostAddress();
00323 final String hostName = actionReceiver.getHostName();
00324
00325
00326 trayIcon.displayMessage("Action Receiver is Online",
00327 "Waiting for commands. This receiver's name/address is: " + hostName + "/"
00328 + hostAddress, TrayIcon.MessageType.INFO);
00329 currentStatus = STATUS_ON;
00330 trayIcon.setImage(imageON);
00331 onOffItem.setLabel(STOP_MSG);
00332 receiverRunning = true;
00333 }
00334
00335 }