org.kepler.gui.PlotsEditorPanel.java Source code

Java tutorial

Introduction

Here is the source code for org.kepler.gui.PlotsEditorPanel.java

Source

/* A tab pane to display sensor data. 
 * 
 * Copyright (c) 2010 The Regents of the University of California.
 * All rights reserved.
 *
 * '$Author: crawl $'
 * '$Date: 2010-06-03 16:45:10 -0700 (Thu, 03 Jun 2010) $' 
 * '$Revision: 24730 $'
 * 
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the above
 * copyright notice and the following two paragraphs appear in all copies
 * of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS.
 *
 */

package org.kepler.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kepler.plotting.Plot;
import org.kepler.plotting.PlotEditor;
import org.kepler.plotting.PlottingControllerFactory;

import ptolemy.actor.gui.TableauFrame;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.NamedObj;
import ptolemy.vergil.toolbox.FigureAction;

public class PlotsEditorPanel extends JPanel implements TabPane {
    private static final Log log = LogFactory.getLog(PlotsEditorPanel.class.getName());

    public PlotsEditorPanel(TableauFrame parent, String title) {
        super();
        _title = title;
        _frame = parent;
        setBackground(TabManager.BGCOLOR);
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        plotsPanel = new JPanel();
        plotsPanel.setLayout(new BoxLayout(plotsPanel, BoxLayout.PAGE_AXIS));

        fixGraphics();

        JScrollPane scrollPane = new JScrollPane(plotsPanel);

        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        this.add(scrollPane, BorderLayout.CENTER);
        JButton addPlotButton = createAddPlotButton();
        this.add(addPlotButton, BorderLayout.PAGE_END);

        // This thread will try to wait until the PlotsPanel is available
        // before adding a plot to it. If a plot is added before the
        // applicable tab pane is available, an NPE will be triggered.
        // The thread will poll for tab pane setup completion every 100 ms,
        // up to a maximum of 10 seconds (100 iterations). If after 10 seconds
        // the tab pane is not available, something has probably gone wrong,
        // and further attempts would do no good.
        new Thread(new Runnable() {
            private void pause(long l) {
                try {
                    Thread.sleep(l);
                } catch (InterruptedException ignored) {
                }
            }

            public void run() {
                int maxIterations = 100;
                for (int i = 0; i < maxIterations; i++) {
                    log.debug("PlotsEditorPanel thread waiting " + "for TabPane to become available...");
                    pause(100);
                    if (canAddPlot()) {
                        log.debug("PlotsEditorPanel thread got TabPane, adding Plot.");
                        addPlot();
                        return;
                    }
                }
            }
        }).start();
    }

    public void fixGraphics() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                plotsPanel.repaint();
                plotsPanel.revalidate();
                plotsPanel.repaint();
            }
        });
    }

    private JButton createAddPlotButton() {
        JButton button = new JButton();
        button.setText("New Plot");
        final PlotsEditorPanel me = this;
        FigureAction action = new FigureAction("add plot") {
            @Override
            public void actionPerformed(ActionEvent e) {
                me.addPlot();
            }
        };
        button.setAction(action);
        return button;
    }

    /** Get the container frame. */
    public TableauFrame getParentFrame() {
        return _frame;
    }

    /** Get the name of the tab. */
    public String getTabName() {
        return _title;
    }

    /** Initialize the contents of the tab. */
    public void initializeTab() throws Exception {

    }

    private boolean canAddPlot() {
        TabPane pane = TabManager.getInstance().getTab(this.getParentFrame(), "Plot Viewer");
        return pane != null;
    }

    public void addPlot() {
        TabPane pane = TabManager.getInstance().getTab(this.getParentFrame(), "Plot Viewer");
        Plot plot = ((PlotsPanel) pane).addGraph();

        addPlotEditor(true, true, plot);
    }

    public void addPlotEditor(boolean enabled, boolean refreshGraphics, Plot plot) {
        PlotEditor editor = new PlotEditor(this, plot);

        if (plot != null) {
            plot.setPlotEditor(editor);
        }
        editor.setActive(enabled);
        plotsPanel.add(editor);

        if (refreshGraphics) {
            fixGraphics();
        }
    }

    /** Set the frame for this tab. */
    public void setParentFrame(TableauFrame parent) {
        _frame = parent;
    }

    public void removePlot(final PlotEditor plotEditor) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                plotsPanel.remove(plotEditor);
            }
        });
    }

    public synchronized int getNextUnusedGraphId() {
        return graphId++;
    }

    public static void setPlottingControllerFactory(PlottingControllerFactory plottingControllerFactory) {
        PlotsEditorPanel.plottingControllerFactory = plottingControllerFactory;
    }

    public static PlottingControllerFactory getPlottingControllerFactory() {
        return plottingControllerFactory;
    }

    public static class Factory extends TabPaneFactory {
        public Factory(NamedObj container, String name) throws IllegalActionException, NameDuplicationException {
            super(container, name);
        }

        public TabPane createTabPane(TableauFrame parent) {
            return new PlotsEditorPanel(parent, "Plot Designer");
        }
    }

    private JPanel plotsPanel;
    private static PlottingControllerFactory plottingControllerFactory;
    private TableauFrame _frame;
    private String _title;
    private int graphId = 1;

}