From d2f7f62a34d50363f0a4135d048a3cc468165ea5 Mon Sep 17 00:00:00 2001 From: nifi Date: Tue, 12 Oct 2010 16:28:19 +0000 Subject: [PATCH] Added quick start help text, added explicit save settings in menu, fixed bug in the background image selection. --- .../sics/contiki/collect/CollectServer.java | 115 ++++++++++++------ .../sics/contiki/collect/gui/NodeControl.java | 93 ++++++++++---- 2 files changed, 147 insertions(+), 61 deletions(-) diff --git a/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java b/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java index 435ed1aa5..8c4cb13f3 100644 --- a/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java +++ b/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: CollectServer.java,v 1.26 2010/10/12 11:38:34 adamdunkels Exp $ + * $Id: CollectServer.java,v 1.27 2010/10/12 16:28:19 nifi Exp $ * * ----------------------------------------------------------------- * @@ -34,8 +34,8 @@ * * Authors : Joakim Eriksson, Niclas Finne * Created : 3 jul 2008 - * Updated : $Date: 2010/10/12 11:38:34 $ - * $Revision: 1.26 $ + * Updated : $Date: 2010/10/12 16:28:19 $ + * $Revision: 1.27 $ */ package se.sics.contiki.collect; @@ -63,6 +63,9 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Properties; + +import javax.swing.AbstractAction; +import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.JCheckBoxMenuItem; @@ -128,9 +131,10 @@ public class CollectServer implements SerialConnectionListener { private JMenuItem serialItem; private JMenuItem runInitScriptItem; - private Visualizer[] visualizers; - private MapPanel mapPanel; - private SerialConsole serialConsole; + private final Visualizer[] visualizers; + private final MapPanel mapPanel; + private final SerialConsole serialConsole; + private final MoteProgramAction moteProgramAction; private JFileChooser fileChooser; private JList nodeList; @@ -139,7 +143,8 @@ public class CollectServer implements SerialConnectionListener { private SerialConnection serialConnection; private boolean hasSerialOpened; - private boolean hasSentInit; + /* Do not auto send init script at startup */ + private boolean doSendInitAtStartup = false; private String initScript; private long nodeTimeDelta; @@ -175,6 +180,8 @@ public class CollectServer implements SerialConnectionListener { } }); + moteProgramAction = new MoteProgramAction("Program Nodes..."); + nodeModel = new DefaultListModel(); nodeModel.addElement(""); nodeList = new JList(nodeModel); @@ -235,6 +242,8 @@ public class CollectServer implements SerialConnectionListener { mapPanel.setMapBackground(image); } final int defaultMaxItemCount = 250; + NodeControl nodeControl = new NodeControl(this, MAIN); + visualizers = new Visualizer[] { mapPanel, new MapPanel(this, "Network Graph", MAIN, false), @@ -572,7 +581,7 @@ public class CollectServer implements SerialConnectionListener { } }, new NodeInfoPanel(this, MAIN), - new NodeControl(this, MAIN), + nodeControl, serialConsole }; for (int i = 0, n = visualizers.length; i < n; i++) { @@ -587,6 +596,10 @@ public class CollectServer implements SerialConnectionListener { } pane.add(visualizers[i].getTitle(), visualizers[i].getPanel()); } + JTabbedPane pane = categoryTable.get(nodeControl.getCategory()); + if (pane != null) { + pane.setSelectedComponent(nodeControl.getPanel()); + } window.getContentPane().add(mainPanel, BorderLayout.CENTER); // Setup menu @@ -598,9 +611,7 @@ public class CollectServer implements SerialConnectionListener { serialItem = new JMenuItem("Connect to serial"); serialItem.addActionListener(new SerialItemHandler()); fileMenu.add(serialItem); - JMenuItem item = new JMenuItem("Program Sky nodes..."); - item.addActionListener(new ProgramItemHandler()); - fileMenu.add(item); + fileMenu.add(new JMenuItem(moteProgramAction)); fileMenu.addSeparator(); final JMenuItem clearMapItem = new JMenuItem("Remove Map Background"); @@ -615,23 +626,24 @@ public class CollectServer implements SerialConnectionListener { }); clearMapItem.setEnabled(mapPanel.getMapBackground() != null); - item = new JMenuItem("Select Map Background..."); + JMenuItem item = new JMenuItem("Select Map Background..."); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (fileChooser == null) { fileChooser = new JFileChooser(); - int reply = fileChooser.showOpenDialog(window); - if (reply == JFileChooser.APPROVE_OPTION) { - File file = fileChooser.getSelectedFile(); - String name = file.getAbsolutePath(); + } + int reply = fileChooser.showOpenDialog(window); + if (reply == JFileChooser.APPROVE_OPTION) { + File file = fileChooser.getSelectedFile(); + String name = file.getAbsolutePath(); + if (!mapPanel.setMapBackground(file.getAbsolutePath())) { + JOptionPane.showMessageDialog(window, "Failed to set background image", "Error", JOptionPane.ERROR_MESSAGE); + } else { configTable.put("collect.mapimage", name); - if (!mapPanel.setMapBackground(file.getAbsolutePath())) { - JOptionPane.showMessageDialog(window, "Failed to set background image", "Error", JOptionPane.ERROR_MESSAGE); - } - clearMapItem.setEnabled(mapPanel.getMapBackground() != null); - saveConfig(configTable, configFile); + save(); } + clearMapItem.setEnabled(mapPanel.getMapBackground() != null); } } @@ -639,6 +651,17 @@ public class CollectServer implements SerialConnectionListener { fileMenu.add(item); fileMenu.add(clearMapItem); + item = new JMenuItem("Save Settings"); + item.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + save(); + JOptionPane.showMessageDialog(window, "Settings have been saved."); + } + + }); + fileMenu.add(item); + fileMenu.addSeparator(); item = new JMenuItem("Clear Sensor Data..."); item.addActionListener(new ActionListener() { @@ -745,7 +768,7 @@ public class CollectServer implements SerialConnectionListener { }); connectToSerial(); } - + protected void connectToSerial() { if (!serialConnection.isOpen()) { String comPort = serialConnection.getComPort(); @@ -759,18 +782,7 @@ public class CollectServer implements SerialConnectionListener { } private void exit() { - /* TODO Clean up resources */ - if (configFile != null) { - configTable.setProperty("collect.bounds", "" + window.getX() + ',' + window.getY() + ',' + window.getWidth() + ',' + window.getHeight()); - if (visualizers != null) { - for(Visualizer v : visualizers) { - if (v instanceof Configurable) { - ((Configurable)v).updateConfig(configTable); - } - } - } - saveConfig(configTable, configFile); - } + save(); if (serialConnection != null) { serialConnection.close(); } @@ -839,6 +851,10 @@ public class CollectServer implements SerialConnectionListener { return configTable.getProperty(property, config.getProperty(property, defaultValue)); } + public Action getMoteProgramAction() { + return moteProgramAction; + } + protected void setSystemMessage(final String message) { SwingUtilities.invokeLater(new Runnable() { @@ -970,6 +986,20 @@ public class CollectServer implements SerialConnectionListener { return false; } + private void save() { + if (configFile != null) { + configTable.setProperty("collect.bounds", "" + window.getX() + ',' + window.getY() + ',' + window.getWidth() + ',' + window.getHeight()); + if (visualizers != null) { + for(Visualizer v : visualizers) { + if (v instanceof Configurable) { + ((Configurable)v).updateConfig(configTable); + } + } + } + saveConfig(configTable, configFile); + } + } + private void saveConfig(Properties properties, String configFile) { try { File fp = new File(configFile); @@ -1188,9 +1218,16 @@ public class CollectServer implements SerialConnectionListener { } - protected class ProgramItemHandler implements ActionListener, Runnable { + protected class MoteProgramAction extends AbstractAction implements Runnable { + + private static final long serialVersionUID = 1L; private boolean isRunning = false; + + public MoteProgramAction(String name) { + super(name); + } + public void actionPerformed(ActionEvent e) { if (!isRunning) { isRunning = true; @@ -1207,10 +1244,10 @@ public class CollectServer implements SerialConnectionListener { mp.searchForMotes(); String[] motes = mp.getMotes(); if (motes == null || motes.length == 0) { - JOptionPane.showMessageDialog(window, "Could not find any connected Sky nodes", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(window, "Could not find any connected nodes", "Error", JOptionPane.ERROR_MESSAGE); return; } - int reply = JOptionPane.showConfirmDialog(window, "Found " + motes.length + " connected Sky nodes.\n" + int reply = JOptionPane.showConfirmDialog(window, "Found " + motes.length + " connected nodes.\n" + "Do you want to upload the firmware " + FIRMWARE_FILE + '?'); if (reply == JFileChooser.APPROVE_OPTION) { boolean wasOpen = serialConnection != null && serialConnection.isOpen(); @@ -1260,9 +1297,9 @@ public class CollectServer implements SerialConnectionListener { if (!connection.isSerialOutputSupported()) { serialConsole.addSerialData("*** Serial output not supported ***"); - } else if (!hasSentInit) { + } else if (doSendInitAtStartup) { // Send any initial commands - hasSentInit = true; + doSendInitAtStartup = false; if (hasInitScript()) { // Wait a short time before running the init script diff --git a/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeControl.java b/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeControl.java index 6a7a03336..039acfd36 100644 --- a/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeControl.java +++ b/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeControl.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: NodeControl.java,v 1.5 2010/10/12 11:39:59 adamdunkels Exp $ + * $Id: NodeControl.java,v 1.6 2010/10/12 16:28:19 nifi Exp $ * * ----------------------------------------------------------------- * @@ -34,8 +34,8 @@ * * Authors : Niclas Finne * Created : 27 sep 2010 - * Updated : $Date: 2010/10/12 11:39:59 $ - * $Revision: 1.5 $ + * Updated : $Date: 2010/10/12 16:28:19 $ + * $Revision: 1.6 $ */ package se.sics.contiki.collect.gui; @@ -43,15 +43,20 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; +import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JTextPane; import javax.swing.border.LineBorder; import se.sics.contiki.collect.CollectServer; @@ -70,6 +75,7 @@ public class NodeControl implements Visualizer { private final String category; private final JPanel panel; private final JLabel statusLabel; + private final JSeparator statusSeparator; public NodeControl(CollectServer server, String category) { this.server = server; @@ -85,6 +91,8 @@ public class NodeControl implements Visualizer { statusLabel.setBackground(Color.white); statusLabel.setBorder(LineBorder.createBlackLineBorder()); statusLabel.setVisible(false); + statusSeparator = new JSeparator(); + statusSeparator.setVisible(false); JButton stopButton = createCommandButton("Send stop to nodes", "netcmd killall"); @@ -115,10 +123,43 @@ public class NodeControl implements Visualizer { c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 0.5; c.insets.left = c.insets.right = c.insets.bottom = 3; - c.insets.top = 10; + c.anchor = GridBagConstraints.WEST; c.gridy = 0; c.gridwidth = 3; + controlPanel.add(statusLabel, c); + c.gridy++; + controlPanel.add(statusSeparator, c); + c.insets.top = 10; + + c.gridy++; + c.gridwidth = 1; + controlPanel.add(new JLabel("Program Connected Nodes", JLabel.RIGHT), c); + c.gridwidth = 2; + c.fill = GridBagConstraints.NONE; + controlPanel.add(new JButton(server.getMoteProgramAction()), c); + + c.gridy++; + c.gridwidth = 3; + c.fill = GridBagConstraints.HORIZONTAL; + controlPanel.add(new JSeparator(), c); + + c.gridy++; + c.gridwidth = 1; + controlPanel.add(new JLabel("Base Station Control", JLabel.RIGHT), c); + c.gridwidth = 2; + JPanel basePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5)); + basePanel.add(collectButton); + basePanel.add(stopCollectButton); + c.insets.left -= 5; + controlPanel.add(basePanel, c); + c.insets.left += 5; + + c.gridy++; + c.gridwidth = 3; + controlPanel.add(new JSeparator(), c); + + c.gridy++; JLabel label = new JLabel("Collect Settings", JLabel.CENTER); controlPanel.add(label, c); c.gridwidth = 1; @@ -150,27 +191,34 @@ public class NodeControl implements Visualizer { c.gridy++; c.gridwidth = 3; - c.weightx = 0; - c.fill = GridBagConstraints.NONE; - c.insets.bottom = 20; - JPanel p = new JPanel(); - p.add(sendButton); - p.add(stopButton); - controlPanel.add(p, c); + c.insets.bottom = 10; + JPanel nodePanel = new JPanel(); + nodePanel.add(sendButton); + nodePanel.add(stopButton); + controlPanel.add(nodePanel, c); c.gridy++; - c.insets.bottom = 3; - controlPanel.add(new JLabel("Base Station Control", JLabel.CENTER), c); - - c.gridy++; - c.insets.bottom = 20; - p = new JPanel(); - p.add(collectButton); - p.add(stopCollectButton); - controlPanel.add(p, c); - + controlPanel.add(new JSeparator(), c); panel.add(controlPanel, BorderLayout.NORTH); - panel.add(statusLabel, BorderLayout.SOUTH); + + JTextPane helpPane = new JTextPane(); + helpPane.setContentType("text/html"); + helpPane.setEditable(false); + helpPane.setText("" + + "

Quick Startup Instructions

" + + "" + + "
  • Connect nodes to USB. Press the Program Nodes... button." + + "
  • Disconnect all except one node. " + + "Press the Start Collect button." + + "
  • Press the Send command to nodes button." + + "" + + ""); + helpPane.setBackground(panel.getBackground()); + JScrollPane helpScroll = new JScrollPane(helpPane, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + helpScroll.setBorder(BorderFactory.createEmptyBorder(3, 10, 10, 10)); + panel.add(helpScroll, BorderLayout.CENTER); } private JButton createCommandButton(String name, final String... command) { @@ -219,6 +267,7 @@ public class NodeControl implements Visualizer { statusLabel.setForeground(isWarning ? Color.red : Color.black); statusLabel.setText(text); statusLabel.setVisible(true); + statusSeparator.setVisible(true); } public String getCategory() {