[ prev | main | next ]

Graph Applet 1



This is a simple applet that draws the graph of a function
input by the user. Enter the function in box at the bottom of
the applet and press return. You can click on the graph to
zoom in on a point. Shift-click to zoom out from a point.
Or drag the mouse to draw a rectangle that is then zoomed
to fill the whole graph area.

The source code for this applet shows how it was assembled
from WCM components:


import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JApplet;

import net.sourceforge.webcompmath.awt.Controller;
import net.sourceforge.webcompmath.awt.ExpressionInput;
import net.sourceforge.webcompmath.awt.WcmPanel;
import net.sourceforge.webcompmath.data.Function;
import net.sourceforge.webcompmath.data.Parser;
import net.sourceforge.webcompmath.data.Variable;
import net.sourceforge.webcompmath.draw.WcmAxes;
import net.sourceforge.webcompmath.draw.DisplayCanvas;
import net.sourceforge.webcompmath.draw.Graph1D;
import net.sourceforge.webcompmath.draw.LimitControlPanel;

/**
* This applet is an example of how to build a math applet using WCM
*/
public class GraphApplet1 extends JApplet {

private static final long serialVersionUID = 1438942325448620289L;

/**
* This overrides init() in JApplet to actually create the applet.
*
* @see java.applet.Applet#init()
*/
public void init() {

Parser parser = new Parser();
/*
* The Parser will take the user's input and turn it into an Expression.
* By default, a Parser knows about the constants pi and e, the basic
* arithmetic operations + - * / ^ (where ^ is exponentiation), standard
* functions (sin, cos, tan, sec, csc, cot, sqrt, cubert, abs, ln, log2,
* log10, exp, trunc, round, floor, ceiling, arcsin, arccos, arctan).
* There is also a conditional "?" operator in the style of Java and
* C++.
*/

Variable x = new Variable("x");
parser.add(x);
/*
* For the parser to know about the variable x, that variable must be
* created and added to the parser.
*/

DisplayCanvas canvas = new DisplayCanvas();
/*
* A DisplayCanvas is the fundamental WCM class for displaying graphical
* items such as axes and graphs.
*/

canvas.setHandleMouseZooms(true);
/*
* This tells the canvas to let the user zoom in and out by clicking,
* shift-clicking, and click-and-dragging on the canvas.
*/

LimitControlPanel limits = new LimitControlPanel();
/*
* A limit control panel can control the x- and y-limits on a
* DisplayCanvas. In the applet, the limit control panel is the gray
* area containing the input boxes for xmin, xmax, ymin, and ymax. It
* also contains a "Set Limits" button (and can contain other buttons if
* you want). The "Set Limits" button is a little redundant because
* pressing return in any of the input boxes will accomplish the same
* thing. However, it has the advantage of giving the user something
* obvious to do to set the limits.
*/

limits.addCoords(canvas);
/*
* Tells the LimitControlPanel to control the x- and y-limits on this
* canvas. The limits on the canvas and the values in the input boxes
* are synchronized. (Try it by clicking on the graph.)
*/

ExpressionInput input = new ExpressionInput("sin(x)+2*cos(3*x)", parser);
/*
* An ExpressionInput is a text-input box where the user can enter an
* expression. The string "sin(x)+2*cos(3*x)" provides the initial
* contents for the box. The parser that is provided as the second
* arguments knows about the variable named "x", which makes it possible
* to use "x" in the expression.
*/

Function func = input.getFunction(x);
/*
* To graph, I need a Function, not not an expression.
* input.getFunction(x) gets the contents of the ExpressionInput, input,
* considered as a function of the variable x.
*/

Graph1D graph = new Graph1D(func);
/*
* This represents a graph of the function, func. It will be added to
* the DisplayCanvas, which will make it appear on the screen.
*/

WcmPanel main = new WcmPanel();
/*
* The interface for this applet is constructed entirely from JCMPanels.
* This makes much of the JCM setup automatic. This constructor makes a
* JCMPanel that uses a BorderLayout.
*/

main.add(canvas, BorderLayout.CENTER); // Add the DisplayCanvas to the
// panel.
main.add(input, BorderLayout.SOUTH); // Add the ExprssionInput.
main.add(limits, BorderLayout.EAST); // Add the LimitControlPanel.

main.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
/*
* This leaves a gap of 3 pixels around the edges of the panel, where
* the gray background shows through.
*/

setLayout(new BorderLayout()); // Set up the Applet itself.
add(main, BorderLayout.CENTER);
setBackground(Color.lightGray);

canvas.add(new WcmAxes());
/*
* Add a set of Axes to the DisplayCanvas. The labels on the applet are
* automatically adjusted when the limits on the canvas changes.
*/

canvas.add(graph);
/*
* Add the graph to the canvas. It will be redrawn whenever necessary.
*/

Controller controller = main.getController();
/*
* A Controller is what makes things happen in a WCM applet. The
* WcmPanel, main, has a controller that recomputes the WCM components
* in the Panel.
*/

controller.setErrorReporter(canvas);
/*
* Errors in the user's input need to be reported somehow. A Controller
* can have an ErrorReporter for this purpose. Currently, the
* alternatives are to use a canvas as an error reporter or to use a
* "MessagePopup". To see an error message in the applet, enter any
* expression with a syntax error and press return. Note that the
* blinking input cursor moves to the point in the expression where the
* error was discovered.
*/

limits.setErrorReporter(canvas);
/*
* A LimitControlPanel also needs a place to report errors in the user's
* input.
*/

main.gatherInputs();
/*
* The WcmPanel must be told to respond to user inputs. The
* gatherInputs() method is an easy way to do this, in many cases. In
* this applet, since there is only one input, this is equivalent to the
* single command "input.setOnUserAction(controller)," which tells the
* input object to notify the controller when the user presses return in
* the input box. (Note that input boxes in a LimitControlPanel are
* taken care of automatically. They don't need to notify a controller.
* Also note that I couldn't use the gatherInputs(controller) method in
* the previous ArithmeticApplet, since gatherInputs() calls the
* setOnUserAction() method of an input box, but in the
* ArithmeticApplet, I wanted to call setOnTextChange(). The difference
* is that with setOnUserAction(), the controller is notified only when
* the user presses return in the input box while with
* setOnTextChange(), the controller is notified each time the text in
* the input box changes.)
*/

} // end init()

} // end class SimpleGraph1


[ prev | main | next ]