Files
2016-04-27 01:07:35 -04:00

547 lines
14 KiB
Java

//******************************************************************************
//
// File: PlotFrame.java
// Package: edu.rit.numeric.plot
// Unit: Class edu.rit.numeric.plot.PlotFrame
//
// This Java source file is copyright (C) 2013 by Alan Kaminsky. All rights
// reserved. For further information, contact the author, Alan Kaminsky, at
// ark@cs.rit.edu.
//
// This Java source file is part of the Parallel Java 2 Library ("PJ2"). PJ2 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 3 of the License, or (at your option) any later version.
//
// PJ2 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.
//
// A copy of the GNU General Public License is provided in the file gpl.txt. You
// may also obtain a copy of the GNU General Public License on the World Wide
// Web at http://www.gnu.org/licenses/gpl.html.
//
//******************************************************************************
package edu.rit.numeric.plot;
import edu.rit.swing.Displayable;
import edu.rit.swing.DisplayableFrame;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
/**
* Class PlotFrame is a {@linkplain edu.rit.swing.DisplayableFrame
* DisplayableFrame} for viewing a {@linkplain Plot} object on the screen. The
* plot object is specified when the viewer is constructed.
* <P>
* To display a plot in a window on the screen, construct an instance of class
* PlotFrame; call <TT>setSize()</TT> to set the viewer window's size if
* desired; and call <TT>setVisible(true)</TT> to display the viewer window.
* <P>
* The viewer window includes a "File" menu with menu items for saving the plot
* in a PNG file, saving the plot in a PostScript file, and closing the window.
* <P>
* The viewer window includes a "View" menu with menu items for zooming in and
* out. When the plot is saved in a PNG file, the plot is saved at its zoomed
* size. When the plot is saved in a PostScript file, the plot is saved at its
* normal (unzoomed) size.
* <P>
* The viewer window includes a "Format" menu with menu items for setting the
* various plot attributes interactively.
* <P>
* When the viewer window is closed, either by using the "File" menu or by
* clicking the window's close box, one of three possible operations is
* performed: hide the window; hide and dispose the window; or exit the
* application. The close operation is specified when the viewer window is
* constructed. The default close operation is to hide and dispose the window.
*
* @author Alan Kaminsky
* @version 20-Dec-2007
*/
class PlotFrame
extends DisplayableFrame
{
// Hidden data members.
private Plot myPlot;
private TitleDialog myPlotTitleDialog;
private PlotMarginsDialog myPlotMarginsDialog;
private PlotAreaDialog myPlotAreaDialog;
private AxisDialog myXAxisDialog;
private TitleDialog myXAxisTitleDialog;
private AxisDialog myYAxisDialog;
private TitleDialog myYAxisTitleDialog;
// Exported constructors.
/**
* Construct a new plot viewer. The frame has no title. The frame is
* initially invisible. When the frame is closed, the frame is hidden and
* disposed.
*
* @param thePlot Plot object.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>thePlot</TT> is null.
*/
public PlotFrame
(Plot thePlot)
{
super (thePlot);
initialize (thePlot);
}
/**
* Construct a new plot viewer with the given title. The frame is initially
* invisible. When the frame is closed, the frame is hidden and disposed.
*
* @param theTitle Title.
* @param thePlot Plot object.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>thePlot</TT> is null.
*/
public PlotFrame
(String theTitle,
Plot thePlot)
{
super (theTitle, thePlot);
initialize (thePlot);
}
/**
* Construct a new plot viewer. The frame has no title. The frame is
* initially invisible. When the frame is closed, <TT>theCloseOperation</TT>
* specifies what to do.
*
* @param thePlot Plot object.
* @param theCloseOperation What to do when the frame is closed, one of
* the following: <TT>JFrame.HIDE_ON_CLOSE</TT>,
* <TT>JFrame.DISPOSE_ON_CLOSE</TT>, or
* <TT>JFrame.EXIT_ON_CLOSE</TT>.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>thePlot</TT> is null.
* @exception IllegalArgumentException
* (unchecked exception) Thrown if <TT>theCloseOperation</TT> is
* invalid.
*/
public PlotFrame
(Plot thePlot,
int theCloseOperation)
{
super (thePlot, theCloseOperation);
initialize (thePlot);
}
/**
* Construct a new plot viewer with the given title. The frame is initially
* invisible. When the frame is closed, <TT>theCloseOperation</TT> specifies
* what to do.
*
* @param theTitle Title.
* @param thePlot Plot object.
* @param theCloseOperation What to do when the frame is closed, one of
* the following: <TT>JFrame.HIDE_ON_CLOSE</TT>,
* <TT>JFrame.DISPOSE_ON_CLOSE</TT>, or
* <TT>JFrame.EXIT_ON_CLOSE</TT>.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>thePlot</TT> is null.
* @exception IllegalArgumentException
* (unchecked exception) Thrown if <TT>theCloseOperation</TT> is
* invalid.
*/
public PlotFrame
(String theTitle,
Plot thePlot,
int theCloseOperation)
{
super (theTitle, thePlot, theCloseOperation);
initialize (thePlot);
}
/**
* Initialize a newly constructed plot viewer.
*
* @param thePlot Plot.
*/
private void initialize
(Plot thePlot)
{
// Record plot.
if (thePlot == null)
{
throw new NullPointerException
("PlotFrame(): thePlot is null");
}
myPlot = thePlot;
// Add item to File menu.
JMenuBar menubar = getJMenuBar();
JMenu fileMenu = menubar.getMenu (0);
JMenuItem saveAsDrawingItem =
new JMenuItem ("Save as Drawing...", KeyEvent.VK_D);
saveAsDrawingItem.setAccelerator
(KeyStroke.getKeyStroke (KeyEvent.VK_D, InputEvent.CTRL_MASK));
saveAsDrawingItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doSaveAsDrawing();
}
});
fileMenu.insert (saveAsDrawingItem, 3);
// Add item to View menu.
JMenu viewMenu = menubar.getMenu (1);
JMenuItem windowTitleItem =
new JMenuItem ("Window Title...", KeyEvent.VK_T);
windowTitleItem.setAccelerator
(KeyStroke.getKeyStroke (KeyEvent.VK_T, InputEvent.CTRL_MASK));
windowTitleItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doWindowTitle();
}
});
viewMenu.add (windowTitleItem);
// Create Format menu.
JMenu formatMenu = new JMenu ("Format");
formatMenu.setMnemonic (KeyEvent.VK_O);
JMenuItem titleItem =
new JMenuItem ("Plot Title...", KeyEvent.VK_P);
titleItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doPlotTitle();
}
});
formatMenu.add (titleItem);
JMenuItem marginsItem =
new JMenuItem ("Margins...", KeyEvent.VK_M);
marginsItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doMargins();
}
});
formatMenu.add (marginsItem);
JMenuItem areaItem =
new JMenuItem ("Plot Area...", KeyEvent.VK_A);
areaItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doPlotArea();
}
});
formatMenu.add (areaItem);
JMenuItem xAxisItem =
new JMenuItem ("X Axis...", KeyEvent.VK_X);
xAxisItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doXAxis();
}
});
formatMenu.add (xAxisItem);
JMenuItem xAxisTitleItem =
new JMenuItem ("X Axis Title...", KeyEvent.VK_I);
xAxisTitleItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doXAxisTitle();
}
});
formatMenu.add (xAxisTitleItem);
JMenuItem yAxisItem =
new JMenuItem ("Y Axis...", KeyEvent.VK_Y);
yAxisItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doYAxis();
}
});
formatMenu.add (yAxisItem);
JMenuItem yAxisTitleItem =
new JMenuItem ("Y Axis Title...", KeyEvent.VK_T);
yAxisTitleItem.addActionListener (new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
doYAxisTitle();
}
});
formatMenu.add (yAxisTitleItem);
// Add Format menu to menu bar.
menubar.add (formatMenu);
// Arrange to handle the window closing.
addWindowListener (new WindowAdapter()
{
public void windowClosing (WindowEvent e)
{
doClose();
}
});
}
// Exported operations.
/**
* Tell this displayable object viewer to display the given displayable
* object.
*
* @param theDisplayable Displayable object.
*
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>theDisplayable</TT> is null.
* @exception ClassCastException
* (unchecked exception) Thrown if <TT>theDisplayable</TT> is not an
* instance of class {@linkplain Plot}.
*/
public void display
(Displayable theDisplayable)
{
myPlot = (Plot) theDisplayable;
super.display (theDisplayable);
}
// Hidden operations.
/**
* "Save as Drawing..." menu item.
*/
private void doSaveAsDrawing()
{
saveFile
(".dwg",
"Serialized drawing object files",
new DisplayableFrame.FileSaver()
{
public void saveFile (File file) throws IOException
{
Plot.write (myPlot, file);
}
});
}
/**
* "Window Title..." menu item.
*/
private void doWindowTitle()
{
String newTitle =
JOptionPane.showInputDialog
(this,
"Window title:",
myPlot.getTitle());
if (newTitle != null)
{
myPlot.frameTitle (newTitle);
setTitle (newTitle);
}
}
/**
* "Plot Title..." menu item.
*/
private void doPlotTitle()
{
// Create plot title dialog if necessary.
if (myPlotTitleDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myPlotTitleDialog = new TitleDialog (this, "Plot");
setCursor (Cursor.getDefaultCursor());
}
myPlotTitleDialog.setLocationRelativeTo (this);
if (myPlot.formatPlotTitle (myPlotTitleDialog))
{
setTitle (myPlot.getTitle());
repaint();
}
}
/**
* "Margins..." menu item.
*/
private void doMargins()
{
// Create plot margins dialog if necessary.
if (myPlotMarginsDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myPlotMarginsDialog = new PlotMarginsDialog (this);
setCursor (Cursor.getDefaultCursor());
}
myPlotMarginsDialog.setLocationRelativeTo (this);
if (myPlot.formatPlotMargins (myPlotMarginsDialog))
{
repaint();
}
}
/**
* "Plot Area..." menu item.
*/
private void doPlotArea()
{
// Create plot area dialog if necessary.
if (myPlotAreaDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myPlotAreaDialog = new PlotAreaDialog (this);
setCursor (Cursor.getDefaultCursor());
}
myPlotAreaDialog.setLocationRelativeTo (this);
if (myPlot.formatPlotArea (myPlotAreaDialog))
{
repaint();
}
}
/**
* "X Axis..." menu item.
*/
private void doXAxis()
{
// Create X axis dialog if necessary.
if (myXAxisDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myXAxisDialog = new AxisDialog (this, "X");
setCursor (Cursor.getDefaultCursor());
}
myXAxisDialog.setLocationRelativeTo (this);
if (myPlot.formatXAxis (myXAxisDialog))
{
repaint();
}
}
/**
* "X Axis Title..." menu item.
*/
private void doXAxisTitle()
{
// Create X axis title dialog if necessary.
if (myXAxisTitleDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myXAxisTitleDialog = new TitleDialog (this, "X Axis");
setCursor (Cursor.getDefaultCursor());
}
myXAxisTitleDialog.setLocationRelativeTo (this);
if (myPlot.formatXAxisTitle (myXAxisTitleDialog))
{
repaint();
}
}
/**
* "Y Axis..." menu item.
*/
private void doYAxis()
{
// Create Y axis dialog if necessary.
if (myYAxisDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myYAxisDialog = new AxisDialog (this, "Y");
setCursor (Cursor.getDefaultCursor());
}
myYAxisDialog.setLocationRelativeTo (this);
if (myPlot.formatYAxis (myYAxisDialog))
{
repaint();
}
}
/**
* "Y Axis Title..." menu item.
*/
private void doYAxisTitle()
{
// Create Y axis title dialog if necessary.
if (myYAxisTitleDialog == null)
{
setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR));
myYAxisTitleDialog = new TitleDialog (this, "Y Axis");
setCursor (Cursor.getDefaultCursor());
}
myYAxisTitleDialog.setLocationRelativeTo (this);
if (myPlot.formatYAxisTitle (myYAxisTitleDialog))
{
repaint();
}
}
/**
* "Close" or "Quit" menu item.
*/
private void doClose()
{
if (myPlotTitleDialog != null)
{
myPlotTitleDialog.dispose();
myPlotTitleDialog = null;
}
if (myPlotMarginsDialog != null)
{
myPlotMarginsDialog.dispose();
myPlotMarginsDialog = null;
}
if (myPlotAreaDialog != null)
{
myPlotAreaDialog.dispose();
myPlotAreaDialog = null;
}
if (myXAxisTitleDialog != null)
{
myXAxisTitleDialog.dispose();
myXAxisTitleDialog = null;
}
if (myYAxisTitleDialog != null)
{
myYAxisTitleDialog.dispose();
myYAxisTitleDialog = null;
}
}
}