00001 package edu.stanford.hci.r3.pen.streaming;
00002
00003 import java.awt.AWTException;
00004 import java.awt.Image;
00005 import java.awt.MenuItem;
00006 import java.awt.PopupMenu;
00007 import java.awt.SystemTray;
00008 import java.awt.TrayIcon;
00009 import java.awt.event.ActionEvent;
00010 import java.awt.event.ActionListener;
00011 import java.net.InetAddress;
00012 import java.net.UnknownHostException;
00013
00014 import javax.swing.JButton;
00015 import javax.swing.JComboBox;
00016 import javax.swing.JDialog;
00017 import javax.swing.JTextField;
00018 import javax.swing.WindowConstants;
00019
00020 import com.jgoodies.forms.builder.PanelBuilder;
00021 import com.jgoodies.forms.layout.CellConstraints;
00022 import com.jgoodies.forms.layout.FormLayout;
00023
00024 import edu.stanford.hci.r3.PaperToolkit;
00025 import edu.stanford.hci.r3.config.Constants;
00026 import edu.stanford.hci.r3.util.DebugUtils;
00027 import edu.stanford.hci.r3.util.WindowUtils;
00028 import edu.stanford.hci.r3.util.communications.COMPort;
00029 import edu.stanford.hci.r3.util.graphics.ImageCache;
00030
00043 public class PenServerTrayApp {
00044
00048 private static final String START_PEN_SERVER_MSG = "Start the Pen Server";
00049
00053 private static final String STOP_PEN_SERVER_MSG = "Stop the Pen Server";
00054
00058 public static void main(String[] args) {
00059 PaperToolkit.initializeLookAndFeel();
00060
00061
00062 final JDialog dialog = new JDialog();
00063
00064 FormLayout layout = new FormLayout(
00065 "right:pref, 3dlu, pref",
00066 "p, 3dlu, p, 9dlu, p"
00067 );
00068 PanelBuilder builder = new PanelBuilder(layout);
00069 builder.setDefaultDialogBorder();
00070
00071 CellConstraints cc = new CellConstraints();
00072
00073 final JComboBox comPortComboBox = new JComboBox(COMPort.PORTS);
00074 comPortComboBox.setSelectedItem(COMPort.COM5);
00075 final JTextField serialPortTextField = new JTextField(15);
00076 serialPortTextField.setText(Constants.Ports.PEN_SERVER_JAVA + "");
00077 JButton button = new JButton("OK");
00078 button.addActionListener(new ActionListener() {
00079 @Override
00080 public void actionPerformed(ActionEvent arg0) {
00081 COMPort selectedCOMPort = (COMPort) comPortComboBox.getSelectedItem();
00082 int selectedTCPIPPort = Integer.parseInt(serialPortTextField.getText());
00083 DebugUtils.println(selectedCOMPort + " " + selectedTCPIPPort);
00084 new PenServerTrayApp(selectedCOMPort, selectedTCPIPPort);
00085 dialog.dispose();
00086 }
00087 });
00088
00089 builder.addLabel("Bluetooth COM Port (e.g., COM5)", cc.xy(1, 1));
00090 builder.add(comPortComboBox, cc.xyw(3, 1, 1));
00091
00092 builder.addLabel("Pen Server Serial Port (e.g., 11025)", cc.xy(1, 3));
00093 builder.add(serialPortTextField, cc.xyw(3, 3, 1));
00094
00095 builder.add(button, cc.xyw(1, 5, 3));
00096
00097 dialog.getContentPane().add(builder.getPanel());
00098 dialog.setTitle("Pen Server Options");
00099 dialog.pack();
00100 dialog.setLocation(WindowUtils.getWindowOrigin(dialog.getWidth(), dialog.getHeight(),
00101 WindowUtils.DESKTOP_CENTER));
00102 dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
00103 dialog.setVisible(true);
00104 }
00105
00109 private COMPort comPort;
00110
00114 private ActionListener iconListener;
00115
00119 private Image imageOFF;
00120
00124 private Image imageON;
00125
00129 private MenuItem onOffItem;
00130
00134 private boolean serverRunning;
00135
00139 private int tcpipPort;
00140
00144 private TrayIcon trayIcon;
00145
00146 public PenServerTrayApp(COMPort btDongleComPortT, int penServerTcpIpPorT) {
00147 if (!SystemTray.isSupported()) {
00148 System.err.println("The System Tray is not supported. " + "Exiting the Pen Server Tray App.");
00149 return;
00150 }
00151 final SystemTray systemTray = SystemTray.getSystemTray();
00152
00153 comPort = btDongleComPortT;
00154 tcpipPort = penServerTcpIpPorT;
00155
00156
00157 imageON = ImageCache.loadBufferedImage(PenServerTrayApp.class.getResource("/icons/sun.png"));
00158 imageOFF = ImageCache.loadBufferedImage(PenServerTrayApp.class.getResource("/icons/sunOff.png"));
00159
00160 final PopupMenu popup = new PopupMenu();
00161 final MenuItem exitItem = new MenuItem("Exit");
00162 exitItem.addActionListener(getExitListener());
00163 onOffItem = new MenuItem(STOP_PEN_SERVER_MSG);
00164 onOffItem.addActionListener(getOnOffListener());
00165 popup.add(onOffItem);
00166 popup.add(exitItem);
00167
00168 InetAddress localHost = null;
00169 try {
00170 localHost = InetAddress.getLocalHost();
00171 } catch (UnknownHostException e1) {
00172 e1.printStackTrace();
00173 }
00174
00175 final String tooltip = "Pen Server at " + localHost + "\n[double-click to turn ON/OFF]";
00176
00177 trayIcon = new TrayIcon(imageON, tooltip, popup);
00178 trayIcon.setImageAutoSize(true);
00179 trayIcon.addActionListener(getOnOffListener());
00180
00181 try {
00182 systemTray.add(trayIcon);
00183 } catch (final AWTException e) {
00184 e.printStackTrace();
00185 }
00186
00187
00188 PenServer.startJavaServer(comPort, tcpipPort);
00189 serverRunning = true;
00190 }
00191
00195 private ActionListener getExitListener() {
00196 return new ActionListener() {
00197 public void actionPerformed(ActionEvent e) {
00198 System.out.println("Exiting the Pen Server Tray App...");
00199 System.exit(0);
00200 }
00201 };
00202 }
00203
00207 private ActionListener getOnOffListener() {
00208 if (iconListener == null) {
00209 iconListener = new ActionListener() {
00210
00211 public void actionPerformed(ActionEvent ae) {
00212 if (serverRunning) {
00213 trayIcon.displayMessage("Pen is Offline", "Pen Server stopped.",
00214 TrayIcon.MessageType.INFO);
00215 PenServer.stopServers();
00216 trayIcon.setImage(imageOFF);
00217 onOffItem.setLabel(START_PEN_SERVER_MSG);
00218 serverRunning = false;
00219 } else {
00220 trayIcon.displayMessage("Pen is Online",
00221 "Server started. The pen is now in live mode.", TrayIcon.MessageType.INFO);
00222 PenServer.startJavaServer(comPort, tcpipPort);
00223 trayIcon.setImage(imageON);
00224 onOffItem.setLabel(STOP_PEN_SERVER_MSG);
00225 serverRunning = true;
00226 }
00227 }
00228 };
00229 }
00230 return iconListener;
00231 }
00232 }