Hello so I'm working on making a engine, and I'm using Java3D, a SimpleUniverse, a Canvas3D, and I understand how to draw, transform, etc. What I'm looking for is how to update the drawing (I have a method that only redraws what's already visible, in order to save on memory). As at the moment I have a timer (will post code below), that runs at a rate of 1000 / fps. Where fps is a long. I want the scene to redraw continuously because if there are no inputs from the user, I want the simulation to continue to run. This timer works, but it flickers a lot. Even if I lower the fps. So my question is, is there a better way to continuously update the Canvas, reducing flicker and memory usage, without only updating with input? I've read some articles about thread usage, but I can never seem to implement it correctly. I've also heard about double buffered but never found a good explanation of how to do that, so was unable to implement it. Here's the code relative to what I'm trying to accomplish:

static long fps = (long) 50;
 
public void gameLoop() {
		Timer t = new Timer();
		t.schedule(new TimerTask() {
 
			@Override
			public void run() {
				update();
			}
 
		}, 0, 1000 / fps);
	}
 
public void update() {
		if (keys[38]) { // up
			Vector3f loc = camloc;
			loc.y = loc.y + 0.05f;
			camloc = loc;
			moveEye(camloc);
		}
		if (keys[40]) { // down
			Vector3f loc1 = camloc;
			loc1.y = loc1.y - 0.05f;
			camloc = loc1;
			moveEye(camloc);
		}
		if (keys[37]) { // left
			Vector3f loc2 = camloc;
			loc2.x = loc2.x - 0.05f;
			camloc = loc2;
			moveEye(camloc);
		}
		if (keys[39]) { // right
			Vector3f loc3 = camloc;
			loc3.x = loc3.x + 0.05f;
			camloc = loc3;
			moveEye(camloc);
		}
		if (keys[44]) { // <
			Vector3f loc4 = camloc;
			loc4.z = loc4.z - 0.05f;
			camloc = loc4;
			moveEye(camloc);
		}
		if (keys[46]) { // >
			Vector3f loc5 = camloc;
			loc5.z = loc5.z + 0.05f;
			camloc = loc5;
			moveEye(camloc);
		}
		if (keys[81]) { // Q
			Point origin12 = new Point(0, 0, 0, new Vector(0.0f, 0.0f, 0.0f));
			Vector tempVector12;
			for (int x = 0; x < points.length; x++) {
				// store the current vector address for the point, and
				// set the point
				tempVector12 = points[x].subtractPointFromPoint(origin12);
				// reset the point so that the scaled vector can be
				// added
				points[x].setPointToPoint(origin12);
				// scale the vector and set the point to its new, scaled
				// location
				points[x].addVectorToPoint(tempVector12.rotateYZ(7));
				redrawVisible();
			}
		}
		if (keys[67]) { // C
			redrawScene(false);
		}
		if (keys[68]) { // D
			//redrawVisible defualt, now open
		}
		if (keys[65]) { // A
			Point origin = new Point(0, 0, 0, new Vector(0.0f, 0.0f, 0.0f));
			Vector tempVector;
			for (int x = 0; x < points.length; x++) {
				// store the current vector address for the point, and
				// set the point
				tempVector = points[x].subtractPointFromPoint(origin);
				// reset the point so that the scaled vector can be
				// added
				points[x].setPointToPoint(origin);
				// scale the vector and set the point to its new, scaled
				// location
				points[x].addVectorToPoint(tempVector.scale(new Vector(0.9f,
						0.9f, 0.9f)));
				redrawVisible();
			}
		}
		if (keys[83]) { // S
			Point origin1 = new Point(0, 0, 0, new Vector(0.0f, 0.0f, 0.0f));
			Vector tempVector1;
			for (int x = 0; x < points.length; x++) {
				// store the current vector address for the point, and
				// set the point
				tempVector1 = points[x].subtractPointFromPoint(origin1);
				// reset the point so that the scaled vector can be
				// added
				points[x].setPointToPoint(origin1);
				// scale the vector and set the point to its new, scaled
				// location
				points[x].addVectorToPoint(tempVector1.scale(new Vector(1.1f,
						1.1f, 1.1f)));
				redrawVisible();
			}
		}
		if (keys[82]) { // R
			Point origin11 = new Point(0, 0, 0, new Vector(0.0f, 0.0f, 0.0f));
			Vector tempVector11;
			for (int x = 0; x < points.length; x++) {
				// store the current vector address for the point, and
				// set the point
				tempVector11 = points[x].subtractPointFromPoint(origin11);
				// reset the point so that the scaled vector can be
				// added
				points[x].setPointToPoint(origin11);
				// scale the vector and set the point to its new, scaled
				// location
				points[x].addVectorToPoint(tempVector11.rotateXY(7));
				redrawVisible();
			}
		}
		if (keys[32]) { // Space bar
			redrawObject("points", false);
		}
		if (keys[76]) { // L
			redrawObject("points", true);
		}
		if (keys[75]) { // K
			redrawObject("segments", true);
		}
		if (keys[74]) { // J
			redrawObject("segments", false);
		}
		if(keys[72]) { // H
 
		}
		redrawVisible();
	}