/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////*\ This class is an extention of Canvas. Runs its own thread. paint methods cannot be called directly by browser (good) \*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////*/ import java.awt.*; import java.awt.event.MouseMotionListener; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.text.DecimalFormat; //! @brief This class shows a sort of video of the actual AFM at work /// It looks only as good as you make it. class Animation extends Canvas implements Runnable { private Thread myThread; private AFMSimulator afmSim; private BufferedImage image; private int ind, time; private final int W = 500, H = 300; private final double INTERVAL = (double) W / AFMConstants.SAMPLES; private int delay = 100; private int k = 6; // speed of animation (skip rate) private int surface_periods = 1; private int zoom = 1000; // don't need this. remove. private final int X_AXIS = H/2 + 100; private Color backgroundColor; private Color textColor; public Animation() { setSize(W, H); afmSim = new AFMSimulator(); afmSim.setParams(AFMApplet.params[0], AFMApplet.params[1], AFMApplet.params[2], AFMApplet.params[3], AFMApplet.params[4], AFMApplet.params[5], AFMApplet.params[6], AFMApplet.params[7], AFMApplet.params[8]); afmSim.resetSim(); image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); textColor = AFMConstants.text_color; backgroundColor = AFMConstants.BG_color; Graphics back = image.getGraphics(); back.setColor(backgroundColor); back.fillRect(0, 0, W, H); back.setColor(textColor); back.drawString("AFM Animation", 400, 20); ind = 0; time = 0; AFMApplet.drawSurface(image, afmSim, surface_periods, AFMConstants.surface_color); addMouseListener(new MouseCoordListener()); addMouseMotionListener(new MouseCoordListener()); } public Animation(int _delay) { this(); delay = _delay; } public void start() { if (myThread != null) stop(); myThread = new Thread(this); myThread.start(); AFMApplet.drawSurface(image, afmSim, surface_periods, AFMConstants.surface_color); }//end start public void reset() { image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); ind = 0; time = 0; Graphics back = image.getGraphics(); back.setColor(backgroundColor); // background color back.fillRect(0, 0, W, H); back.setColor(textColor); // title text color back.drawString("AFM Animation", 400, 20); afmSim = new AFMSimulator(); afmSim.setParams(AFMApplet.params[0], AFMApplet.params[1], AFMApplet.params[2], AFMApplet.params[3], AFMApplet.params[4], AFMApplet.params[5], AFMApplet.params[6], AFMApplet.params[7], AFMApplet.params[8]); afmSim.resetSim(); AFMApplet.drawSurface(image, afmSim, surface_periods, AFMConstants.surface_color); } public void resume() { start(); } public void run() { while (myThread != null) { repaint(); try { Thread.sleep(delay); } catch (InterruptedException e) { this.stop(); } } }//end run public void stop() { myThread = null; } public void cleanup() { myThread = null; afmSim = null; image = null; backgroundColor = null; textColor = null; } public void setState(AFMSimulator afmSim) { this.afmSim = afmSim; } public void clear() { Graphics back = image.getGraphics(); back.setColor(backgroundColor); back.fillRect(0, 0, W, H); } public void update(Graphics g) { Graphics back = image.getGraphics(); back.setColor(backgroundColor); back.fillRect(0, 0, W, H); back = image.getGraphics(); back.setColor(textColor); back.drawString("AFM Animation", 400, 20); int old; if (ind > 0) old = ind - k; else old = k * (AFMConstants.SAMPLES / k); for (int i = 0; i < AFMConstants.SAMPLES; i++) { int xOld = W / 2 + (int) (i * INTERVAL); int j = AFMMath.mod((i + ind + AFMSimulator.STROBE_OFFSET), AFMConstants.SAMPLES); //if(j>=AFMConstants.SAMPLES) j-=AFMConstants.SAMPLES; int yNew = AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getSurface().getY(j) * 500 / surface_periods); if (xOld > W) xOld -= W; back.setColor(AFMConstants.surface_color); back.drawOval(xOld, yNew, 0, 0); } back.setColor(backgroundColor); DecimalFormat dec = new DecimalFormat("0.###"); String t = dec.format(afmSim.getAFM().getTime(old)); back.drawString("Time = " + time + " = " + t, 20, 290); //afmSim.getAFM().getTime(old), others (0) ind-1-->time paint(g); } public void paint(Graphics g) { Graphics back = image.getGraphics(); if (AFMMath.dif(AFMConstants.SAMPLES, ind, 20)) /**** and selection is STROBOSCOPIC,... ****/ back.setColor(textColor); else back.setColor(AFMConstants.info_color); DecimalFormat dec = new DecimalFormat("0.###"); String t = dec.format(afmSim.getAFM().getTime(ind)); back.drawString("Time = " + time + " = " + t + " ms", 20, 290); //afmSim.getAFM().getTime(ind) int tipX = (int) (W / 2 + (afmSim.getAFM().getX(ind) - afmSim.getAFM().getV() * afmSim.getAFM().getT(ind)) * AFMConstants.SAMPLES / (Surface.L)); int tipY = AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getAFM().getY(ind) * 500 / surface_periods); // draw AFM tip (triangle) int x[] = {tipX - 5, tipX, tipX + 5}, y[] = {tipY - 7, tipY, tipY - 7}; back.fillPolygon(x, y, 3); // draw AFM cantilever back.setColor(AFMConstants.AFMspring_color); //back.drawLine((int) (W / 2 + (afmSim.getAFM().getX(ind) - afmSim.getAFM().getV() * afmSim.getAFM().getT(ind)) * AFMConstants.SAMPLES / Surface.L), (int) (AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getAFM().getY(ind) * 500 / surface_periods) - 8), W / 2, 0); back.drawArc((int) (W / 2 + (afmSim.getAFM().getX(ind) - afmSim.getAFM().getV() * afmSim.getAFM().getT(ind)) * AFMConstants.SAMPLES / Surface.L), (int) (AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getAFM().getY(ind) * 500 / surface_periods) - 38), W*3/2, 55, 90, 90); //back.drawLine((int) (W / 2 + (afmSim.getAFM().getX(ind) - afmSim.getAFM().getV() * afmSim.getAFM().getT(ind)) * AFMConstants.SAMPLES / Surface.L), (int) (AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getAFM().getY(ind) * 500 / surface_periods) - 8), W, (int) (AFMApplet.SURFACE_HEIGHT - (int) Math.round(afmSim.getAFM().getY(ind) * 500 / surface_periods) - 8)); g.drawImage(image, 0, 0, this); ind += k; if (ind >= AFMConstants.SAMPLES) { afmSim.getMore(); // add a warning when there is dragging ind = 0; time++; } }//end paint private class MouseCoordListener implements MouseMotionListener, MouseListener { private String lastInfo = ""; public void mouseDragged(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mouseMoved(MouseEvent event) { Graphics back = image.getGraphics(); double x = event.getPoint().getX(); double y = event.getPoint().getY(); double x_realValue = (double) (x - W / 2) * Surface.L / W; // x_center holds *actual* x center value (in the system, not on the display) if(x_realValue > 1) x_realValue -= 1; double y_realValue = (double) (X_AXIS - y) / zoom; back.setColor(backgroundColor); back.drawString(lastInfo, 20, 270); DecimalFormat dec = new DecimalFormat("0.###"); dec.setMaximumFractionDigits((int)Math.round(AFMMath.log2(zoom/100)) + 4); back.setColor(AFMConstants.info_color); lastInfo = "(" + dec.format(x_realValue) + ", " + dec.format(y_realValue) + ")"; back.drawString(lastInfo, 20, 270); /***ADD CODE HERE***/ } public void mouseClicked(MouseEvent event) { if(AFMApplet.zoomTool.isSelected()) { if (event.getButton() != MouseEvent.BUTTON1) surface_periods *= 2; else surface_periods /= 2; if(surface_periods<1) surface_periods = 1; //Graphics back = surface_image.getGraphics(); //back.setColor(backgroundColor); //back.fillRect(0,0,W,H); //AFMApplet.drawSurface(surface_image, afmSim, surface_periods, AFMConstants.surface_color); clear(); repaint(); } } public void mouseEntered(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mouseExited(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mousePressed(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } public void mouseReleased(MouseEvent e) { //To change body of implemented methods use File | Settings | File Templates. } }// end MouseListener }//end Animation