PlotFrame_2005

PlotFrame.java

package org.opensourcephysics.frames;
import java.awt.Color;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.*;
import org.opensourcephysics.display.*;
import org.opensourcephysics.controls.*;
import org.opensourcephysics.display.dialogs.ScaleInspector;
import org.opensourcephysics.display.dialogs.LogAxesInspector;

/**
* DrawingFrame displays a plot using a dedicated DatasetManager.
*
* Commmon Dataset methods are forwarded to the DatasetManager.
*
* @author W. Christian
* @version 1.0
*/

public class PlotFrame extends DrawingFrame
{
   protected DatasetManager datasetManager = new DatasetManager();   // benutzt ArrayList
   protected DataTable dataTable = new DataTable();
   protected DataTableFrame tableFrame;

   /**
   * Constructs the PlottingFrame with the given frame title and axes labels.
   *
   * @param xlabel String
   * @param ylabel String
   * @param frameTitle String
   */

   public PlotFrame(String xlabel, String ylabel, String frameTitle)
   {
     super(new PlottingPanel(xlabel, ylabel, null));
     setTitle(frameTitle);
     drawingPanel.addDrawable(datasetManager);
     datasetManager.setXPointsLinked(true);
     dataTable.add(datasetManager);
     setAnimated(true);
     setAutoclear(true);
     addMenuItems();
   }

   /**
   * Adds Views menu items on the menu bar.
   */

   protected void addMenuItems()
   {
     JMenuBar menuBar = getJMenuBar();
     if(menuBar==null)
     {
       return;
     }
     JMenu helpMenu = this.removeMenu("Help");
     JMenu menu = getMenu("Views");
     if(menu==null)
     {
       menu = new JMenu("Views");
       menuBar.add(menu);
       menuBar.validate();
     }
     else
     { // add a separator if tools already exists
       menu.addSeparator();
     }
     menuBar.add(helpMenu);
     // add a scale option
     JMenuItem scaleItem = new JMenuItem("Scale");
     ActionListener actionListener = new ActionListener()
     {
       public void actionPerformed(ActionEvent e)
       {
         scale();
       }
     };
     scaleItem.addActionListener(actionListener);
     menu.add(scaleItem);
     // add a log scale option
     JMenuItem logItem = new JMenuItem("Log Axes");
     actionListener = new ActionListener()
     {
       public void actionPerformed(ActionEvent e)
       {
         logAxes();
       }
     };
     logItem.addActionListener(actionListener);
     menu.add(logItem);
     menu.addSeparator();
     // add a data table item to show the data table
     JMenuItem tableItem = new JMenuItem("Data Table");
     tableItem.setAccelerator(KeyStroke.getKeyStroke('T', MENU_SHORTCUT_KEY_MASK));
     actionListener = new ActionListener()
     {
       public void actionPerformed(ActionEvent e)
       {
         showDataTable(true);
       }
     };
     tableItem.addActionListener(actionListener);
     menu.add(tableItem);
     // add data table to the popup menu
     if((drawingPanel!=null)&&(drawingPanel.getPopupMenu()!=null))
     {
       JMenuItem item = new JMenuItem("Data Table");
       item.addActionListener(actionListener);
       drawingPanel.getPopupMenu().add(item);
     }
   }

   /**
   * Sets the log scale property for the x axis.
   *
   * @param log boolean
   */

   public void setLogScaleX(boolean log)
   {
     if(drawingPanel instanceof PlottingPanel)
       ((PlottingPanel)drawingPanel).setLogScaleX(log);
   }

   /**
   * Sets the log scale property for the y axis.
   *
   * @param log boolean
   */

   public void setLogScaleY(boolean log)
   {
     if (drawingPanel instanceof PlottingPanel)
       ((PlottingPanel) drawingPanel).setLogScaleX(log);
   }


   protected void scale()
   {
     ScaleInspector plotInspector = new ScaleInspector(drawingPanel);
     plotInspector.setLocationRelativeTo(drawingPanel);
     plotInspector.updateDisplay();
     plotInspector.setVisible(true);
   }

   protected void logAxes()
   {
     if(!(drawingPanel instanceof PlottingPanel))
       return;
     LogAxesInspector logAxesInspector = new LogAxesInspector((PlottingPanel)drawingPanel);
     logAxesInspector.setLocationRelativeTo(drawingPanel);
     logAxesInspector.updateDisplay();
     logAxesInspector.setVisible(true);
   }

