Blame | Last modification | View Log | Download
/*AVRcamVIEW: A PC application to test out the functionallity of theAVRcam real-time image processing engine.Copyright (C) 2004 Brent A. TaylorThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General PublicLicense as published by the Free Software Foundation; eitherversion 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General PublicLicense along with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAFor more information on the AVRcamVIEW, please contact:taylorba@comcast.netor go to www.jrobot.net for more details regarding the system.*/package avr.swing;import java.io.*;import java.util.prefs.*;import javax.comm.*;import java.awt.*;import java.awt.event.*;import java.lang.reflect.*;import javax.swing.*;import javax.swing.event.*;import avr.connection.*;import avr.connection.event.*;import avr.device.event.*;import avr.lang.*;import avr.swing.filechooser.*;import avr.util.*;import java.beans.*;public class JAVRCamFrame extends JFrame {public static void main(String[] args) {/*try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch(Exception e) {}*/try {if(args.length == 1) {if(args[0].equals("-r")) {AVRSystem.PREFS.clear();}}} catch(BackingStoreException bse) {System.out.println("Could not clear preferences: " + bse.getMessage());}SwingUtilities.invokeLater(new Runnable() {public void run() {JFrame frame = new JAVRCamFrame();frame.setVisible(true);}});}private static final String COLOR_MAP_BOUNDS_KEY = "avr.colormap.bounds";private static final String COLOR_MAP_SHOWING_KEY = "avr.colormap.showing";private static final String COM_PORT_KEY = "avr.com.port";private static final String COM_PARAMS_KEY = "avr.com.params";private static final String DEVICE_CONNECTED_KEY = "avr.device.connected";private static final String FRAME_BOUNDS_KEY = "avr.frame.bounds";private static final String LOG_BOUNDS_KEY = "avr.log.bounds";private static final String LOG_SHOWING_KEY = "avr.log.showing";private static final String MESSAGE_SHOWING_KEY = "avr.message.showing";private JFrame logF;private JSerialPanel serialP;private JRegisterPanel registersP;private JMessagePanel messageP;private JColorMapInterface colorMapP;private JFrame colorMapF;private JMenu windowM;private JDesktopPane desktop;private JTrackingInternalFrame trackingF;private CaptureInternalFrameHandler captureInternalFrameHandler;private AbstractButton viewLogB;private AbstractButton viewMessagesB;private AbstractButton viewColorMapB;private AbstractButton trackingB;private AbstractButton passiveTrackingB;private ProxyAction connectAction;private ProxyAction disconnectAction;private ProxyAction serialParamsAction;private ProxyAction setRegistersAction;private ProxyAction pingAction;private ProxyAction resetAction;private ProxyAction captureAction;private ProxyAction trackingAction;private ProxyAction passiveTrackingAction;private ProxyAction cascadeAction;private ProxyAction tileHorizontalAction;private ProxyAction tileVerticalAction;private ProxyAction resetAllAction;private ProxyAction closeAllAction;private ButtonGroup windowBG;public JAVRCamFrame() {super("AVRcamVIEW");createActions();windowBG = new ButtonGroup();captureInternalFrameHandler = new CaptureInternalFrameHandler();// ImageIcon icon = new ImageIcon(getClass().getClassLoader().getResource("avr/resource/AVRcam.gif"));// if(icon != null) {// this.setIconImage(icon.getImage());// }serialP = new JSerialPanel();registersP = new JRegisterPanel();messageP = new JMessagePanel();String classVersionString = System.getProperty("java.class.version","44.0");int classVersion = (int)(Double.parseDouble(classVersionString) * 10.0);// JDK 5.0 class version is 49.0. Since the JNewColorMapPanel requires JDK 5.0// this will check to make sure that the JVM is 5.0 or better, Otherwise, use// the old color map.if(System.getProperty("avr.old.color.map") != null || classVersion < 490) {colorMapP = new JColorMapPanel(messageP);} else {try {// must load the class using reflection so that the 1.4 compiler does not try// to compile the JNewColorMapPanel classConstructor constructor = Class.forName("avr.swing.JNewColorMapPanel").getConstructor(new Class[] { JMessagePanel.class });colorMapP = (JColorMapInterface)constructor.newInstance(new Object[] {messageP});// colorMapP = new JNewColorMapPanel(messageP);} catch(Exception ex) {// we can't load the new color map, so default to the old one.colorMapP = new JColorMapPanel(messageP);ex.printStackTrace(System.err);}}messageP.addComponentListener(new MessagePanelHandler());Dimension screen = getToolkit().getScreenSize();Rectangle bounds = null;JLogApplet logA = new JLogApplet();logA.init(false);AVRSystem.LOG.addHandler(new LogHandler(logA.getTableModel(), AVRSystem.LOG.getLevel()));logF = logA.createFrame();bounds = getBounds(LOG_BOUNDS_KEY);if(bounds == null) {bounds = new Rectangle(0, 0, screen.width * 3 / 4, screen.height / 2);}logF.setBounds(bounds);desktop = new JDesktopPane();desktop.setBackground(new Color(0x005C5C));// desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);desktop.addMouseListener(new PopupHandler());setJMenuBar(createMenuBar());getContentPane().add(createToolBar(), BorderLayout.NORTH);getContentPane().add(desktop, BorderLayout.CENTER);getContentPane().add(messageP, BorderLayout.EAST);bounds = getBounds(FRAME_BOUNDS_KEY);if(bounds == null) {bounds = new Rectangle(screen.width / 8, screen.height / 8,screen.width * 3 / 4, screen.height * 3 / 4);}setBounds(bounds);colorMapF = new JFrame("AVRcamVIEW - Color Map");colorMapF.addWindowListener(new ColorMapWindowHandler(colorMapF, viewColorMapB));colorMapF.getContentPane().add(colorMapP, BorderLayout.CENTER);colorMapF.pack();colorMapF.setResizable(false);bounds = getBounds(COLOR_MAP_BOUNDS_KEY);if(bounds == null) {Dimension dim = colorMapF.getSize();bounds = new Rectangle((screen.width - dim.width) / 2,(screen.height - dim.height) / 2,dim.width, dim.height);}colorMapF.setLocation(bounds.x, bounds.y);colorMapF.pack();addWindowListener(new WindowHandler(this));logF.addWindowListener(new LogWindowHandler(viewLogB));Action action = new ProxyAction(AVRSystem.DEVICE, "simulateNCK", "Simulate NCK");registerKeyStrokeAction(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK),action);action = new ProxyAction(AVRSystem.DEVICE, "simulateACK", "Simulate ACK");registerKeyStrokeAction(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK),action);resetAction = new ProxyAction(this, "reset", "Reset");// registerKeyStrokeAction(// KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK),// resetAction);SwingUtilities.invokeLater(new Startup());}private void registerKeyStrokeAction(KeyStroke keyStroke, Action action) {// attach the action to the Ctrl+A keygetRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keyStroke, action.getValue(Action.NAME));getRootPane().getActionMap().put(action.getValue(Action.NAME), action);}private void createActions() {serialParamsAction = new ProxyAction(this, "showSerialDialog", "Configure Serial", 'S');setRegistersAction = new ProxyAction(this, "showRegisterDialog", "Set Registers", 'R');connectAction = new ProxyAction(this, "connect", "Connect", 'C');disconnectAction = new ProxyAction(this, "disconnect", "Disconnect", 'D');pingAction = new ProxyAction(this, "ping", "Ping", 'P');pingAction.setEnabled(false);// resetAction = new ProxyAction(this, "reset", "Reset", 'R');captureAction = new ProxyAction(this, "capture", "Capture", 'C');trackingAction = new ProxyAction(this, "tracking", "Enable Tracking", 'E');passiveTrackingAction = new ProxyAction(this, "passiveTracking", "Enable Passive Tracking", 'V');cascadeAction = new ProxyAction(this, "cascadeWindows", "Cascade", 'C');tileHorizontalAction = new ProxyAction(this, "tileHorizontal", "Tile Horizontal", 'H');tileVerticalAction = new ProxyAction(this, "tileVertical", "Tile Vertical", 'V');resetAllAction = new ProxyAction(this, "resetAllWindows", "Reset All", 'R');closeAllAction = new ProxyAction(this, "closeAllWindows", "Close All", 'L');// resetAction.setEnabled(false);setRegistersAction.setEnabled(false);captureAction.setEnabled(false);disconnectAction.setEnabled(false);trackingAction.setEnabled(false);passiveTrackingAction.setEnabled(false);trackingB = new JToggleButton(trackingAction);passiveTrackingB = new JToggleButton(passiveTrackingAction);serialParamsAction.setToolTipText("Modify the Serial Port Parameters");setRegistersAction.setToolTipText("Modify the AVRcam Register values");connectAction.setToolTipText("Open the Serial Connection to the AVRcam");disconnectAction.setToolTipText("Close the Serial Connection to the AVRcam");pingAction.setToolTipText("Send a Ping ccommand to the AVRcam");captureAction.setToolTipText("Capture a image from the AVRcam");trackingAction.setToolTipText("Command the AVRcam to start tracking");passiveTrackingAction.setToolTipText("Receive tracking packets from the AVRcam");}private JMenuBar createMenuBar() {JMenuBar menubar = new JMenuBar();JMenu fileM = new JMenu("File");JMenu viewM = new JMenu("View");JMenu deviceM = new JMenu("Device");JMenu helpM = new JMenu("Help");windowM = new JMenu("Window");fileM.setMnemonic('f');viewM.setMnemonic('v');deviceM.setMnemonic('d');windowM.setMnemonic('w');helpM.setMnemonic('h');fileM.add(new ProxyAction(this, "openBayer", "Open Bayer Image", 'B'));fileM.add(new ProxyAction(this, "openTracking", "Open Tracking Data", 'T'));fileM.addSeparator();fileM.add(serialParamsAction);fileM.add(setRegistersAction);fileM.addSeparator();fileM.add(new ProxyAction(this, "close", "Exit", 'X'));viewColorMapB = new JCheckBoxMenuItem(new ProxyAction(this, "viewColorMap", true, "Show Color Map", 'C'));viewM.add(viewColorMapB);viewMessagesB = new JCheckBoxMenuItem(new ProxyAction(this, "viewMessages", true, "Show Messages", 'M'));viewM.add(viewMessagesB);viewLogB = new JCheckBoxMenuItem(new ProxyAction(this, "viewLog", true, "Show Log", 'L'));viewM.add(viewLogB);deviceM.add(connectAction);deviceM.add(disconnectAction);windowM.add(cascadeAction);windowM.add(tileHorizontalAction);windowM.add(tileVerticalAction);windowM.add(resetAllAction);windowM.add(closeAllAction);windowM.addSeparator();helpM.add(new ProxyAction(this, "about", "About", 'A'));menubar.add(fileM);menubar.add(viewM);menubar.add(deviceM);menubar.add(windowM);menubar.add(helpM);return menubar;}private JToolBar createToolBar() {JToolBar toolbar = new JToolBar();toolbar.add(connectAction);toolbar.add(disconnectAction);toolbar.addSeparator();toolbar.add(serialParamsAction);toolbar.add(setRegistersAction);toolbar.addSeparator();toolbar.add(pingAction);// toolbar.add(resetAction);toolbar.add(captureAction);toolbar.add(trackingB);toolbar.add(passiveTrackingB);toolbar.setFloatable(false);return toolbar;}private static Rectangle getBounds(String key) {byte[] boundsArray = AVRSystem.PREFS.getByteArray(key, null);Rectangle bounds = null;if(boundsArray != null) {try {ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(boundsArray));bounds = (Rectangle)in.readObject();in.close();} catch(ClassNotFoundException ex) {} catch(IOException ex) {}}return bounds;}protected JRootPane createRootPane() {// create a new JRootPaneJRootPane rootPane = new JRootPane() {/*** Create a new Glass Pane Glass Pane that when visible it captures* all the mouse events, plays a "beep" when the mouse is clicked* when the Glass Pane is visible, and changes the mouse depending* on if the Glass Pane is visible or not.* @return The Glass Pane*/protected Component createGlassPane() {JComponent c = new JPanel() {/*** Overridden to change the cursor to a busy cursor when visible* and a default cursor when not visible.* @param visible True to show the Glass Pane, false to not* show the Glass Pane.*/public void setVisible(boolean visible) {super.setVisible(visible);if(visible) {// this is possible if it this panel has not been added// to a JRootPane yetif(getRootPane() != null) {// change the cursor to a wait/busy cursor (hour glass)getRootPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));AVRSystem.LOG.finest("Glass Pane SHOWING... ");}} else {// this is possible if it this panel has not been added// to a JRootPane yetif(getRootPane() != null) {// chage the cursor back to the default cursorgetRootPane().setCursor(Cursor.getDefaultCursor());AVRSystem.LOG.finest("Glass Pane HIDDEN... ");}}}};c.setName(this.getName() + ".glassPane");c.setVisible(false);((JPanel)c).setOpaque(false);// add a mouse listener to capture all the mouse events and play// a "beep" when the mouse is pressed.c.addMouseListener(new MouseAdapter() {public void mousePressed(MouseEvent me) {Toolkit.getDefaultToolkit().beep();}});return c;}};rootPane.setOpaque(true);return rootPane;}public void openBayer() {javax.swing.filechooser.FileFilter[] filters = AVRSystem.FILE_CHOOSER.getChoosableFileFilters();for(int i = 0; i < filters.length; i++) {AVRSystem.FILE_CHOOSER.removeChoosableFileFilter(filters[i]);}AVRSystem.FILE_CHOOSER.addChoosableFileFilter(new LogFileFilter("Bayer Image File (*.byr)", ".byr"));int option = AVRSystem.FILE_CHOOSER.showOpenDialog(getRootPane());if(option == JFileChooser.APPROVE_OPTION) {JInternalFrame iFrame = new JCaptureInternalFrame(messageP, colorMapP, AVRSystem.FILE_CHOOSER.getSelectedFile());iFrame.pack();iFrame.setLocation(10, 10);desktop.add(iFrame);iFrame.setVisible(true);}}public void openTracking() {javax.swing.filechooser.FileFilter[] filters = AVRSystem.FILE_CHOOSER.getChoosableFileFilters();for(int i = 0; i < filters.length; i++) {AVRSystem.FILE_CHOOSER.removeChoosableFileFilter(filters[i]);}AVRSystem.FILE_CHOOSER.addChoosableFileFilter(new LogFileFilter("AVR Tracking File (*.trk)", ".trk"));int option = AVRSystem.FILE_CHOOSER.showOpenDialog(getRootPane());if(option == JFileChooser.APPROVE_OPTION) {try {JInternalFrame iFrame = new JTrackingInternalFrame(AVRSystem.FILE_CHOOSER.getSelectedFile());iFrame.pack();iFrame.setLocation(10, 10);desktop.add(iFrame);iFrame.setVisible(true);} catch(FileNotFoundException fnfe) {JOptionPane.showMessageDialog(getRootPane(), "File Not Found", fnfe.getMessage(), JOptionPane.ERROR_MESSAGE);} catch(IOException ioe) {JOptionPane.showMessageDialog(getRootPane(), "I/O Exception", ioe.getMessage(), JOptionPane.ERROR_MESSAGE);}}}public void showSerialDialog() {if(AVRSystem.DEVICE.getConnection() != null) {showSerialDialog(((SerialConnection)AVRSystem.DEVICE.getConnection()).getSerialParams());} else {showSerialDialog(null);}}public void showSerialDialog(SerialParams params) {int option = serialP.showDialog(this, params);if(option == JSerialPanel.OK_OPTION) {try {if(AVRSystem.DEVICE.isConnected()) {((SerialConnection)AVRSystem.DEVICE.getConnection()).setSerialParams(serialP.getSerialParameters());}saveConnectionPrefs(null, serialP.getSerialParameters());} catch(UnsupportedCommOperationException ucoe) {AVRSystem.LOG.severe(ucoe.getMessage());}}}public void showRegisterDialog() {int option = registersP.showDialog(this);if(option == JRegisterPanel.OK_OPTION && registersP.getRegisters().size() > 0) {DataListener handler = null;try {handler = new SetRegistersHandler();AVRSystem.DEVICE.addDataListener(handler);getRootPane().getGlassPane().setVisible(true);AVRSystem.DEVICE.sendSetRegisters(registersP.getRegisters());messageP.append("Set Registers");} catch(IOException ioe) {AVRSystem.DEVICE.removeDataListener(handler);getRootPane().getGlassPane().setVisible(false);AVRSystem.LOG.severe(ioe.getMessage());messageP.append("Set Registers not sent");}}}public void close() {AVRSystem.PREFS.putBoolean(DEVICE_CONNECTED_KEY, AVRSystem.DEVICE.isConnected());if(AVRSystem.DEVICE.isConnected()) {saveConnectionPrefs((SerialConnection)AVRSystem.DEVICE.getConnection());disconnect();}AVRSystem.PREFS.putBoolean(LOG_SHOWING_KEY, logF.isVisible());AVRSystem.PREFS.putBoolean(MESSAGE_SHOWING_KEY, messageP.isVisible());AVRSystem.PREFS.putBoolean(COLOR_MAP_SHOWING_KEY, colorMapF.isVisible());saveBounds(FRAME_BOUNDS_KEY, getBounds());saveBounds(COLOR_MAP_BOUNDS_KEY, colorMapF.getBounds());saveBounds(LOG_BOUNDS_KEY, logF.getBounds());System.exit(0);}private static void saveConnectionPrefs(SerialConnection con) {saveConnectionPrefs(con.getComPort(), con.getSerialParams());}private static void saveConnectionPrefs(String comPort, SerialParams params) {if(comPort != null) {AVRSystem.PREFS.put(COM_PORT_KEY, comPort);}try {ByteArrayOutputStream out = new ByteArrayOutputStream();ObjectOutputStream oOut = new ObjectOutputStream(out);oOut.writeObject(params);oOut.close();byte[] serialParams = out.toByteArray();AVRSystem.PREFS.putByteArray(COM_PARAMS_KEY, serialParams);} catch(IOException ioe) {ioe.printStackTrace();AVRSystem.LOG.warning("Could not save serial parameters: " + ioe.getMessage());}}private static void saveBounds(String key, Rectangle rect) {try {ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();ObjectOutputStream out = new ObjectOutputStream(arrayOut);out.writeObject(rect);out.close();AVRSystem.PREFS.putByteArray(key, arrayOut.toByteArray());} catch(IOException ex) {}}public void viewColorMap(ActionEvent ae) {colorMapF.setVisible(((AbstractButton)ae.getSource()).isSelected());}public void viewLog(ActionEvent ae) {logF.setVisible(((AbstractButton)ae.getSource()).isSelected());}public void viewMessages(ActionEvent ae) {messageP.setVisible(((AbstractButton)ae.getSource()).isSelected());}public void connect() {String[] ports = SerialConnection.getSerialPorts();if(ports.length > 0) {Object option = JOptionPane.showInputDialog(this, "Select a COM Port:", "Serial Port",JOptionPane.QUESTION_MESSAGE,null,ports,AVRSystem.PREFS.get(COM_PORT_KEY, ports[0]));if(option != null) {connect(option.toString(), serialP.getSerialParameters());}} else {JOptionPane.showMessageDialog(this, "No Serial Ports Available", "No Serial Ports",JOptionPane.ERROR_MESSAGE);}}public void connect(String comPort, SerialParams params) {SerialConnection con = new SerialConnection(comPort, params);AVRSystem.DEVICE.setConnection(con);AVRSystem.DEVICE.addConnectionListener(new ConnectionHandler());try {AVRSystem.DEVICE.connect();} catch(Exception ioe) {JOptionPane.showMessageDialog(getRootPane(),ioe.getMessage(),"Connect Error",JOptionPane.ERROR_MESSAGE);AVRSystem.LOG.severe(ioe.getMessage());}}public void disconnect() {AVRSystem.DEVICE.disconnect();}public void ping() {DataListener handler = null;try {handler = new PingHandler();AVRSystem.DEVICE.addDataListener(handler);getRootPane().getGlassPane().setVisible(true);AVRSystem.DEVICE.sendPing();messageP.append("Ping");} catch(IOException ioe) {AVRSystem.DEVICE.removeDataListener(handler);getRootPane().getGlassPane().setVisible(false);AVRSystem.LOG.severe(ioe.getMessage());messageP.append("Ping not sent: " + ioe.getMessage());}}public void reset() {DataListener handler = null;try {handler = new ResetHandler();AVRSystem.DEVICE.addDataListener(handler);getRootPane().getGlassPane().setVisible(true);AVRSystem.DEVICE.sendReset();messageP.append("Reset");} catch(IOException ioe) {AVRSystem.DEVICE.removeDataListener(handler);getRootPane().getGlassPane().setVisible(false);AVRSystem.LOG.severe(ioe.getMessage());messageP.append("Reset not sent");}}public void capture() {JCaptureInternalFrame captureF = new JCaptureInternalFrame(messageP, colorMapP);Insets insets = captureF.getInsets();captureF.pack();int frameCount = desktop.getAllFrames().length;captureF.setLocation(10 * frameCount, 10 * frameCount);captureF.addInternalFrameListener(captureInternalFrameHandler);desktop.add(captureF);captureF.setVisible(true);}public void tracking() {if(trackingB.isSelected()) {enableTracking();} else {disableTracking();}}private void enableTracking() {DataListener handler = new TrackingHandler();try {AVRSystem.DEVICE.addDataListener(handler);AVRSystem.DEVICE.sendEnableTracking();messageP.append("Enable Tracking");} catch(IOException ioe) {AVRSystem.DEVICE.removeDataListener(handler);AVRSystem.LOG.severe(ioe.getMessage());messageP.append("Enable Tracking not sent");}}private void disableTracking() {DataListener handler = new TrackingHandler();try {AVRSystem.DEVICE.addDataListener(handler);AVRSystem.DEVICE.sendDisableTracking();messageP.append("Disable Tracking");} catch(IOException ioe) {AVRSystem.DEVICE.removeDataListener(handler);AVRSystem.LOG.severe(ioe.getMessage());messageP.append("Disable Tracking not sent");}}public void passiveTracking() {if(passiveTrackingB.isSelected()) {passiveTrackingB.setText("Disable Passive Tracking");disconnectAction.setEnabled(false);serialParamsAction.setEnabled(false);setRegistersAction.setEnabled(false);pingAction.setEnabled(false);resetAction.setEnabled(false);captureAction.setEnabled(false);trackingAction.setEnabled(false);trackingF = new JTrackingInternalFrame();Insets insets = trackingF.getInsets();trackingF.pack();trackingF.setLocation(10, 10);desktop.add(trackingF);trackingF.setVisible(true);trackingF.startTracking();messageP.append("Enable Passive Tracking");} else {passiveTrackingB.setText("Enable Passive Tracking");disconnectAction.setEnabled(true);serialParamsAction.setEnabled(true);setRegistersAction.setEnabled(true);pingAction.setEnabled(true);resetAction.setEnabled(true);captureAction.setEnabled(true);trackingAction.setEnabled(true);trackingF.stopTracking();desktop.getDesktopManager().closeFrame(trackingF);messageP.append("Disable Passive Tracking");}}public void activateWindow(ActionEvent event) {JInternalFrame[] frames = desktop.getAllFrames();for(int i = 0; i < frames.length; i++) {if(frames[i].getTitle().equals(event.getActionCommand())) {desktop.getDesktopManager().activateFrame(frames[i]);desktop.setSelectedFrame(frames[i]);frames[i].toFront();try {frames[i].setSelected(true);} catch(PropertyVetoException ex) {ex.printStackTrace(System.out);AVRSystem.LOG.severe(ex.getMessage());}break;}}}public void cascadeWindows() {int x = 0;int y = 0;JInternalFrame[] frames = desktop.getAllFrames();for(int i = 0; i < frames.length; i++) {frames[i].setLocation(x, y);x += 30;y += 30;}}public void tileHorizontal() {JInternalFrame[] frames = desktop.getAllFrames();int frameCount = frames.length;int nrows = 1;int ncols = (frameCount + nrows - 1) / nrows;if(frameCount == 0) {return;}int w = desktop.getWidth();int h = desktop.getHeight();w = (w - (ncols - 1)) / ncols;h = (h - (nrows - 1)) / nrows;for(int c = 0, x = 0; c < ncols; c++, x += w) {for(int r = 0, y = 0; r < nrows; r++, y += h) {int i = r * ncols + c;if(i < frameCount) {frames[i].setBounds(x, y, w, h);}}}}public void tileVertical() {JInternalFrame[] frames = desktop.getAllFrames();int frameCount = frames.length;int ncols = 1;int nrows = (frameCount + ncols - 1) / ncols;;if(frameCount == 0) {return;}int w = desktop.getWidth();int h = desktop.getHeight();w = (w - (ncols - 1)) / ncols;h = (h - (nrows - 1)) / nrows;for(int c = 0, x = 0; c < ncols; c++, x += w) {for(int r = 0, y = 0; r < nrows; r++, y += h) {int i = r * ncols + c;if(i < frameCount) {frames[i].setBounds(x, y, w, h);}}}}public void resetAllWindows() {JInternalFrame[] frames = desktop.getAllFrames();for(int i = 0; i < frames.length; i++) {frames[i].pack();}}public void closeAllWindows() {JInternalFrame[] frames = desktop.getAllFrames();for(int i = 0; i < frames.length; i++) {if(frames[i] != trackingF) {desktop.getDesktopManager().closeFrame(frames[i]);}}}public void about() {new JAboutDialog(this, messageP).showDialog();}private final class SetRegistersHandler extends DataAdapter {public void ack() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);}public void nck() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Set Register NCK Received", "NCK Received", JOptionPane.ERROR_MESSAGE);}public void responseTimerExpired() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Response Timer Expired", "Timer Expired", JOptionPane.ERROR_MESSAGE);}}private final class CaptureInternalFrameHandler implements InternalFrameListener {public void internalFrameOpened(InternalFrameEvent e) {String title = e.getInternalFrame().getTitle();JCheckBoxMenuItem windowMI = new JCheckBoxMenuItem(new ProxyAction(JAVRCamFrame.this, "activateWindow", true, title));windowMI.setActionCommand(title);windowBG.add(windowMI);windowMI.setSelected(true);windowM.add(windowMI);}public void internalFrameClosing(InternalFrameEvent e) {}public void internalFrameClosed(InternalFrameEvent e) {String text = null;String title = e.getInternalFrame().getTitle();for(int i = 0; i < windowM.getItemCount(); i++) {// need to check for the separatorif(windowM.getItem(i) != null) {text = windowM.getItem(i).getText();if((text != null) && (title != null) &&(text.equals(title))) {windowM.remove(i);break;}}}}public void internalFrameIconified(InternalFrameEvent e) {}public void internalFrameDeiconified(InternalFrameEvent e) {}public void internalFrameActivated(InternalFrameEvent e) {}public void internalFrameDeactivated(InternalFrameEvent e) {}}private final class PingHandler extends DataAdapter {public void ack() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);}public void nck() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Ping NCK Received", "NCK Received", JOptionPane.ERROR_MESSAGE);}public void responseTimerExpired() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Response Timer Expired", "Timer Expired", JOptionPane.ERROR_MESSAGE);}}private final class ResetHandler extends DataAdapter {public void ack() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);}public void nck() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Reset NCK Received", "NCK Received", JOptionPane.ERROR_MESSAGE);}public void responseTimerExpired() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Response Timer Expired", "Timer Expired", JOptionPane.ERROR_MESSAGE);}}private final class TrackingHandler extends DataAdapter {public void ack() {AVRSystem.DEVICE.removeDataListener(this);if(trackingB.isSelected()) {trackingB.setText("Disable Tracking");disconnectAction.setEnabled(false);serialParamsAction.setEnabled(false);setRegistersAction.setEnabled(false);pingAction.setEnabled(false);resetAction.setEnabled(false);captureAction.setEnabled(false);passiveTrackingAction.setEnabled(false);trackingF = new JTrackingInternalFrame();Insets insets = trackingF.getInsets();trackingF.pack();trackingF.setLocation(10, 10);desktop.add(trackingF);trackingF.setVisible(true);trackingF.startTracking();} else {trackingB.setText("Enable Tracking");disconnectAction.setEnabled(true);serialParamsAction.setEnabled(true);setRegistersAction.setEnabled(true);pingAction.setEnabled(true);resetAction.setEnabled(true);captureAction.setEnabled(true);passiveTrackingAction.setEnabled(true);trackingF.stopTracking();desktop.getDesktopManager().closeFrame(trackingF);}}public void nck() {AVRSystem.DEVICE.removeDataListener(this);if(trackingB.isSelected()) {trackingB.setSelected(false);} else {trackingB.setSelected(true);}JOptionPane.showMessageDialog(JAVRCamFrame.this, "Disable Tracking NCK Received", "NCK Received", JOptionPane.ERROR_MESSAGE);}public void responseTimerExpired() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);if(trackingB.isSelected()) {trackingB.setSelected(false);} else {trackingB.setSelected(true);}JOptionPane.showMessageDialog(JAVRCamFrame.this, "Response Timer Expired", "Timer Expired", JOptionPane.ERROR_MESSAGE);}}private final class Startup implements Runnable {public void run() {boolean logVisible = AVRSystem.PREFS.getBoolean(LOG_SHOWING_KEY, false);logF.setVisible(logVisible);viewLogB.setSelected(logVisible);boolean messagesVisible = AVRSystem.PREFS.getBoolean(MESSAGE_SHOWING_KEY, true);messageP.setVisible(messagesVisible);viewMessagesB.setSelected(messagesVisible);boolean colorMapVisible = AVRSystem.PREFS.getBoolean(COLOR_MAP_SHOWING_KEY, false);viewColorMapB.setSelected(colorMapVisible);if(colorMapVisible) {viewColorMap(new ActionEvent(viewColorMapB, ActionEvent.ACTION_PERFORMED, viewColorMapB.getText()));}try {String comPort = AVRSystem.PREFS.get(COM_PORT_KEY, "COM1");byte[] serialParams = AVRSystem.PREFS.getByteArray(COM_PARAMS_KEY, null);AVRSystem.LOG.config("Prefs Com Port: " + comPort);SerialParams params = null;if(serialParams != null) {ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serialParams));params = (SerialParams)in.readObject();in.close();AVRSystem.LOG.config("Prefs Com Params: " + params);if(AVRSystem.PREFS.getBoolean(DEVICE_CONNECTED_KEY, false)) {connect(comPort, params);}}} catch(Exception e) {e.printStackTrace();AVRSystem.LOG.warning("Could not read serial params: " + e.getMessage());}}}private final class ConnectionHandler extends DataAdapter implements ConnectionListener {public void connected(ConnectionEvent ce) {SerialConnection con = (SerialConnection)ce.getSource();saveConnectionPrefs(con.getComPort(), con.getSerialParams());try {AVRSystem.DEVICE.addDataListener(this);getRootPane().getGlassPane().setVisible(true);AVRSystem.DEVICE.sendPing();messageP.append("Ping");} catch(IOException ioe) {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);AVRSystem.LOG.severe(ioe.getMessage());messageP.append("Ping not sent: " + ioe.getMessage());}}public void ack() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);enableButtons(true);}public void nck() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);enableButtons(true);JOptionPane.showMessageDialog(JAVRCamFrame.this, "Ping NCK Received", "NCK Received", JOptionPane.ERROR_MESSAGE);}public void responseTimerExpired() {AVRSystem.DEVICE.removeDataListener(this);getRootPane().getGlassPane().setVisible(false);disconnect();JOptionPane.showMessageDialog(JAVRCamFrame.this, "Response Timer Expired: Please connect the serial port to the computer and make sure the AVRcam is powered.", "Timer Expired", JOptionPane.ERROR_MESSAGE);}public void disconnected(ConnectionEvent ce) {AVRSystem.DEVICE.removeConnectionListener(this);enableButtons(false);}private void enableButtons(boolean enabled) {connectAction.setEnabled(!enabled);disconnectAction.setEnabled(enabled);setRegistersAction.setEnabled(enabled);pingAction.setEnabled(enabled);resetAction.setEnabled(enabled);captureAction.setEnabled(enabled);trackingAction.setEnabled(enabled);passiveTrackingAction.setEnabled(enabled);}}private final class MessagePanelHandler extends ComponentAdapter {public void componentHidden(ComponentEvent e) {viewMessagesB.setSelected(false);}}private final class PopupHandler extends MouseAdapter {private JPopupMenu popup;public void mouseReleased(MouseEvent event) {if(SwingUtilities.isRightMouseButton(event)) {if(popup == null) {popup = new JPopupMenu();popup.add(cascadeAction);popup.add(tileHorizontalAction);popup.add(tileVerticalAction);popup.add(resetAllAction);popup.add(closeAllAction);popup.setInvoker(event.getComponent());}popup.show(event.getComponent(), event.getX(), event.getY());}}}private final static class ColorMapWindowHandler extends WindowAdapter {private JFrame frame;private AbstractButton viewB;public ColorMapWindowHandler(JFrame frame, AbstractButton viewB) {this.frame = frame;this.viewB = viewB;}public void windowClosed(WindowEvent we) {viewB.setSelected(false);}public void windowClosing(WindowEvent we) {frame.dispose();}}private final static class WindowHandler extends WindowAdapter {private JAVRCamFrame frame;public WindowHandler(JAVRCamFrame frame) {this.frame = frame;}public void windowClosing(WindowEvent we) {frame.dispose();}public void windowClosed(WindowEvent we) {frame.close();}}private final static class LogWindowHandler extends WindowAdapter {private AbstractButton button;public LogWindowHandler(AbstractButton button) {this.button = button;}public void windowClosing(WindowEvent we) {button.setSelected(false);}}}