/*
* Showcase.java, the main demo application of project jchart2d.
* Copyright (C) 2007 - 2011 Achim Westermann, created on 10.12.2004, 13:48:55
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* If you modify or optimize the code in a useful way please let me know.
* Achim.Westermann@gmx.de
*
*/
package info.monitorenter.gui.chart.demos;
import info.monitorenter.gui.chart.Chart2D;
import info.monitorenter.gui.chart.controls.LayoutFactory;
import info.monitorenter.gui.chart.events.Chart2DActionSaveImageSingleton;
import info.monitorenter.gui.chart.io.ADataCollector;
import info.monitorenter.gui.chart.io.RandomDataCollectorOffset;
import info.monitorenter.gui.chart.rangepolicies.RangePolicyMinimumViewport;
import info.monitorenter.gui.chart.traces.Trace2DLtd;
import info.monitorenter.gui.chart.views.ChartPanel;
import info.monitorenter.util.Range;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* Advanced demonstration applet for jchart2d.
* <p>
* Please right click on the chart and on the label for the traces to see popup
* menus that offer the freshest new features.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.15 $
*
*/
public final class Showcase
extends JApplet {
/**
* Panel with controls for the chart.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
*
* @version $Revision: 1.15 $
*/
final class ControlPanel
extends JPanel {
/**
* Generated for <code>serialVersionUID</code>.
*/
private static final long serialVersionUID = 3257005441048129846L;
/** Slider for the maximum amount of points to show. */
private JSlider m_amountPointsSlider;
/** Button to clear data from the chart. */
private JButton m_clear;
/**
* <p>
* The <code>JComboBox</code> used to choose the color of the chart.
* </p>
*/
private JComboBox m_colorChooser;
/** The slider for choosing the speed of adding new points. */
private JSlider m_latencyTimeSlider;
/** Button for the action of capturing a snapshot image. */
private JButton m_snapshot;
/** Button to start or stop data collection. */
private JButton m_startStop;
/**
* Defcon.
* <p>
*/
protected ControlPanel() {
// create the components:
this.setBackground(Color.WHITE);
this.createAmountPointSlider();
this.createLatencySlider();
this.createStartStopButton();
this.createSnapShotButton();
this.createClearButton();
this.createColorChooserButton();
// Layouting: Vertical Grid Layout for putting the sliders...
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(this.m_amountPointsSlider);
this.add(this.m_latencyTimeSlider);
// GridLayout stretches components (no respect for their preferred size):
// Small trick by inserting another component with different Layout.
JComponent stretch = new JPanel();
stretch.setBackground(Color.WHITE);
stretch.setLayout(new BoxLayout(stretch, BoxLayout.X_AXIS));
stretch.add(Box.createHorizontalGlue());
stretch.add(this.m_startStop);
stretch.add(Box.createHorizontalGlue());
stretch.add(this.m_clear);
if (this.m_snapshot != null) {
// for applet usage snapshot is null!
stretch.add(Box.createHorizontalGlue());
stretch.add(this.m_snapshot);
}
stretch.add(Box.createHorizontalGlue());
stretch.add(this.m_colorChooser);
stretch.add(Box.createHorizontalGlue());
this.add(stretch);
}
/**
* Helper to create a slider for maximum amount of points to show.
* <p>
*/
private void createAmountPointSlider() {
// amountPointsSlider
this.m_amountPointsSlider = new JSlider(10, 410);
this.m_amountPointsSlider.setBackground(Color.WHITE);
// find the value of max points:
int maxPoints = Showcase.this.getTrace().getMaxSize();
this.m_amountPointsSlider.setValue(maxPoints);
this.m_amountPointsSlider.setMajorTickSpacing(40);
this.m_amountPointsSlider.setMinorTickSpacing(20);
this.m_amountPointsSlider.setSnapToTicks(true);
this.m_amountPointsSlider.setPaintLabels(true);
this.m_amountPointsSlider.setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(), "Amount of points.", TitledBorder.LEFT, TitledBorder.BELOW_TOP));
this.m_amountPointsSlider.setPaintTicks(true);
this.m_amountPointsSlider.addChangeListener(new ChangeListener() {
public void stateChanged(final ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
// Only if not currently dragged...
if (!source.getValueIsAdjusting()) {
int value = source.getValue();
Showcase.this.getTrace().setMaxSize(value);
}
}
});
}
/**
* Helper to create a button for clearing data from the chart.
* <p>
*/
private void createClearButton() {
// clear Button
this.m_clear = new JButton("clear");
this.m_clear.setBackground(Color.WHITE);
this.m_clear.setBackground(Color.WHITE);
this.m_clear.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
Showcase.this.clearTrace();
}
});
}
/**
* Helper to create a button for choosing trace colors.
* <p>
*/
private void createColorChooserButton() {
// color chooser JComboBox
this.m_colorChooser = new JComboBox();
this.m_colorChooser.setBackground(Color.WHITE);
/**
* Color with a name.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
* @version $Revision: 1.15 $
*/
final class ColorItem
extends Color {
/**
* Generated <code>serialVersionUID</code>.
*/
private static final long serialVersionUID = 3257854281104568629L;
/** The name of the color. */
private String m_name;
/**
* Creates an instance with the given color and it's name.
* <p>
*
* @param c
* the color to use.
*
* @param name
* the name of the color.
*/
public ColorItem(final Color c, final String name) {
super(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
this.m_name = name;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.m_name;
}
}
this.m_colorChooser.addItem(new ColorItem(Color.BLACK, "black"));
this.m_colorChooser.addItem(new ColorItem(Color.BLUE, "blue"));
this.m_colorChooser.addItem(new ColorItem(Color.CYAN, "cyan"));
this.m_colorChooser.addItem(new ColorItem(Color.DARK_GRAY, "darg gray"));
this.m_colorChooser.addItem(new ColorItem(Color.GRAY, "gray"));
this.m_colorChooser.addItem(new ColorItem(Color.GREEN, "green"));
this.m_colorChooser.addItem(new ColorItem(Color.LIGHT_GRAY, "light gray"));
this.m_colorChooser.addItem(new ColorItem(Color.MAGENTA, "magenta"));
this.m_colorChooser.addItem(new ColorItem(Color.ORANGE, "orange"));
this.m_colorChooser.addItem(new ColorItem(Color.PINK, "pink"));
this.m_colorChooser.addItem(new ColorItem(Color.RED, "red"));
this.m_colorChooser.addItem(new ColorItem(Color.YELLOW, "yellow"));
this.m_colorChooser.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent ae) {
Color color = (Color) ((JComboBox) ae.getSource()).getSelectedItem();
Showcase.this.getTrace().setColor(color);
}
});
this.m_colorChooser.setSelectedIndex(10);
this.m_colorChooser.setMaximumSize(new Dimension(200, this.m_clear.getMaximumSize().height));
}
/**
* Helper to create a slider for speed of adding new points.
* <p>
*/
private void createLatencySlider() {
// Latency slider:
this.m_latencyTimeSlider = new JSlider(10, 210);
this.m_latencyTimeSlider.setBackground(Color.WHITE);
this.m_latencyTimeSlider.setValue((int) Showcase.this.getCollector().getLatency());
this.m_latencyTimeSlider.setMajorTickSpacing(50);
this.m_latencyTimeSlider.setMinorTickSpacing(10);
this.m_latencyTimeSlider.setSnapToTicks(true);
this.m_latencyTimeSlider.setPaintLabels(true);
this.m_latencyTimeSlider.setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(), "Latency for adding points.", TitledBorder.LEFT,
TitledBorder.BELOW_TOP));
this.m_latencyTimeSlider.setPaintTicks(true);
this.m_latencyTimeSlider.addChangeListener(new ChangeListener() {
public void stateChanged(final ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
// Only if not currently dragged...
if (!source.getValueIsAdjusting()) {
int value = source.getValue();
Showcase.this.getCollector().setLatency(value);
}
}
});
}
/**
* Helper to create a button for taking snapshot images.
* <p>
*/
private void createSnapShotButton() {
// the button for snapshot:
this.m_snapshot = new JButton(Chart2DActionSaveImageSingleton.getInstance(
Showcase.this.m_chart, "Save image"));
this.m_snapshot.setBackground(Color.WHITE);
}
/**
* Helper to create a button to start and stop button for data collection.
* <p>
*/
private void createStartStopButton() {
// Start stop Button
this.m_startStop = new JButton("start");
this.m_startStop.setBackground(Color.WHITE);
this.m_startStop.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
JButton source = (JButton) e.getSource();
if (Showcase.this.getCollector().isRunning()) {
Showcase.this.stopData();
source.setText("start");
} else {
Showcase.this.startData();
source.setText("stop");
}
source.invalidate();
source.repaint();
}
});
}
}
/**
* Generated <code>serialVersionUID</code>.
*/
private static final long serialVersionUID = 3904676068135678004L;
/**
* Main entry that uses the applet initialization.
* <p>
*
* @param args
* ignored.
*
* @see #init()
*/
public static void main(final String[] args) {
JFrame frame = new JFrame("Showcase");
Showcase showcase = new Showcase();
showcase.init();
frame.getContentPane().add(showcase);
frame.setSize(400, 600);
// Enable the termination button [cross on the upper right edge]:
frame.addWindowListener(new WindowAdapter() {
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
}
/** The char to use. */
protected Chart2D m_chart;
/** The data collector to use. */
private transient ADataCollector m_collector;
/** The trace to use. */
private Trace2DLtd m_trace;
/**
* Defcon.
*
*/
public Showcase() {
super();
}
/**
* Clears the internal trace.
* <p>
*/
public synchronized void clearTrace() {
this.getTrace().removeAllPoints();
}
/**
* Returns the chart.
* <p>
*
* @return the chart to use.
*/
public Chart2D getChart() {
return this.m_chart;
}
/**
* Returns the collector to use.
* <p>
*
* @return the collector to use.
*/
public ADataCollector getCollector() {
return this.m_collector;
}
/**
* Returns the trace.
* <p>
*
* @return the trace.
*/
public Trace2DLtd getTrace() {
return this.m_trace;
}
/**
* @see java.applet.Applet#init()
*/
@Override
public void init() {
super.init();
Chart2D chart = new Chart2D();
this.setChart(chart);
this.setSize(new Dimension(600, 500));
this.m_chart.getAxisX().setPaintGrid(true);
this.m_chart.getAxisY().setPaintGrid(true);
chart.getAxisY().setRangePolicy(new RangePolicyMinimumViewport(new Range(-20, +20)));
chart.setGridColor(Color.LIGHT_GRAY);
this.setTrace(new Trace2DLtd(100));
this.getTrace().setName("random");
this.getTrace().setPhysicalUnits("Milliseconds", "random value");
this.getTrace().setColor(Color.RED);
chart.addTrace(this.getTrace());
Container content = this.getContentPane();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
LayoutFactory factory = LayoutFactory.getInstance();
ChartPanel chartpanel = new ChartPanel(chart);
this.setJMenuBar(factory.createChartMenuBar(chartpanel, false));
content.add(chartpanel);
content.addPropertyChangeListener(chartpanel);
this.setCollector(new RandomDataCollectorOffset(this.getTrace(), 50));
content.add(new ControlPanel());
}
/**
* Sets the chart to use.
* <p>
*
* I would never code this but applets won't access private members and
* Checkstyle does not accept non-private members.
* <p>
*
* So it is only accepted if the member is null. Don't try calling.
* <p>
*
* @param chart2D
* the chart to use.
*/
public void setChart(final Chart2D chart2D) {
if (this.m_chart == null) {
this.m_chart = chart2D;
}
}
/**
* Sets the collector to use.
* <p>
*
* @param collector
* the collector to use.
*/
private void setCollector(final RandomDataCollectorOffset collector) {
this.m_collector = collector;
}
/**
* Sets the trace to use.
* <p>
*
* This will do nothing if the internal trace has been set before and is only
* intended for the applet which needs public members or setters.
* <p>
*
* @param trace
* the trace to use.
*/
public void setTrace(final Trace2DLtd trace) {
if (this.m_trace == null) {
this.m_trace = trace;
}
}
/**
* Starts data collection.
* <p>
*
*/
public synchronized void startData() {
if (!this.getCollector().isRunning()) {
this.getCollector().start();
}
}
/**
* Stops data collection.
*
* <p>
*/
public synchronized void stopData() {
if (this.getCollector().isRunning()) {
this.getCollector().stop();
}
}
}