/* =================== * Orson Charts - Demo * =================== * * Copyright (c) 2013-2016, Object Refinery Limited. * All rights reserved. * * http://www.object-refinery.com/orsoncharts/index.html * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of the Object Refinery Limited nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL OBJECT REFINERY LIMITED BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Note that the above terms apply to the demo source only, and not the * Orson Charts library. * */ package com.orsoncharts.demo.swing; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.io.IOException; import java.net.URL; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.border.Border; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import com.orsoncharts.demo.DemoDescription; import com.orsoncharts.style.ChartStyle; /** * A component that fits inside a tab and contains a JTree to select individual * demos, a chart panel to display the chart, and a chart description panel * to display the description. This component is intended to be self-contained * so it can be instantiated and embedded wherever (such as in the JFreeChart * demo application). */ @SuppressWarnings("serial") public class OrsonChartsDemoComponent extends JPanel implements TreeSelectionListener { private static final String PREFIX = "com.orsoncharts.demo.swing."; private static final String ABOUT_PREFIX = "/com/orsoncharts/demo/"; /** * The path to the default demo chart. This gets used to ensure the * JTree is open at the initial demo selection. */ private TreePath defaultChartPath; /** * The panel that contains the current chart - sits in the upper section of * the right-hand split pane. */ private JPanel chartContainer; /** * The panel that contains the chart description - sits in the lower * section of the right-hand split pane. */ private JTextPane chartDescriptionPane; /** * The chart style (if non-{@code null} this will be applied to * new charts). */ private ChartStyle style; /** * Creates a new instance. */ public OrsonChartsDemoComponent() { super(new BorderLayout()); this.style = null; add(createContent()); } public ChartStyle getChartStyle() { if (this.style == null) { return null; } return this.style.clone(); } public void setChartStyle(ChartStyle style) { this.style = style; } /** * Returns a reference to the panel that contains the chart viewer. * * @return A reference to the panel that contains the chart viewer. */ public JPanel getChartContainer() { return this.chartContainer; } /** * Returns a reference to the chart description pane. * * @return A reference to the chart description pane. */ public JTextPane getChartDescriptionPane() { return this.chartDescriptionPane; } private JComponent createContent() { JSplitPane content = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); content.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); // tree on the left JTree tree = new JTree(createTreeModel()); tree.addTreeSelectionListener(this); tree.setSelectionPath(this.defaultChartPath); JScrollPane scroller = new JScrollPane(tree); scroller.setPreferredSize(new Dimension(300, 580)); content.add(scroller); // chart display on the right content.add(createChartComponent()); return content; } /** * Creates a {@code TreeModel} with references to all the individual * demo applications. * * @return A TreeModel. */ private TreeModel createTreeModel() { DefaultMutableTreeNode root = new DefaultMutableTreeNode( "Orson Charts"); root.add(createCategoryChartsNode(root)); root.add(createPieChartsNode()); root.add(createXYZChartsNode()); root.add(createAxisRangeTestNode()); return new DefaultTreeModel(root); } private MutableTreeNode createNode(String name, String file, String description) { return new DefaultMutableTreeNode(new DemoDescription(name, file, description)); } /** * A node for the first group of charts. * * @param r the root node. * * @return The node. */ private MutableTreeNode createCategoryChartsNode(DefaultMutableTreeNode r) { DefaultMutableTreeNode n = new DefaultMutableTreeNode( "Category Charts"); MutableTreeNode defaultNode = createNode(PREFIX + "AreaChart3DDemo1", "AreaChart3DDemo1.java", ABOUT_PREFIX + "AreaChart3D1.html"); this.defaultChartPath = new TreePath(new Object[] {r, n, defaultNode}); n.add(defaultNode); n.add(createNode(PREFIX + "AreaChart3DDemo2", "AreaChart3DDemo2.java", ABOUT_PREFIX + "AreaChart3D2.html")); n.add(createNode(PREFIX + "BarChart3DDemo1", "BarChart3DDemo1.java", ABOUT_PREFIX + "BarChart3D1.html")); n.add(createNode(PREFIX + "BarChart3DDemo2", "BarChart3DDemo2.java", ABOUT_PREFIX + "BarChart3D2.html")); n.add(createNode(PREFIX + "CategoryMarkerDemo1", "CategoryMarkerDemo1.java", ABOUT_PREFIX + "CategoryMarkerDemo1.html")); n.add(createNode(PREFIX + "LineChart3DDemo1", "LineChart3DDemo1.java", ABOUT_PREFIX + "LineChart3D1.html")); n.add(createNode(PREFIX + "LineChart3DDemo2", "LineChart3DDemo2.java", ABOUT_PREFIX + "LineChart3D2.html")); n.add(createNode(PREFIX + "StackedBarChart3DDemo1", "StackedBarChart3DDemo1.java", ABOUT_PREFIX + "StackedBarChart3D1.html")); n.add(createNode(PREFIX + "StackedBarChart3DDemo2", "StackedBarChart3DDemo2.java", ABOUT_PREFIX + "StackedBarChart3D2.html")); n.add(createNode(PREFIX + "StackedBarChart3DDemo3", "StackedBarChart3DDemo3.java", ABOUT_PREFIX + "StackedBarChart3D3.html")); return n; } /** * Creates a node for the pie chart demos. * * @return A node for the pie chart demos. */ private MutableTreeNode createPieChartsNode() { DefaultMutableTreeNode n = new DefaultMutableTreeNode("Pie Charts"); n.add(createNode(PREFIX + "PieChart3DDemo1", "PieChart3DDemo1.java", ABOUT_PREFIX + "PieChart3D1.html")); n.add(createNode(PREFIX + "PieChart3DDemo2", "PieChart3DDemo2.java", ABOUT_PREFIX + "PieChart3D2.html")); return n; } private MutableTreeNode createXYZChartsNode() { DefaultMutableTreeNode n = new DefaultMutableTreeNode("XYZ Charts"); n.add(createNode(PREFIX + "RangeMarkerDemo1", "RangeMarkerDemo1.java", ABOUT_PREFIX + "RangeMarker1.html")); n.add(createNode(PREFIX + "ScatterPlot3DDemo1", "ScatterPlot3DDemo1.java", ABOUT_PREFIX + "ScatterPlot3D1.html")); n.add(createNode(PREFIX + "ScatterPlot3DDemo2", "ScatterPlot3DDemo2.java", ABOUT_PREFIX + "ScatterPlot3D2.html")); n.add(createNode(PREFIX + "ScatterPlot3DDemo3", "ScatterPlot3DDemo3.java", ABOUT_PREFIX + "ScatterPlot3D3.html")); n.add(createNode(PREFIX + "SurfaceRendererDemo1", "SurfaceRendererDemo1.java", ABOUT_PREFIX + "SurfaceRenderer1.html")); n.add(createNode(PREFIX + "SurfaceRendererDemo2", "SurfaceRendererDemo2.java", ABOUT_PREFIX + "SurfaceRenderer2.html")); n.add(createNode(PREFIX + "XYZBarChart3DDemo1", "XYZBarChart3DDemo1.java", ABOUT_PREFIX + "XYZBarChart3D1.html")); n.add(createNode(PREFIX + "XYZLineChart3DDemo1", "XYZLineChart3DDemo1.java", ABOUT_PREFIX + "XYZLineChart3D1.html")); return n; } private MutableTreeNode createAxisRangeTestNode() { DefaultMutableTreeNode n = new DefaultMutableTreeNode( "Axis Range Tests"); n.add(createNode(PREFIX + "AxisRangeDemo1", "AxisRangeDemo1.java", ABOUT_PREFIX + "AxisRangeDemo1.html")); n.add(createNode(PREFIX + "AxisRangeDemo2", "AxisRangeDemo2.java", ABOUT_PREFIX + "AxisRangeDemo2.html")); n.add(createNode(PREFIX + "AxisRangeDemo3", "AxisRangeDemo3.java", ABOUT_PREFIX + "AxisRangeDemo3.html")); n.add(createNode(PREFIX + "AxisRangeDemo4", "AxisRangeDemo4.java", ABOUT_PREFIX + "AxisRangeDemo4.html")); n.add(createNode(PREFIX + "AxisRangeDemo5", "AxisRangeDemo5.java", ABOUT_PREFIX + "AxisRangeDemo5.html")); n.add(createNode(PREFIX + "AxisRangeDemo6", "AxisRangeDemo6.java", ABOUT_PREFIX + "AxisRangeDemo6.html")); n.add(createNode(PREFIX + "AxisRangeDemo7", "AxisRangeDemo7.java", ABOUT_PREFIX + "AxisRangeDemo7.html")); return n; } /** * Creates the panel that contains the chart and the chart description, * divided by a splitter. * * @return */ private JComponent createChartComponent() { JSplitPane splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT); Border b = BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(4, 4, 4, 4), BorderFactory.createLineBorder(Color.DARK_GRAY)); this.chartContainer = new JPanel(new BorderLayout()); DemoPanel chartPanel = AreaChart3DDemo1.createDemoPanel(); chartPanel.setBorder(b); this.chartContainer.add(chartPanel); splitter.add(this.chartContainer); JPanel lowerPanel = new JPanel(new BorderLayout()); lowerPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(4, 4, 4, 4), BorderFactory.createLineBorder(Color.BLACK))); this.chartDescriptionPane = new JTextPane(); this.chartDescriptionPane.setPreferredSize(new Dimension(400, 200)); this.chartDescriptionPane.setEditable(false); this.chartDescriptionPane.setBorder( BorderFactory.createEmptyBorder(2, 2, 2, 2)); this.chartDescriptionPane.setText("No chart description available."); lowerPanel.add(this.chartDescriptionPane); splitter.add(lowerPanel); return splitter; } @Override public void valueChanged(TreeSelectionEvent e) { TreePath path = e.getPath(); Object obj = path.getLastPathComponent(); if (obj != null) { DefaultMutableTreeNode n = (DefaultMutableTreeNode) obj; Object userObj = n.getUserObject(); if (userObj instanceof DemoDescription) { DemoDescription dd = (DemoDescription) userObj; SwingUtilities.invokeLater(new DemoDisplayer(this, dd)); } else { this.chartContainer.removeAll(); this.chartContainer.add(createNoDemoSelectedPanel()); this.chartContainer.validate(); URL descriptionURL = OrsonChartsDemo.class.getResource( "select.html"); if (descriptionURL != null) { try { this.chartDescriptionPane.setPage(descriptionURL); } catch (IOException ex) { System.err.println("Attempted to read a bad URL: " + descriptionURL); } } } } } private JComponent createNoDemoSelectedPanel() { return new JButton("No demo selected."); } }