package com.srbenoit.math.grapher;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import com.srbenoit.log.LoggedObject;
import com.srbenoit.ui.UIUtilities;
/**
* A graphing tool that renders the graph of a function.
*/
public class Grapher extends LoggedObject {
/** PNG file format */
private static final String PNG = "PNG";
/** JPEG file format */
private static final String JPEG = "JPEG";
/** GIF file format */
private static final String GIF = "GIF";
/** BMP file format */
private static final String BMP = "BMP";
/** WBMP file format */
private static final String WBMP = "WBMP";
/** the image that displays the graph */
private final transient GraphImage image;
/**
* Create a Grapher
to render a function's graph.
*
* @param xSize the width of graphs to generate
* @param ySize the height of graphs to generate
*/
public Grapher(final int xSize, final int ySize) {
super();
this.image = new GraphImage(xSize, ySize);
}
/**
* Gets the GraphImage
that this grapher draws to.
*
* @return the GraphImage
*/
public GraphImage getGraphImage() {
return this.image;
}
/**
* Renders the graph.
*
* @param functions the functions to be graphed
*/
public void graph(final Graphable... functions) {
this.image.graph(functions);
}
/**
* Exports the image of the graph to a file.
*
* @param file the file to which to export
* @throws IOException if there is an error writing the file
*/
public void export(final File file) throws IOException {
String fname;
int pos;
String ext;
String format;
File target;
fname = file.getName();
pos = fname.lastIndexOf('.');
if (pos == -1) {
format = JPEG;
target = new File(file.getParent(), file.getName() + ".jpg");
} else {
ext = fname.substring(pos + 1).toUpperCase();
if (("JPG".equals(ext)) || (JPEG.equals(ext))) {
format = JPEG;
target = file;
} else if (PNG.equals(ext)) {
format = PNG;
target = file;
} else if (GIF.equals(ext)) {
format = GIF;
target = file;
} else if (BMP.equals(ext)) {
format = BMP;
target = file;
} else if (WBMP.equals(ext)) {
format = WBMP;
target = file;
} else {
format = JPEG;
target = new File(file.getParent(), file.getName() + ".jpg");
}
}
ImageIO.write(this.image.getImage(), format, target);
}
/**
* Builds a JFrame
and displays the grapher in that frame.
*
* @param title the frame title
*/
public void showInFrame(final String title) {
FrameBuilder builder;
builder = new FrameBuilder(this, title);
SwingUtilities.invokeLater(builder);
}
/**
* Class to construct a frame and display the grapher as its content pane from within the AWT
* event thread.
*/
private static class FrameBuilder implements Runnable {
/** the Grapher
whose panel is to be shown in the frame */
private final Grapher grapher;
/** the frame title */
private final String frameTitle;
/**
* Constructs a new FrameBuilder
.
*
* @param grapherToShow the Grapher
whose panel is to be shown in the frame
* @param title the frame title
*/
protected FrameBuilder(final Grapher grapherToShow, final String title) {
this.grapher = grapherToShow;
this.frameTitle = title;
}
/**
* Builds the frame and installs the Grapher
's panel is its content pane.
*/
public void run() {
JFrame frame;
JLabel label;
frame = new JFrame(this.frameTitle);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
label = new JLabel(new ImageIcon(this.grapher.getGraphImage().getImage()));
frame.setContentPane(label);
frame.pack();
UIUtilities.positionFrame(frame, 0.5, 0.5);
frame.setVisible(true);
}
}
}