/* My first graphing applet. */ /* Need to: put in a status line. see why it doesn't use the full range of ymin to ymax when I change functions. put tick marks into a function. */ import java.awt.*; import java.util.*; import java.applet.Applet; public class SimplePlot extends Applet { TextField fromFld, toFld; String MyText; Label label, toLabel, fromLabel, statusLabel; PlotCanvas canvas; public int i; Button redb, blueb, domainChangeb; Color color; Panel panel1, panel2, bottomPanel, statusPanel, xdomainPanel; Choice fnChoice; float beginXmin = -100, beginXmax = 100; public void init() { setLayout(new BorderLayout(5,5)); panel1 = new Panel(); label = new Label("Plotting a Function"); panel1.add(label); add("North", panel1); panel2 = new Panel(); panel2.setLayout(new GridLayout(0,1,5,5)); panel2.add(new Label("Choose a Color")); redb = new Button("RED"); redb.setBackground(Color.red); panel2.add(redb); blueb = new Button("BLUE"); blueb.setBackground(Color.blue); panel2.add(blueb); panel2.add(new Label("Choose a Function")); fnChoice = new Choice(); fnChoice.addItem("x^2"); fnChoice.addItem("x + 30"); fnChoice.addItem("x^3"); fnChoice.addItem("x^2 + x - 52"); panel2.add(fnChoice); add("East", panel2); canvas = new PlotCanvas(this); add("Center", canvas); fromLabel = new Label("-100"); /* Bottom Panel, with from and to and status line. */ bottomPanel = new Panel(); bottomPanel.setLayout(new GridLayout(0,1,5,5)); /* Domain panel */ xdomainPanel = new Panel(); xdomainPanel.add(new Label("Plot x from : ")); fromFld = new TextField("-100", 7); canvas.setXmin(-100); xdomainPanel.add(fromFld); xdomainPanel.add(new Label("to : ")); toFld = new TextField("100", 10); canvas.setXmax(100); xdomainPanel.add(toFld); domainChangeb = new Button ("Change Domain"); xdomainPanel.add(domainChangeb); bottomPanel.add(xdomainPanel); /* Status Line */ statusPanel = new Panel(); statusLabel = new Label(" "); statusLabel.setForeground(Color.magenta); statusPanel.add(statusLabel); bottomPanel.add(statusPanel); add("South", bottomPanel); } /** Draws a box around this panel. */ public void paint(Graphics g) { Dimension d = size(); g.drawRect(0,0, d.width - 1, d.height - 1); } public Insets insets() { return new Insets(5,5,5,8); } public boolean handleEvent(Event e) { int newFn; try { if ((e.target instanceof Button) && (e.id == Event.ACTION_EVENT)) { if (e.target == redb) { canvas.changeColor(Color.red); } else if (e.target == blueb) { canvas.changeColor(Color.blue); } else if (e.target == domainChangeb) { float newXmin = 0, newXmax = 0; /* Do this to get rid of a possible "Domain must be a number" message */ statusLabel.setText(" "); newXmin = Float.valueOf(fromFld.getText()).floatValue(); newXmax = Float.valueOf(toFld.getText()).floatValue(); if (newXmax <= newXmin) { statusLabel.setText("From must be less than To"); } else { canvas.setXmin(newXmin); canvas.setXmax(newXmax); } } canvas.repaint(); } else if (e.target instanceof Choice && e.id == Event.ACTION_EVENT) { newFn = fnChoice.getSelectedIndex(); canvas.setFn(newFn); canvas.repaint(); } } catch (NumberFormatException e1) { statusLabel.setText("Domain must be a number"); System.out.println(e1); } return false; } } /* End of class */ class PlotCanvas extends Canvas { SimplePlot containedBy; public int mousex, mousey; public boolean isMouse = false; int timeThrough = 0; Color color = Color.green; int inset = 20; int fn = 0; float ymax, ymin, xmax, xmin; PlotCanvas(SimplePlot containedByIn) { super(); containedBy = containedByIn; xmin = -100; xmax = 100; } public void changeColor (Color inColor) { color = inColor; } public void setFn(int newFn) { fn = newFn; } public void setXmin(float newXmin) { xmin = newXmin; } public float getXmin() { return(xmin); } public void setXmax(float newXmax) { xmax = newXmax; } /** Draws a box around this panel, plus other stuff. */ public void paint(Graphics g) { int x, y; Dimension d = size(); /* These need to be made into floats. */ float xcur, ycur; float xplot, yplot; PlotCoord pc; g.drawRect(0,0, d.width - 1, d.height - 1); g.setColor(color); /* This time through is just to find out what the max y value is. */ ymax = 0; ymin = 0; float stepSize = (xmax - xmin)/50; for (xcur = xmin; xcur <= xmax; xcur += stepSize) { /* The function we are going to plot. */ ycur = func(xcur); if (ycur > ymax) ymax = ycur; if (ycur < ymin) ymin = ycur; } pc = new PlotCoord (xmax, ymax, xmin, ymin, d.width, d.height, inset); int xcoord = 0, ycoord = 0; g.setColor(Color.black); float xaxisStart = xmax, xaxisEnd = xmin, xaxisPosy; float yaxisStart = ymax, yaxisEnd = ymin, yaxisPosx;; /* Axis rules: If 0 is on the map, print out the axis there. If 0 is not on the map, print out the axis on the minimum. */ if (xmin < 0 && xmax > 0) yaxisPosx = 0; else yaxisPosx = xmin; if (ymin < 0 && ymax > 0) xaxisPosy = 0; else xaxisPosy = ymin ; /* System.out.println("Yaxis at x = " + yaxisPosx + " Xaxis at y = " + xaxisPosy); */ Font f = new Font ("Dialog", Font.PLAIN, 10); g.setFont(f); /* Draw x axis. */ g.drawLine(pc.xcoord(xaxisStart), pc.ycoord(xaxisPosy), pc.xcoord(xaxisEnd), pc.ycoord(xaxisPosy)); /* Draw y axis. */ g.drawLine(pc.xcoord(yaxisPosx), pc.ycoord(yaxisStart), pc.xcoord(yaxisPosx), pc.ycoord(yaxisEnd)); /* This draws one tick mark on y */ ycoord = pc.ycoord(ymin + (ymax - ymin)/2); xcoord = pc.xcoord(yaxisPosx); g.drawLine(xcoord+3, ycoord , xcoord - 3, ycoord); g.drawString( new Integer(Math.round(ymin + (ymax - ymin)/2)).toString(), xcoord + 5, ycoord + 10); /* This draws one tick mark on x */ xcoord = pc.xcoord(xmin + (xmax - xmin)/2); ycoord = pc.ycoord(xaxisPosy); g.drawLine(xcoord, ycoord + 3, xcoord , ycoord - 3); g.drawString( new Integer(Math.round(xmin + (xmax - xmin)/2)).toString(), xcoord -5, ycoord + 15); /* draw a tick at 0 if it is on the graph */ if (xmin < 0 && xmax > 0) { xcoord = pc.xcoord(0); ycoord = pc.ycoord(xaxisPosy); g.drawLine(xcoord, ycoord + 3, xcoord , ycoord - 3); g.drawString("0", xcoord -5, ycoord + 15); } if (ymin < 0 && ymax > 0) { ycoord = pc.ycoord(0); xcoord = pc.xcoord(yaxisPosx); g.drawLine(xcoord+3, ycoord , xcoord - 3, ycoord); g.drawString("0", xcoord + 7, ycoord + 10); } /* Draw tick marks at the max's. */ /* This draws one tick mark on y */ ycoord = pc.ycoord(ymax); xcoord = pc.xcoord(yaxisPosx); g.drawLine(xcoord+3, ycoord , xcoord - 3, ycoord); g.drawString( new Integer(Math.round(ymax)).toString(), xcoord + 5, ycoord + 10); /* This draws one tick mark on x */ xcoord = pc.xcoord(xmax); ycoord = pc.ycoord(xaxisPosy); g.drawLine(xcoord, ycoord + 3, xcoord , ycoord - 3); g.drawString( new Integer(Math.round(xmax)).toString(), xcoord - 5, ycoord + 15); /* end of tick marks at the max's. */ g.setColor(color); int xcoordPrev = 0, ycoordPrev = 0; float xprev = 0, yprev = 0; stepSize = (xmax - xmin)/50; for (xcur = xmin; xcur <= xmax; xcur += stepSize) { ycur = func(xcur); xcoord = pc.xcoord(xcur); ycoord = pc.ycoord(ycur); /* ie, don't do the very first x */ if (xcur != xmin) { /*if (xcur > -0.01 && xcur < 0.01 ) System.out.println( xprev + ":" + xcoordPrev + " " + yprev + ":" + ycoordPrev + " " + xcur + ":" + xcoord + " " + ycur + ":" + ycoord);*/ /* g.drawOval(xcoord-3, ycoord-3, 6, 6);*/ g.drawLine(xcoordPrev, ycoordPrev, xcoord, ycoord); } xcoordPrev = xcoord; ycoordPrev = ycoord; xprev = xcur; yprev = ycur; } } float func( float x) { float retval; switch (fn) { case 0: retval = x * x; break; case 1: retval = x + 30; break; case 2: retval = x * x * x; break; case 3: retval = x * x + x - 52; break; default: System.out.println("Bad function number"); retval = -1; } return(retval); } /* public boolean mouseDown(Event e, int x, int y) { Graphics gc; gc = getGraphics(); isMouse = true; mousex = x; mousey = y; System.out.println("Got a mouse event at " + x + ", " + y); gc.setColor(color); System.out.println(color); System.out.println(gc.getColor()); gc.drawLine(mousex, mousey, mousex + 50, mousey + 10); return true; } */ } class PlotCoord { float xstretch = 1; float ystretch = 1; float xshift = 0; float yshift = 0; float ywholeScreen; int inset; /* How far from the edge the display is */ PlotCoord(float xmax, float ymax, float xmin, float ymin, int width, int height, int insetin ) { inset = insetin; xstretch = (width - (2 * inset))/ (xmax - xmin); ystretch = (height - (2 * inset)) / (ymax - ymin); xshift = -xmin; yshift = -ymin; ywholeScreen = ymax - ymin; } /* Return the X and Y coordinates on the canvas. */ int xcoord(float x) { float xcoordFloat; xcoordFloat = (x + xshift) * xstretch + inset; return(Math.round(xcoordFloat)); } int ycoord(float y) { float ycoordFloat; ycoordFloat = (ywholeScreen - (y + yshift)) * ystretch + inset; return(Math.round(ycoordFloat)); } }