package com.rle.monitor; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.io.IOException; /* * RLE Surface Crack Detector Graphing Software * * Copyright (C) 2002 RLE Technologies * For more information visit http://www.rletech.com/ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ /** * @author Andy Goth * @author Eric Peterson * @author Matt Lane * @version 0.1 */ /** Panel in which data is graphed. */ public class Display extends JPanel { /* State info */ private App app; private Window window; private Bounds bounds; private Buffer buffer; private boolean running = true; /* Widgets */ private JMenuBar menubar; private JMenu menu; private Chart chart; private MySlider ceil; private MySlider floor; private MySlider width; private MySlider position; private MyCheckBox status; private MySpinner offset; private MySpinner gain; private Insets insets = new Insets(1, 1, 1, 1); /** Constructor. */ public Display(App app) { super(new GridBagLayout()); this.app = app; window = app.getWindow(); bounds = new Bounds(app.getBuffer()); buffer = app.getBuffer(); /* Menubar */ menubar = new JMenuBar(); LookAndFeel.uninstallBorder(menubar); window.setJMenuBar(menubar); /* Menu */ menu = new JMenu("Menu"); menu.setMnemonic('m'); menu.setIcon(new ImageIcon("images/down.png")); //menu.setIconTextGap(2); menu.setHorizontalTextPosition(SwingConstants.LEADING); menu.add(new JMenuItem("Save", new ImageIcon("images/save.png"))); menu.add(new JMenuItem("Export", new ImageIcon("images/export.png"))); menu.addSeparator(); menu.add(new JMenuItem("Setup", new ImageIcon("images/setup.png"))); menu.addSeparator(); menu.add(new JMenuItem("74%/1hr", new ImageIcon("images/battery_3.png"))); menu.addSeparator(); menu.add(new JMenuItem("Shutdown", new ImageIcon("images/shutdown.png"))); menu.addMenuListener(new MenuListener() { private boolean running; public void menuSelected(MenuEvent e) { running = getRunning(); if (running) setRunning(false); } public void menuDeselected(MenuEvent e) { setRunning(running); } public void menuCanceled(MenuEvent e) {} }); menubar.add(menu); /* Something to fill extra space */ menubar.add(Box.createGlue()); /* Status button */ status = new MyCheckBox("Run", running); status.setMnemonic('r'); status.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setRunning(status.isSelected()); } }); menubar.add(status); /* Offset spinner */ offset = new MySpinner("Offset", 0, 255, 0); menubar.add(offset); offset.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { buffer.setOffset(offset.getValue()); } }); /* Gain spinner */ gain = new MySpinner("Gain", 0, 255, 0); menubar.add(gain); gain.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { buffer.setGain(gain.getValue()); } }); /* Main roll chart for plotting data */ chart = new Chart(app.getBuffer()); chart.setBounds(bounds); add(chart, new GridBagConstraints(0, 1, 2, 1, 100, 100, GridBagConstraints.NORTH, GridBagConstraints.BOTH, insets, 0, 0)); chart.addSelectionListener(new SelectionListener() { boolean oldRunning = running; int oldState = Selection.NONE; /* Handle scrolling due to selection */ public void rangeChange(SelectionEvent e) { Bounds newBounds = e.getBounds(); if (newBounds.getPosition() == bounds.getPosition()) return; position.setValueQuiet(newBounds.getPosition()); bounds.setPosition(newBounds.getPosition()); } /* Handle zooming due to selection */ public void stateChange(SelectionEvent e) { Selection selection = e.getSelection(); switch (selection.getState()) { case Selection.NONE: if (oldState != Selection.ZOOM) setRunning(!oldRunning); break; case Selection.BEGIN: oldRunning = running; if (running) setRunning(false); /* Fall through */ case Selection.SELECT: return; /* case Selection.ZOOM: */ } oldState = selection.getState(); Bounds newBounds = e.getBounds(); if (newBounds.equals(bounds)) return; floor.setValueQuiet(newBounds.getFloor()); ceil.setValueQuiet(newBounds.getCeil()); width.setValueQuiet(newBounds.getWidth()); position.setValueQuiet(newBounds.getPosition()); bounds.setRange(newBounds); } }); buffer.addParamListener(new ParamListener() { public void offsetChanged(int value) { offset.setValueQuiet(value); } public void gainChanged(int value) { gain.setValueQuiet(value); } public void threshholdChanged(int value) { chart.repaint(); } }); /* Ceiling setting */ add(new JLabel("Ceiling", JLabel.RIGHT), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, insets, 0, 0)); ceil = new MySlider(0, 255, bounds.getCeil()); ceil.setStopMin(bounds.getMinCeil()); ceil.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { bounds.setCeil(ceil.getValue()); floor.setStopMax(bounds.getMaxFloor()); chart.setBounds(bounds); } }); add(ceil, new GridBagConstraints(1, 2, 1, 1, 100, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0)); /* Floor setting */ add(new JLabel("Floor", JLabel.RIGHT), new GridBagConstraints(0, 3, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, insets, 0, 0)); floor = new MySlider(MySlider.HORIZONTAL, 0, 255, bounds.getFloor()); floor = new MySlider(0, 255, bounds.getFloor()); floor.setStopMax(bounds.getMaxFloor()); floor.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { bounds.setFloor(floor.getValue()); ceil.setStopMin(bounds.getMinCeil()); chart.setBounds(bounds); } }); add(floor, new GridBagConstraints(1, 3, 1, 1, 100, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0)); /* Width setting */ add(new JLabel("Width", JLabel.RIGHT), new GridBagConstraints(0, 4, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, insets, 0, 0)); width = new MySlider(Bounds.MIN_WIDTH, bounds.getMaxRight(), bounds.getWidth()); width.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { bounds.setWidth(width.getValue()); position.setStopMin(bounds.getMinPosition()); chart.setBounds(bounds); } }); add(width, new GridBagConstraints(1, 4, 1, 1, 100, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0)); /* Position setting */ add(new JLabel("Position", JLabel.RIGHT), new GridBagConstraints(0, 5, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, insets, 0, 0)); position = new MySlider(bounds.getMinWidth(), bounds.getMaxPosition(), bounds.getPosition()); position.setStopMin(bounds.getMinPosition()); position.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { bounds.setPosition(position.getValue()); chart.setBounds(bounds); } }); add(position, new GridBagConstraints(1, 5, 1, 1, 100, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, insets, 0, 0)); } /** Switches to the setup panel. */ private void setupPanel() { setRunning(false); app.getWindow().setPanel(app.getSetup()); } /** Returns true if data is being collected and graphed. */ public boolean getRunning() {return running;} /** Starts or stops data collection and graphing. */ public void setRunning(boolean running) { if (running == this.running) return; status.setSelectedQuiet(running); if (running && chart.getSelection().getState() != Selection.NONE) chart.clearSelection(); chart.setRunning(running); this.running = running; } /** Save all visible data */ public void saveData() { try { /* TODO: security manager stuff */ CSVString export = new CSVString(); Buffer buffer = app.getBuffer(); int left = bounds.getLeft(); int right = bounds.getRight() + 1; if (left < buffer.getStart()) left = buffer.getStart(); for (int i = left; i < right; i++) { export.addCell(buffer.getSample(i)); export.newRow(); } /* TODO: calculate filename */ export.writeToFile("export.csv"); } catch (IOException x) { x.printStackTrace(); JOptionPane.showMessageDialog(getParent(), x.getMessage(), "Error Exporting Data", JOptionPane.ERROR_MESSAGE); } } }