I am trying to program a basic plotter using Applets. I need to use Applets specifically.
For the polt I have created a separate Canvas, but I have encountered a problem I cannot solve. When I draw any graph for the first time, it is drawn nicely. However, the canvas is not being repainted properly afterwards - I see in the debugging screen that the repaint() method was called and the paint() is invoked, but no graphics are updated.
Here is the code:
public class MyCanvas extends Canvas{
int w,h; //width and height
int samples;
ArrayList<Double> eqValues = new ArrayList<>();
MyCanvas(int wi, int he) //constructor
{ w=wi; h=he;
setSize(w,h); //determine size of canvas
samples=wi-20;
}
public void paint(Graphics g)
{
int y0=0, y1; //previous and new function value
g.setColor(Color.yellow);
g.fillRect(0,0,w,h); //clear canvas
g.setColor(Color.black);
if (eqValues.size()>0) { // draw new graph
for (int t = 1; t <= samples; t = t + 1) {
y1 = eqValues.get(t).intValue();
g.drawLine(10 + t - 1, h - y0, 10 + t, h - y1);
y0 = y1;
}
}
System.out.println("Repainted");
/*g.drawLine(10,10,10,h-10); //y-axis
g.drawLine(10,h/2,w-10,h/2); //x-axis
g.drawString("P",w-12,h/2+15);
g.drawString("P/2",w/2-13,h/2+15);
g.drawLine(w-10,h/2-2,w-10,h/2+2); //horizontal marks
g.drawLine(w/2, h/2-2,w/2, h/2+2);*/
}
public void drawSine(double amp, double xCoef, double phase){
for (int j=0;j<=samples;j++){
eqValues.add(amp*Math.sin(xCoef*Math.PI*j/samples + Math.PI*phase/180)+0.5+h/2);
}
repaint();
System.out.println("Got sine vals");
}
public void drawFOeq(double sc, double fc){
for (int j=0;j<=samples;j++){
eqValues.add(sc*j+fc);
}
repaint();
System.out.println("Got FO eq vals");
}
}
Thanks in advance!
The problem is when you add values to the ArrayList: you are putting them after the ones already in the ArrayList (with the add(Double) method). If you just want to clear the plot and draw a new function use the clear() method in the ArrayList of values before adding the new ones:
public void drawSine(double amp, double xCoef, double phase) {
eqValues.clear(); //this clear the ArrayList
......
repaint();
......
}
public void drawFOeq(double sc, double fc){
eqValues.clear(); //this clear the ArrayList
......
repaint();
......
}
If you want to plot multiple functions you have to create different ArrayList or, even better, store in the ArrayList all points (for example with java.awt.Point):
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
public class MyCanvas extends Canvas {
int w, h; // width and height
int samples;
ArrayList<Point> eqValues = new ArrayList<>(); //Point constructor receives 2 int arguments: x and y; however, his methods getX() and getY() return double values
// constructor
MyCanvas(int wi, int he) {
w = wi;
h = he;
setSize(w, h); // determine size of canvas
samples = wi - 20;
}
public void paint(Graphics g) {
int x1, y0, y1; // previous and new function value
g.setColor(Color.yellow);
g.fillRect(0, 0, w, h); // clear canvas
g.setColor(Color.black);
if (eqValues.size() > 0) { // draw new graph
y0 = (int) Math.round(eqValues.get(0).getY()); // first line must start at the first point, not at 0,h
for (Point p : eqValues) { // iterates over the ArrayList
x1 = (int) Math.round(p.getX());
y1 = (int) Math.round(p.getY());
g.drawLine(10 + x1 - 1, h - y0, 10 + x1, h - y1);
y0 = y1;
}
}
System.out.println("Repainted");
}
public void drawSine(double amp, double xCoef, double phase) {
for (int j = 0; j <= samples; j++) {
eqValues.add(new Point(j, (int) Math
.round(amp * Math.sin(xCoef * Math.PI * j / samples + Math.PI * phase / 180) + 0.5 + h / 2)));
}
repaint();
System.out.println("Got sine vals");
}
public void drawFOeq(double sc, double fc) {
for (int j = 0; j <= samples; j++) {
eqValues.add(new Point(j, (int) Math.round(sc * j + fc)));
}
repaint();
System.out.println("Got FO eq vals");
}
}