   /**
   * Appends an (x,y) datum to the Dataset with the given index.
   *
   * @param datasetIndex Description of Parameter
   * @param x
   * @param y
   */

   public void append(int datasetIndex, double x, double y)
   {
     datasetManager.append(datasetIndex, x, y);
     // may be too slow if lots of data is being added to the table
     if((tableFrame!=null)&&tableFrame.isShowing())
     {
       dataTable.refreshTable();
     }
   }

   /**
   * Appends a data point and its uncertainty to the Dataset.
   *
   * @param datasetIndex
   * @param x
   * @param y
   * @param delx
   * @param dely
   *
   */

   public void append(int datasetIndex, double x, double y, double delx, double dely)
   {
     datasetManager.append(datasetIndex, x, y, delx, dely);
     if((tableFrame!=null)&&tableFrame.isShowing())
     {
       dataTable.refreshTable();
     }
   }

   /**
   * Appends (x,y) arrays to the Dataset.
   *
   * @param datasetIndex Description of Parameter
   * @param xpoints
   * @param ypoints
   */

   public void append(int datasetIndex, double[] xpoints, double[] ypoints)
   {
     datasetManager.append(datasetIndex, xpoints, ypoints);
     if((tableFrame!=null)&&tableFrame.isShowing())
     {
       dataTable.refreshTable();
     }
   }

   /**
   * Appends arrays of data points and uncertainties to the Dataset.
   *
   * @param datasetIndex
   * @param xpoints
   * @param ypoints
   * @param delx
   * @param dely
   */

   public void append(int datasetIndex, double[] xpoints, double[] ypoints, double[] delx, double[] dely)
   {
     datasetManager.append(datasetIndex, xpoints, ypoints, delx, dely);
     if((tableFrame!=null)&&tableFrame.isShowing())
     {
       dataTable.refreshTable();
     }
   }

   /**
   * Sets the connected flag for all datasets.
   *
   * @param connected true if connected; false otherwise
   */

   public void setConnected(boolean connected)
   {
     datasetManager.setConnected(connected);
   }

   /**
   * Sets a custom marker shape.
   *
   * @param datasetIndex int
   * @param marker Shape
   */

   public void setCustomMarker(int datasetIndex, Shape marker)
   {
     datasetManager.setCustomMarker(datasetIndex, marker);
   }

   /**
   * Sets the data point marker shape. Shapes are: NO_MARKER, CIRCLE, SQUARE,
   * AREA, PIXEL, BAR, POST
   *
   * @param datasetIndex The new markerShape value
   * @param markerShape
   */

   public void setMarkerShape(int datasetIndex, int markerShape)
   {
     datasetManager.setMarkerShape(datasetIndex, markerShape);
   }

   /**
   * Sets the half-width of the data point marker.
   *
   * @param datasetIndex
   * @param markerSize in pixels
   */

   public void setMarkerSize(int datasetIndex, int markerSize)
   {
     datasetManager.setMarkerSize(datasetIndex, markerSize);
   }

   /**
   * Sets the data marker color for the given index.
   *
   * @param datasetIndex int
   * @param color Color
   */

   public void setMarkerColor(int datasetIndex, Color color)
   {
     datasetManager.setMarkerColor(datasetIndex, color);
   }

   /**
   * Sets the marker's fill and edge colors.
   *
   * The error bar color is set equal to the edge color.
   *
   * @param datasetIndex
   * @param fillColor
   * @param edgeColor
   */

   public void setMarkerColor(int datasetIndex, Color fillColor, Color edgeColor)
   {
     datasetManager.setMarkerColor(datasetIndex, fillColor, edgeColor);
   }

   /**
   * Sets the data connected flag. Points are connected by straight lines.
   *
   * @param datasetIndex The new connected value
   * @param connected <code>true<\code> if points are connected
   */

   public void setConnected(int datasetIndex, boolean connected)
   {
     datasetManager.setConnected(datasetIndex, connected);
   }

   /**
   * Sets the linked flag. X data for datasets > 0 will not be shown in a table view.
   *
   * @param linked The new value
   */

   public void setXPointsLinked(boolean linked)
   {
     datasetManager.setXPointsLinked(linked);
   }

   /**
   * Sets the column names and the dataset name.
   *
   * @param datasetIndex The new xYColumnNames value
   * @param xColumnName
   * @param yColumnName
   * @param datasetName
   */

   public void setXYColumnNames(int datasetIndex, String xColumnName, String yColumnName, String datasetName)
   {
     datasetManager.setXYColumnNames(datasetIndex, xColumnName, yColumnName, datasetName);
   }

