75­62 Técnicas de Programación Concurrente II 2004 Java Varios FIUBA Ing. Osvaldo Clúa Double Buffering: En algunos de los ejercicios se debió notar un molesto parpadeo. Una técnica para evitarlo se conoce como duble buffering. Consiste en lo siguiente: • Trabajar en un contexto gráfico que no esté mapeado a la pantalla y • Enviar ese contexto gráfico a la pantalla en una sola operación: Para esto debemos hacer lo siguiente, suponiendo un programa lo suficientemente complejo y con varios actores moviéndose en un único Canvas. Crear un Graphics adicional donde se hará el dibujo. Pero el Graphics no se puede crear sino que se lo debe obtener de alguna parte. El componente adecuado es una Image. Entonces en el lugar adecuado (generalmente como variables de instancia) se ponen las declaraciones: 1. Graphics miGr; 2. Image miIm; // para doble buffer Y al comenzar a dibujar se obtiene el Graphics y se dibuja en él: 1. miIm=createImage(300,400); 2. miGr=miIm.getGraphics(); Se crea una Image del mismo tamaño que el Canvas llamado ca y se obtiene su Contexto Gráfico. 1.public void paint(Graphics g) { 2. miGr.clearRect(0,0,300,400); 3. miGr.setColor(Color.lightGray); 4. miGr.fillRect(0,0,300,400) 5. for(int i=0;i<cant;i++) 6. {p[i].paint(miGr);} 7. Graphics g1=ca.getGraphics(); 8. g1.drawImage(miIm,0,0,this); 9. } Luego se opera sobre el nuevo contexto gráfico, en la línea 10 se lo pasa a los diversos agentes que quieren dibujarse y finalmente en la 12 se lo vuelca a la pantalla. Además debe evitarse que update( Graphics g) borre la pantalla, para lo que se lo reprograma: 3. void update (Graphics G){ 4. paint (G);} Manejo de Bitmaps: Las técnicas para cargar una imagen externa son distintas si se trata de un Técnicas Concurrentes 2 Temas varios de Java applet o de una aplicación: En el caso de un applet: (obviamente hace falta una imagen llamada en este caso 03­08.jpg) 1.import java.applet.*; 2.import java.awt.*; 3. 4.public class ApBitmap extends Applet { 5. Image image; 6. 7. public void init() { 8. setBackground(Color.pink); // applet background 9. image = getImage(getCodeBase(),"03-08t.jpg"); 10. } 11. public void paint(Graphics g) { 12. g.drawImage(image,10,10,this); 13. } 14.} El bitmap se carga sobre una Image usando DrawImage (y haciendo uso de las facilidades del browser para desplegarlo, sin interactuar con el Sistema Operativo host). En una Aplicación esa interacción es obligada y se hace así; 1.import java.awt.*; 2.import java.awt.event.*; 3. 4.class PureBitmap extends Frame{ 5. Image image; 6. 7. PureBitmap(String s) { 8. super(s); 9. setBackground(Color.pink); 10. image = Toolkit.getDefaultToolkit().getImage ("./03-08t.jpg"); 11. addWindowListener(new WindowAdapter() { 12. public void windowClosing(WindowEvent e) {System.exit(0);}}); 13. setSize(300,200); 14. setVisible(true); 15. } 16. public void paint(Graphics g) { 17. g.drawImage(image,50,50,this); 18. } 19. 20.} El uso de Toolkit para obtener la Image transparenta esta interacción. Drag and Drop: Para hacer Drag de un objeto, el código se dividió en dos partes: El rectángulo que se dibuja, se mueve, crece y se achica: 5. import java.awt.*; 6. import java.awt.event.*; 7. class DragRect{ ­2­ Técnicas Concurrentes 2 Temas varios de Java 8. int x; int y; 9. int ancho; int alto; 10. Color c; 11. boolean draggable; 12.DragRect(int x, int y, int w, int h){ 13. this.x=x; this.y=y; 14. ancho=w;alto=h; 15. } 16.public void setDraggable( boolean como){ 17. draggable=como; 18. } 19.public boolean isDraggable(){ 20. return draggable; 21. } 22.public void paint (Graphics g){ 23. g.setColor(c); 24. g.fillRect(x,y,ancho,alto); 25. } 26.public boolean estaAdentro(int xx,int yy){ 27. return (x <= xx && y <= yy && 28. (x + ancho >= xx) && 29. (y + alto >= yy)); 30. } 31.public void mover(int xx,int yy){ 32. x+=xx;y+=yy; 33. } 34.public void crecer(){ 35. ancho++;alto++; 36. } 37.public void decrecer(){ 38. ancho--;alto--; 39. } 40.} Y el canvas que capta las acciones de mouse y keyboard y le ordena al rectángulo sus movimientos (usa double buffering). 1.import java.awt.*; 2.import java.awt.event.*; 3. 4.class CanDragDB extends Frame { 5. int locX=0; int locY=0; 6. int locAncho=300; int locAlto=300; 7. Canvas c; 8. DragRect r; 9. int viejoX; int viejoY; 10. Image offIm; 11. Graphics offGr; 12.CanDragDB(String s){ 13. super(s); 14. addWindowListener(new WindowAdapter() { 15. public void windowClosing(WindowEvent e) {System.exit(0);}}); 16. c=new Canvas (); 17. r=new DragRect(0,0,50,50); 18. r.c=Color.red; 19. c.addMouseListener( new MouseAdapter(){ ­3­ Técnicas Concurrentes 2 Temas varios de Java 20. public void mousePressed(MouseEvent e){ 21. if (r.estaAdentro(e.getX(),e.getY ()))r.setDraggable(true); 22. viejoX=e.getX();viejoY=e.getY ();} 23. public void mouseReleased(MouseEvent e){ 24. r.setDraggable(false);} 25. }); 26. c.addMouseMotionListener(new MouseMotionAdapter(){ 27. public void mouseDragged(MouseEvent e){ 28. if (r.isDraggable()){ 29. r.mover(e.getX()-viejoX,e.getY ()-viejoY); 30. viejoX=e.getX(); 31. viejoY=e.getY(); 32. repaint(); 33. } 34. } 35. }); 36. c.addKeyListener(new KeyAdapter(){ 37. public void keyPressed(KeyEvent e){ 38. int tecla=e.getKeyCode(); 39. if (tecla==KeyEvent.VK_ADD) r.crecer(); 40. if (tecla==KeyEvent.VK_SUBTRACT) r.decrecer(); 41. if (tecla==KeyEvent.VK_DOWN) r.mover(0,1); 42. if (tecla==KeyEvent.VK_UP) r.mover (0,-1); 43. if (tecla==KeyEvent.VK_LEFT) r.mover(-1,0); 44. if (tecla==KeyEvent.VK_RIGHT) r.mover(1,0); 45. repaint(); 46. } 47. }); 48. setSize(locAncho,locAlto); 49. c.setSize(locAncho,locAlto); 50. add(c);pack(); 51. offIm=createImage(locAncho,locAlto); 52. offGr=offIm.getGraphics(); 53. setVisible(true); 54. update(c.getGraphics()); // forzar el primer dibujo 55. } 56.public void paint (Graphics g){ 57. offGr.clearRect(locX,locY,locAncho,locAlto); 58. offGr.setClip(locX,locY,locAncho,locAlto); 59. offGr.setColor(Color.gray); 60. offGr.fillRect(locX,locY,locAncho,locAlto); 61. r.paint(offGr); 62. Graphics g1=c.getGraphics(); 63. g1.drawImage(offIm,0,0,this); 64. } ­4­ Técnicas Concurrentes 2 Temas varios de Java 65.public void update(Graphics g) { 66. paint(g); 67. } 68.} ­5­