3UiFWLFDPDUWHV San Sebastián, mayo 1999 3URJUDPDFLyQ-DYD -DYLHU*DUFtDGH-DOyQÂ -RVp,JQDFLR5RGUtJXH] $OIRQVR%UD]iOH]Â $OEHUWR/DU]DEDOÂ -HV~V&DOOHMDÂ -RQ*DUFtD Informática 2: Práctica nº 14 (martes) página 1 INDICE Ejercicio 1: Ejercicio 2: Ejercicio 3: Ejercicio 4: Osciloscopio3 .................................................................................................................................... 1 Incluir en el osciloscopio un botón de parada ................................................................................... 3 Añadir barras de desplazamiento para controlar el osciloscopio....................................................... 4 Añadir la posibilidad de video inverso .............................................................................................. 6 Antes de comenzar la práctica abre el Windows Explorer y comprueba que se ha creado de modo automático en tu disco G:\ un directorio llamado Inf2prac14. Es muy importante que todos los ejercicios de esta práctica se creen dentro de este directorio, porque esta semana la práctica es evaluada. Como recomendación general, mantén abierto el Windows Explorer y comprueba de vez en cuando que los proyectos de los distintos ejercicios se están guardando correctamente. Los ejercicios de esta páctica son incrementales, lo cual quiere decir que cada ejercicio se apoya y continúa el anterior. Para cada ejercicio deberás crear un nuevo proyecto y un nuevo directorio, copiando a este nuevo directorio los ficheros del ejercicio anterior y cambiándoles de nombre cuando sea necesario. Puedes utilizar Windows Explorer para ayudar a Visual J++ 6.0 en esta tarea de crear un proyecto nuevo a partir de los ficheros del anterior. Ejercicio 1: Osciloscopio3 Esta práctica va de osciloscopios. El punto de partida es el programa Osciloscopio3 realizado en la clase de teoría de esta semana. Crea un proyecto llamado Ejer1 en el directorio de la práctica y copia a él los ficheros Osciloscopio3.java, Timer.java, ITimer.java y PruebaOscilos3.htm que se encuentran en el directorio Q:\Infor2\Prac14\Martes\Ejer1. Este primer ejercicio es de pre-calentamiento. Simplemente deberás comprobar que los ficheros entregados con este ejercicio funcionan correctamente, como applet y como aplicación. A continuación se incluye, como ayuda extra, un listado de la clase principal: // fichero Osciloscopio3.java import java.applet.*; import java.awt.*; public class Osciloscopio3 extends Applet implements ITimer { // variables miembro int n=5; double X=100; double T=n*2*Math.PI; double omega=2*Math.PI*n/T; double fi=0; int nInt=100; double delta=T/nInt; Dimension d; // definición del control Timer indicando nombre y // quién inplementa la interface ITimer Timer unTimer; // variables para el double buffer Image imgInvisible; Graphics graInvisible; Dimension dimInvisible; Informática 2: Práctica nº 14 (martes) página 2 public void init() { unTimer = new Timer("unTimer", this); unTimer.setInterval(20); System.out.println("Initializing..."); } public void start() { unTimer.setEnabled(true); System.out.println("Starting..."); } public void stop() { unTimer.setEnabled(false); System.out.println("Stoping..."); } // método paint() para double buffer public void paint(Graphics g) { double x, y, xn, yn; d = this.getSize(); int w = d.width, h = d.height/2; // si no existen o son diferentes, se crean los objetos invisibles if( (graInvisible==null) || (d.width != dimInvisible.width) || (d.height != dimInvisible.height) ) { dimInvisible = d; imgInvisible = createImage(d.width, d.height); // método de Component graInvisible = imgInvisible.getGraphics(); } // end if // se establece el color de fondo como color actual graInvisible.setColor(this.getBackground()); // se dibuja un rectángulo con el color de fondo graInvisible.fillRect(0, 0, d.width, d.height); // se restablece el negro como color actual graInvisible.setColor(Color.black); double fact=w/T; // relación de escalas x=0; y=f(0); for (int i=0; i<nInt; i++) { xn=x+delta; yn=f(xn); // se dibujan dos líneas para simular espesor de 2 pixels graInvisible.drawLine((int)(x*fact), h-(int)y, (int)(xn*fact), h-(int)yn); graInvisible.drawLine((int)(x*fact)+1, h-(int)y+1, (int)(xn*fact)+1, h-(int)yn+1); x=xn; y=yn; } // se dibuja la imagen invisible g.drawImage(imgInvisible, 0, 0, this); } // fin paint() // necesario para que el double buffer funcione correctamente public void update(Graphics g) { paint(g); } public double f(double x) { return X*Math.sin(omega*x+fi); } // método timer() para la interface ITimer public void timer() { fi += Math.PI/24; repaint(); } // fin timer() Informática 2: Práctica nº 14 (martes) página 3 // método main() para ejecutar como aplicación public static void main (String[] args) { Osciloscopio3 osc = new Osciloscopio3(); VentanaCerrable vc = new VentanaCerrable("Osciloscopio 3"); vc.add(osc, "Center"); vc.setSize(400, 300); vc. setLocation(100, 100); vc.show(); osc.init(); osc.start(); } // fin main() } // fin clase Oscilosopio3 Una vez comprobado que todo funciona correctamente, ya puedes pasar al siguiente ejercicio. Ejercicio 2: Incluir en el osciloscopio un botón de parada Crea con Visual J++ un proyecto llamado Ejer2 en el directorio de la práctica Inf2prac14. Copia a este directorio los ficheros resultado del ejercicio anterior. Cambia el nombre de Osciloscopio3.java por Osciloscopio4.java y PruebaOscilos3.htm por PruebaOscilos4.htm. El ejecutable modelo de cómo debe quedar este ejercicio está en el directorio Q:\Infor2\Prac14\Martes\Ejer2. Este ejercicio tiene como finalidad el introducir un botón que pare y vuelva a arrancar la animación, resultando una pantalla como la mostrada en la Figura 1. Figura 1. Osciloscopio4 ejecutándose como aplicación. Para realizar este ejercicio puedes tener en cuanta las siguientes consideraciones: 1. Un applet es un panel, y por tanto tiene como Layout Manager por defecto FlowLayout. Se puede cambiar el Layout Manager a BorderLayout con el método setLayout(). Esto permitirá introducir un panel para dibujo en la zona “Center” y un botón en la zona “South”. 2. Para dibujar en un panel de dibujo distinto del propio applet hay que redefinir sus métodos paint() y update(). Para poder redefinir estos métodos habrá que crear una clase llamada MiPanel que derive de Panel. Esta clase se puede definir en el mismo fichero Osciloscopio4.java. Habrá que crear un objeto de esta clase llamado por ejemplo mpan que puede ser variable miembro de Osciloscopio4. 3. La clase MiPanel necesita una referencia a un objeto de la clase Osciloscopio4 para poder acceder a sus variables miembro y realizar los dibujos (mpan, X, nInt, omega, T, etc.). Esa referencia puede ser variable miembro de MiPanel y un argumento del constructor de dicha clase. Informática 2: Práctica nº 14 (martes) página 4 4. Así pues, habrá que crear un objeto de la clase MiPanel y añadirlo a la zona “Center” de Osciloscopio4. Habrá que crear también un botón y añadirlo a la zona “South” a través de un panel intermedio para que su tamaño sea lo más pequeño posible. Habrá que definir un ActionListener para este botón con un método actionPerformed() que cambie el estado del Timer y su propio label según en qué situación esté la animación. La mejor forma de hacer esto es con una clase anónima definida justo al registrar el ActionListener. 5. Las operaciones indicadas en el número anterior deberán realizarse en el mátodo init() de Osciloscopio4, que realiza el papel del constructor del applet. 6. Un punto importante es que, en el método init(), después de añadir el panel y el botón al applet con el Layout Manager modificado, hay que llamar al método validate() del propio applet (validate() se encarga de llamar a doLayout(), que a su vez se encarga de reajustar todos los tamaños de los componentes. Esto es necesario porque el applet se ha modificado en el método init(), que aunque hace el papel del constructor se ejecuta después que éste. Si no se incluye esta llamada a validate() no se dibuja nada en la ventana de la aplicación. Ejercicio 3: Añadir barras de desplazamiento para controlar el osciloscopio Crea un proyecto llamado Ejer3 en el directorio de la práctica Inf2prac14. Copia a este directorio los ficheros del ejercicio anterior y cámbiales el nombre a Osciloscopio5.java y PruebaOscilos5.htm. Los modelos de este ejercicio están en el directorio Q:\Infor2\Prac14\Martes\Ejer3. Prueba a ejecutarlos al menos como aplicación. En este caso, como aplicación se basará en una ventana de 400x400 pixels y como applet deberá tener este mismo tamaño. El objetivo es “hacer sitio” para los controles adicionales que deben aparecer en la parte “South”, según se muestra en la Figura 2. Figura 2. Osciloscopio con controles de diversas magnitudes. Como se puede ver en la figura y ser comprobado ejecutando los modelos, en este caso se han añadido tres barras de desplazamiento para controlar el desfase Fi, la amplitud X y la frecuencia omega, y las tres labels correspondientes (Fi, X y omega). Estas magnitudes son variables miembro de la clase Osciloscopio5 y lo único que hacen las barras de desplazamiento es cambiar su valor. Informática 2: Práctica nº 14 (martes) página 5 Todo el cálculo y el dibujo se debería actualizar automáticamente con los nuevos valores sin ninguna modificación adicional. La aplicación mostrada en la Figura 2 se puede hacer en base a una jerarquía de paneles como la mostrada en la siguiente Figura: mpan pan11 pan12 pan21 pan22 pan31 pan32 span Figura 3. Jerarquía de paneles para la aplicación mostrada en la Figura 2. Los pasos a dar pueden ser los siguientes: 1. En la zona “Center” del applet se introduce un panel llamado mpan de la clase MiPanel en el que se realizará el dibujo de las curvas sinusoidales. 2. En la zona “South” del applet se introduce un panel normal llamado span con un GridLayout de tres filas y dos columnas. Su papel es simplemente de contenedor. 3. A continuación se crean 6 paneles (pan11, pan22, pan21, pan22, pan31 y pan32) que se introducirán en las celdas correspondientes de span. 4. Los tres paneles de la columna de la izquierda son paneles normales con FlowLayout. El botón “Start”/”Stop” se deberá introducir en el panel pan21. En los paneles pan11 y pan31 no se introduce nada. 5. Los tres paneles de la columna de la derecha deberán tener a su vez GridLayout con una fila y dos columnas, pues en ellos hay que introducir las labels y las barras de desplazamiento. Independientemente de las estructura de paneles mostrada, este ejercicio también se puede realizar incrementalmente: 1. En primer lugar se crearán los paneles indicados y se introducirán vacíos en sus respectivos contenedores. 2. El único componente que se considerará será el botón “Start”/”Stop” en el panel pan21. No se seguirá hasta que el ejercicio funcione como en el ejercicio anterior. 3. A continuacion se introducirá la barra de desplazamiento que controla el ángulo Fi y la label correspondiente. Esta barra controlará el número de incrementos de dicha variable (entre –10 y 10; valor inicial 1). Este número puede ser una nueva variable miembro de Informática 2: Práctica nº 14 (martes) página 6 Osciloscopio5 llamada nInc. Cada incremento valdrá π/24. Eso quiere decir que si en la barra se elige el valor 4, el valor de Fi se incrementará en 4*π/24, dentro del método timer(). La barra deberá ser una variable miembro de Osciloscopio5. Después de crear el objeto correspondiente en el método init() se deberá registrar el event listener que implemente el método adjustmentValueChanged(). Dicho método sólo tendrá que cambiar el valor de la variable miembro nInc en función del valor de la barra de desplazamiento. No se deberá seguir adelante hasta que el programa no funcione correctamente sólo con esta barra. 4. A continuación se creará una barra de desplazamiento que controle la amplitud X y se introducirá en pan22 junto con la label correspondiente. La amplitud X variará entre 10 y 100, siendo 100 el valor inicial. El correspondiente método adjustmentValueChanged() cambiará el valor de la variable miembro X a partir del valor de la barra. No se deberá seguir hasta que el programa funcione correctamente modificando la amplitud. 5. Finalmente y de modo análogo se introducirá una barra de desplazamiento que controle la frecuencia. Para ello, la variable miembro de Osciloscopio5 que de verdad se va a controlar es el número de ciclos n, que tomará valores entre 1 y 20, con un valor por defecto de 5. Cuando esto se consiga, ya estará terminado el ejercicio. Todos los pasos citados se deberán realizar modificando el método init(). El resto del programa quedará prácticamente inalterado. Ejercicio 4: Añadir la posibilidad de video inverso Crea un nuevo proyecto llamado Ejer4 y copia en él los ficheros del ejercicio anterior. Cambia el nombre a los ficheros del modo habitual. La Figura 4 muestra lo que se pretende hacer con esta último ejercicio. Se trata de introducir la posibilidad de video inverso, es decir de que en vez de dibujar las líneas oscuras sobre fondo blanco, se dibujen las líneas blancas sobre fondo oscuro. Figura 4. Opción de video inverso. Para realizar este ejercicio introduce un Checkbox en el panel pan32 y realiza todas las modificaciones necesarias para que el programa se comporte como el modelo que puedes encontrar en el directorio Q:\Infor2\Prac14\Martes\Ejer4.