   /**
   * Sets the column names when rendering this dataset in a JTable.
   *
   * @param datasetIndex The new xYColumnNames value
   * @param xColumnName
   * @param yColumnName
   */

   public void setXYColumnNames(int datasetIndex, String xColumnName, String yColumnName)
   {
     datasetManager.setXYColumnNames(datasetIndex, xColumnName, yColumnName);
   }

   /**
   * Sets the maximum number of fraction digits to display for cells that have
   * type Double
   *
   * @param maximumFractionDigits - maximum number of fraction digits to display
   */

   public void setMaximumFractionDigits(int maximumFractionDigits)
   {
     dataTable.setMaximumFractionDigits(maximumFractionDigits);
   }

   /**
   * Sets the maximum number of fraction digits to display in all data table columns with
   * cthe given columnName.
   *
   * @param maximumFractionDigits - maximum number of fraction digits to display
   * @param columnName The new maximumFractionDigits value
   */

   public void setMaximumFractionDigits(String columnName, int maximumFractionDigits)
   {
     dataTable.setMaximumFractionDigits(columnName, maximumFractionDigits);
   }

   /**
   * Sets the display row number flag. Table displays row number.
   *
   * @param vis <code>true<\code> if table display row number
   */

   public void setRowNumberVisible(boolean vis)
   {
     dataTable.setRowNumberVisible(vis);
   }

   /**
   * Clears drawable objects added by the user from this frame.
   */

   public void clearDrawables()
   {
     drawingPanel.clear(); // removes all drawables
     drawingPanel.addDrawable(datasetManager);
   }

   /**
   * Gets a dataset with the given index.
   *
   * @param datasetIndex
   * @return the index
   *
   */

   public Dataset getDataset(int index)
   {
     return datasetManager.getDataset(index);
   }

   /**
   * Gets Drawable objects added by the user to this frame.
   *
   * @return the list
   */

   public synchronized ArrayList getDrawables()
   {
     ArrayList list = super.getDrawables();
     list.remove(datasetManager);
     return list;
   }

   /**
   * Gets Drawable objects added by the user of an assignable type. The list contains
   * objects that are assignable from the class or interface.
   *
   * @param c the type of Drawable object
   *
   * @return the cloned list
   *
   * @see #getObjectOfClass(Class c)
   */

   public synchronized ArrayList getDrawables(Class c)
   {
     ArrayList list = super.getDrawables(c);
     list.remove(datasetManager);
     return list;
   }

   /**
   * Clears the data from all datasets and removes all objects from the drawing panel except the dataset manager.
   *
   * Dataset properties are preserved because only the data is cleared.
   */

   public void clearData()
   {
     datasetManager.clear();
     dataTable.refreshTable();
     drawingPanel.invalidateImage();
   }

   /**
   * Shows or hides the data table.
   *
   * @param show boolean
   */

   public synchronized void showDataTable(boolean show)
   {
     if(show)
     {
       if(tableFrame==null)
       {
         tableFrame = new DataTableFrame(getTitle()+" Data", dataTable);
         tableFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       }
       dataTable.refreshTable();
       tableFrame.setVisible(true);
     }
     else
     {
       tableFrame.setVisible(false);
       tableFrame.dispose();
       tableFrame = null;
     }
   }

   /**
   * Returns an XML.ObjectLoader to save and load data.
   *
   * @return the object loader
   */

   public static XML.ObjectLoader getLoader()
   {
     return new PlotFrameLoader();
   }

   static protected class PlotFrameLoader extends DrawingFrame.DrawingFrameLoader
   {
     /**
     * Creates a PlotFame.
     *
     * @param element XMLControl
     * @return Object
     */

     public Object createObject(XMLControl control)
     {
       PlotFrame frame = new PlotFrame("x","y","Plot Frame");
       return frame;
     }

     /**
     * Loads the object with data from the control.
     *
     * @param element XMLControl
     * @param obj Object
     * @return Object
     */

     public Object loadObject(XMLControl control, Object obj)
     {
       super.loadObject(control,obj);
       PlotFrame frame = ((PlotFrame) obj);
       ArrayList list=frame.getObjectOfClass(DatasetManager.class);
       if(list.size()>0)
       { // assume the first DatasetManager is the manager for this frame
         frame.datasetManager=(DatasetManager)list.get(0);
         frame.dataTable.clear();
         frame.dataTable.add(frame.datasetManager);
       }
       return obj;
     }
   }
}