Herramientas de usuario

Herramientas del sitio


bloque1:interfaces

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

bloque1:interfaces [2020/10/30 13:33] – [Eventos] fernandobloque1:interfaces [2024/09/16 20:55] (actual) – editor externo 127.0.0.1
Línea 344: Línea 344:
  
 https://docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html https://docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html
 +
 +
 +===== Diseñadores de interfaces =====
 +
 +==== WindowBuilder para Eclipse ====
 +
 +WindowBuilder es un plugin de código abierto para Eclipse destinado a crear interfaces gráficas de usuario (GUI) de forma rápida y sencilla. Como otros muchos sistemas de este tipo, contiene una paleta de elementos que podemos añadir mediante “drag and drop”, arrastrar y soltar. En lugar de tener que escribir el código a medida que vamos incluyendo elementos gráficos en nuestra ventana, WindowBuilder nos genera el código en nuestras clases.
 +
 +Aunque WindowBuilder sea una herramienta de gran ayuda, necesitamos comprender la estructura con la que WindowBuilder crea clases para poder modificarla y darle un formato a las clases que nos ayude a separar y entender el programa.
 +
 +=== Instalación de WindowBuilder ===
 +
 +Para poder descargar WindowBuilder iremos en Eclipse a la pestaña ''Help'' y ahí a ''Eclipse MarketPlace…''. Buscamos el Plugin por su nombre (WindowBuilder) en el campo buscar, y una vez que lo haya encontrado, pulsamos sobre instalar.
 +
 +{{:bloque1:eclipsemarketplace1.png?300 |}}
 +{{ :bloque1:eclipsemarketplace2.png?300 |}}
 +
 +Al terminar la instalación, reiniciamos Eclipse y ya podremos trabajar con él.
 +
 +=== Crear un proyecto con ventanas ===
 +WindowBuilder está compuesto de varias herramientas para crear interfaces gráficas de usuario. Nosotros vamos a trabajar únicamente con los componentes [[https://es.wikipedia.org/wiki/Swing_(biblioteca_gr%C3%A1fica)|Swing]].
 +Para ello usaremos la herramienta Swing Designer de WindowBuilder. 
 +
 +Por convenio, en Java una ''aplicación de escritorio'' empleará un contenedor principal de tipo ''JFrame''. Si además contiene otras ventanas secundarias dentro del programa emplearemos contenedores de tipo ''JDialog'' para estas ventanas secundarias.
 +
 +
 +**Creamos un proyecto** de la misma forma que lo hacemos siempre:
 +
 +{{:bloque1:creaproyecto1.jpg?300 |}}
 +{{ :bloque1:creaproyecto2.jpg?300 |}}
 +
 +**Creamos una clase JFrame** para una ventana. Dentro de nuestro proyecto, en algún ''package'' haremos lo siguiente. Debemos usar los componentes de Swing o de la sección Swing Designer de WindowBuilder:
 +
 +{{:bloque1:creaclase1.jpg?300 |}}
 +{{ :bloque1:creaclase2.jpg?300 |}}
 +----
 +
 +También podemos acceder de forma rápida al menú de WindowBuilder mediante su nuevo botón, siempre seleccionando Swing como componentes gráficos:
 +
 +{{:bloque1:creaclase3.png?300 |}}
 +{{ :bloque1:creaclase4.jpg?300 |}}
 +
 +Una vez creada la clase nos aparecerá una nueva vista, desde la cual podemos acceder al código o al diseño a través de las pestañas inferiores.
 +
 +{{:bloque1:pestanadiseno.jpg?300 |}}
 +{{ :bloque1:pestanacodigo.jpg?300 |}}
 +
 +=== Ventana sin Layout Manager ===
 +
 +Para poder emplazar elementos en una ventana de cualquier tipo debemos indicar una organización (Layout). Si al principio no queremos complicarnos demasiado con un layout podemos trabajar de forma sencilla con ''AbsoluteLayout''. Con este Layout podemos emplazar los elementos en el lugar que queramos, aunque no quedará tan bién a la hora de redimensionar la ventana. **Usando AbsoluteLayout los elementos se emplazan atendiendo a coordenadas. Esto se desaconseja en el futuro, ya que no mantiene un orden al redimensionar la ventana.**
 +
 +{{:bloque1:contentpane.png?300 |}}
 +{{ :bloque1:absolutelayout.png?300 |}}
 +
 +Por defecto toda aplicación **JFrame** emplea un JPanel principal de contenido //contentPane//. En el iremos arrastrando todos los elementos que queramos emplear. Para aplicar un layout a nuestra ventana tan solo tenemos que pinchar sobre el layout que queremos usar y pinchar después sobre la ventana.
 +
 +{{ vimeo>246942867?medium }}
 +
 +=== Añadir manejadores de eventos ===
 +{{ :bloque1:addeventhandler.png?350|}}
 +Para añadir un manejador de eventos a nuestra aplicación, bastará con pulsar clic derecho sobre el elemento (p.e. botón) sobre el cual queremos controlar un evento. Se nos desplegará un menú en el que podemos seleccionar el evento que queremos controlar.
 +
 +
 +En algunos componentes deberemos crear un manejador de eventos para otro tipo de eventos (''KeyEvent'', ''StateChanged'', p.e.), aunque como se ha comentado, en la mayoría de los casos bastará con el método ''actionPerformed()''.
 +
 +{{ :bloque1:addeventhandler2.png?300|}}
 +Cuando creemos un manejador de eventos, este se asociará al elemento sobre el cual se realiza el evento (p.e. botón). 
 +Este código se creará justo debajo de la definición del componente, por lo que deberemos moverlo al lugar en el que lo queremos organizar (por ejemplo un método para inicializar los manejadores de eventos).
 +
 +
 +==== UIDesigner para IntelliJ ====
 +Cuando trabajamos con el IDE IntelliJ, también haremos uso de su diseñador de interfaces **UIDesigner**. La principal diferencia con WindowBuilder, es que UIDesigner no crea elementos de tipo JFrame o JDialog, sino que crea contenedores de segundo nivel (JPanel). 
 +
 +{{ :bloque1:uidesigner.png?direct&600 |}}
 +
 +Este elemento posteriormente debemos añadirlo a un contenedor de alto nivel, usando el método setContentPane().
 +
 +Para crear una GUI utilizando IntelliJ, haremos lo siguiente:
 +  - Ir a File -> New
 +  - Seleccionar GUI Form (o Dialog)
 +  - Dar nombre al formulario y seleccionar el Layout Manager
 +  - Marcar el checkbox **Create bound class**, e indicar el nombre
 +
 +En la siguiente videoclase se enseña la creación de una aplicacion MVC desde 0, con el IDE IntelliJ.
 +
 +{{ vimeo>296086288?medium }}
  
 ===== Manejadores de Eventos ===== ===== Manejadores de Eventos =====
 +Una interfaz gráfica se maneja mediante eventos. Los eventos le indican al programa como debe actuar: qué codigo debe ejecutar. La parte del programa que está atenta de esos eventos se conoce como //manejador de eventos// o //listener//.
  
 ==== Eventos ==== ==== Eventos ====
Línea 353: Línea 440:
 Para que nuestro programa pueda responder (ejecutar código) ante un evento, debemos usar un manejador de eventos. Para que nuestro programa pueda responder (ejecutar código) ante un evento, debemos usar un manejador de eventos.
  
-El manejador de eventos es un objeto que implementa los métodos necesarios para responder a ciertos tipos de eventos. Por ejemplo, para responder a los eventos de tipo **ActionEvent** necesitamos un objeto que haya implementado el método actionPerformed(ActionEvent event). +El manejador de eventos es un objeto que implementa los métodos necesarios para responder a ciertos tipos de eventos. Por ejemplo, para responder a los eventos de tipo ''ActionEvent'' necesitamos un objeto que haya implementado el método ''actionPerformed(ActionEvent event)''
  
 <code java> <code java>
Línea 372: Línea 459:
   * creando una clase concreta que implemente la //interface// **ActionListener**.   * creando una clase concreta que implemente la //interface// **ActionListener**.
  
-==== Clases Anónimas ====+==== Usando Clases Anónimas ====
  
-En alguna situaciones, dado que hay muy pocos componentes sobre los que manejar eventos, podemos evitar crear una clase propia para manejar eventos implementaremos el método para manejar eventos //actionPerformed()// directamente a la hora de contruir un objeto. Este se realiza mediante la instancición de una **clase anónima**:+En alguna situaciones, dado que hay muy pocos componentes sobre los que manejar eventos, podemos evitar crear una clase concreta para manejar eventos. Simplemente implementaremos el método para manejar eventos ''actionPerformed()'' directamente a la hora de contruir un objeto. Este se realiza mediante la instanciación de una **clase anónima**:
  
 <code java> <code java>
Línea 382: Línea 469:
 //Usamos una clase anónima que implementa la interface ActionListener //Usamos una clase anónima que implementa la interface ActionListener
 btnNewNuevo.addActionListener(new ActionListener() { btnNewNuevo.addActionListener(new ActionListener() {
 +
 +   //Y por lo tanto está obligada a implementar sus métodos
    @Override    @Override
    public void actionPerformed(ActionEvent evento) {    public void actionPerformed(ActionEvent evento) {
       //código que se ejecuta al producirse el evento       //código que se ejecuta al producirse el evento
    }    }
-});+}); //Fin de la llamada al método addActionListener()
  
 </code> </code>
  
-Si nos fijamos, el parámetro que pasamos al método addActionListener() no es la variable que contiene el objeto de tipo ActionListener, sino que dentro de los paréntesis creamos un nuevo objeto que implementa la interface ActionListener. **Estamos definiendo una clase anónima**.+Si nos fijamos, el parámetro que pasamos al método ''addActionListener()'' no es una variable que contiene el objeto de tipo ActionListener, sino que dentro de los paréntesis creamos un nuevo objeto que implementa la interface ''ActionListener''. **Estamos definiendo una clase anónima**.
  
-==== Interfaces ====+==== Usando Interfaces ==== 
 +Cuando tenemos que manejar eventos en muchos componentes (varios botones, diferentes eventos, etc) **la forma más correcta** es crear una clase que actúe como manejador de eventos, de modo que podamos crear un objeto de dicha clase y el mismo objeto se encargue de atender todos los eventos (objeto listener). 
 + 
 +Para ello debemos crear una clase que implemente las //interfaces// de cada tipo de evento. En el siguiente punto se indican las principales interfaces para manejar los eventos más habituales.
  
 <code java> <code java>
Línea 401: Línea 493:
 // código de la clase // código de la clase
  
 +//Método de la interface ActionListener que se ejecutará al capturar un evento
 @Override @Override
 public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
Línea 419: Línea 512:
  
 </code> </code>
- 
-**Esta forma es la más correcta.** 
  
 ==== Tipos Eventos y sus Interfaces Listener ==== ==== Tipos Eventos y sus Interfaces Listener ====
Línea 431: Línea 522:
 |WindowEvent|WindowListener|Al abrir o cerrar ventanas, o cambiar el icono|**windowActivated**(); **windowClosed**(); **windowClosing**(); **windowDeactivated**(); **windowDeiconified**(); **windowIconified**(); **windowOpened**()| |WindowEvent|WindowListener|Al abrir o cerrar ventanas, o cambiar el icono|**windowActivated**(); **windowClosed**(); **windowClosing**(); **windowDeactivated**(); **windowDeiconified**(); **windowIconified**(); **windowOpened**()|
 |FocusEvent|FocusListener|Cuando un elemento recibe el foco|**focusGained**(); **focusLost**()| |FocusEvent|FocusListener|Cuando un elemento recibe el foco|**focusGained**(); **focusLost**()|
 +|MouseEvent|MouseListener|Cuando uso el ratón en algún componente|**mouseClicked**(); **mouseEntered**(); **mouseExited**(); **mousePressed**(); **mouseReleased**()|
 |ContainerEvent|ContainerListener|Cuando añado o quito elementos de un contenedor|**componentAdded**(); **componentRemoved**()| |ContainerEvent|ContainerListener|Cuando añado o quito elementos de un contenedor|**componentAdded**(); **componentRemoved**()|
 |TableModelEvent|TableModelListener|Al modificar valores de celdas|**tableChanged**()| |TableModelEvent|TableModelListener|Al modificar valores de celdas|**tableChanged**()|
Línea 436: Línea 528:
 |ChangeEvent|ChangeListener|Al realizar cualquier cambio en el elemento|**stateChange**()| |ChangeEvent|ChangeListener|Al realizar cualquier cambio en el elemento|**stateChange**()|
 |ComponentEvent|ComponentListener|Al cambiar la propiedad ''visible'' o redimensionar elementos|**componentHidden**(); **componentMoved**(); **componentResized**(); **componentShown**()| |ComponentEvent|ComponentListener|Al cambiar la propiedad ''visible'' o redimensionar elementos|**componentHidden**(); **componentMoved**(); **componentResized**(); **componentShown**()|
-===== Diseñadores de interfaces ===== 
- 
-==== WindowBuilder para Eclipse ==== 
- 
-WindowBuilder es un plugin de código abierto para Eclipse destinado a crear interfaces gráficas de usuario (GUI) de forma rápida y sencilla. Como otros muchos sistemas de este tipo, contiene una paleta de elementos que podemos añadir mediante “drag and drop”, arrastrar y soltar. En lugar de tener que escribir el código a medida que vamos incluyendo elementos gráficos en nuestra ventana, WindowBuilder nos genera el código en nuestras clases. 
- 
-Aunque WindowBuilder sea una herramienta de gran ayuda, necesitamos comprender la estructura con la que WindowBuilder crea clases para poder modificarla y darle un formato a las clases que nos ayude a separar y entender el programa. 
- 
-=== Instalación de WindowBuilder === 
- 
-Para poder descargar WindowBuilder iremos en Eclipse a la pestaña ''Help'' y ahí a ''Eclipse MarketPlace…''. Buscamos el Plugin por su nombre (WindowBuilder) en el campo buscar, y una vez que lo haya encontrado, pulsamos sobre instalar. 
- 
-{{:bloque1:eclipsemarketplace1.png?300 |}} 
-{{ :bloque1:eclipsemarketplace2.png?300 |}} 
- 
-Al terminar la instalación, reiniciamos Eclipse y ya podremos trabajar con él. 
- 
-=== Crear un proyecto con ventanas === 
-WindowBuilder está compuesto de varias herramientas para crear interfaces gráficas de usuario. Nosotros vamos a trabajar únicamente con los componentes [[https://es.wikipedia.org/wiki/Swing_(biblioteca_gr%C3%A1fica)|Swing]]. 
-Para ello usaremos la herramienta Swing Designer de WindowBuilder.  
- 
-Por convenio, en Java una ''aplicación de escritorio'' empleará un contenedor principal de tipo ''JFrame''. Si además contiene otras ventanas secundarias dentro del programa emplearemos contenedores de tipo ''JDialog'' para estas ventanas secundarias. 
- 
- 
-**Creamos un proyecto** de la misma forma que lo hacemos siempre: 
- 
-{{:bloque1:creaproyecto1.jpg?300 |}} 
-{{ :bloque1:creaproyecto2.jpg?300 |}} 
- 
-**Creamos una clase JFrame** para una ventana. Dentro de nuestro proyecto, en algún ''package'' haremos lo siguiente. Debemos usar los componentes de Swing o de la sección Swing Designer de WindowBuilder: 
- 
-{{:bloque1:creaclase1.jpg?300 |}} 
-{{ :bloque1:creaclase2.jpg?300 |}} 
----- 
- 
-También podemos acceder de forma rápida al menú de WindowBuilder mediante su nuevo botón, siempre seleccionando Swing como componentes gráficos: 
- 
-{{:bloque1:creaclase3.png?300 |}} 
-{{ :bloque1:creaclase4.jpg?300 |}} 
- 
-Una vez creada la clase nos aparecerá una nueva vista, desde la cual podemos acceder al código o al diseño a través de las pestañas inferiores. 
- 
-{{:bloque1:pestanadiseno.jpg?300 |}} 
-{{ :bloque1:pestanacodigo.jpg?300 |}} 
- 
-=== Ventana sin Layout Manager === 
- 
-Para poder emplazar elementos en una ventana de cualquier tipo debemos indicar una organización (Layout). Si al principio no queremos complicarnos demasiado con un layout podemos trabajar de forma sencilla con **AbsoluteLayout**. Con este Layout podemos emplazar los elementos en el lugar que queramos, aunque no quedará tan bién a la hora de redimensionar la ventana. **Usando AbsoluteLayout los elementos se emplazan atendiendo a 4 coordenadas. Esto se desaconseja en el futuro, ya que no mantiene un orden al redimensionar la ventana.** 
- 
-{{:bloque1:contentpane.png?300 |}} 
-{{ :bloque1:absolutelayout.png?300 |}} 
- 
-Por defecto toda aplicación **JFrame** emplea un JPanel principal de contenido //contentPane//. En el iremos arrastrando todos los elementos que queramos emplear. Para aplicar un layout a nuestra ventana tan solo tenemos que pinchar sobre el layout que queremos usar y pinchar después sobre la ventana. 
- 
-{{ vimeo>246942867?medium }} 
- 
-=== Añadir manejadores de eventos === 
-{{ :bloque1:addeventhandler.png?350|}} 
-Para añadir un manejador de eventos a nuestra aplicación, bastará con pulsar clic derecho sobre el elemento (p.e. botón) sobre el cual queremos controlar un evento. Se nos desplegará un menú en el que podemos seleccionar el evento que queremos controlar. 
- 
- 
-En algunos componentes deberemos crear un manejador de eventos para otro tipo de eventos (KeyEvent, StateChanged, p.e.), aunque como se ha comentado, en la mayoría de los casos bastará con el evento //actionPerformed//. 
- 
-{{ :bloque1:addeventhandler2.png?300|}} 
-Cuando creemos un manejador de eventos, este se asociará al elemento sobre el cual se realiza el evento (p.e. botón).  
-Este código se creará justo debajo de la definición del componente, por lo que deberemos moverlo al lugar en el que lo queremos organizar (por ejemplo un método para inicializar los manejadores de eventos). 
- 
- 
-==== UIDesigner para IntelliJ ==== 
-Cuando trabajamos con el IDE IntelliJ, también haremos uso de su diseñador de interfaces **UIDesigner**. La principal diferencia con WindowBuilder, es que UIDesigner no crea elementos de tipo JFrame o JDialog, sino que crea contenedores de segundo nivel (JPanel).  
- 
-{{ :bloque1:uidesigner.png?direct&600 |}} 
- 
-Este elemento posteriormente debemos añadirlo a un contenedor de alto nivel, usando el método setContentPane(). 
- 
-Para crear una GUI utilizando IntelliJ, haremos lo siguiente: 
-  - Ir a File -> New 
-  - Seleccionar GUI Form (o Dialog) 
-  - Dar nombre al formulario y seleccionar el Layout Manager 
-  - Marcar el checkbox **Create bound class**, e indicar el nombre 
- 
-En la siguiente videoclase se enseña la creación de una aplicacion MVC desde 0, con el IDe IntelliJ. 
- 
-{{ vimeo>296086288?medium }} 
  
 ===== Patrón de diseño: Modelo-Vista-Controlador ===== ===== Patrón de diseño: Modelo-Vista-Controlador =====
Línea 525: Línea 533:
 Cuando se diseña una aplicacion aplicando el patrón de diseño //modelo-vista-controlador//, se persigue separar la aplicación en 3 capas diferenciadas: Cuando se diseña una aplicacion aplicando el patrón de diseño //modelo-vista-controlador//, se persigue separar la aplicación en 3 capas diferenciadas:
  
-  * La **vista** hace referencia a la ventana principal de la aplicación, la que contiene la mayoría de los elementos sobre los que el usuario va a interactuar. En MVC, la vista solo contiene el código referente a la construcción y organización de los componentes gráficos. Esta clase no contiene ningún //manejador de eventos// ni ningun código que haga alguna operación. No tiene ninguna interacción con el modelo.+  * La **vista** hace referencia a la ventana principal de la aplicación, la que contiene la mayoría de los elementos sobre los que el usuario va a interactuar. En MVC, la vista solo contiene el código referente a la construcción y organización de los componentes gráficos. Esta clase no contiene ningún //manejador de eventos// ni ningun código que haga alguna operación. Tampoco tiene ninguna interacción con el modelo, y es independiente del modelo y del controlador; de este modo es un componente reutilizable.
  
-  * El **modelo** es la capa que contiene los datos de la aplicación y los gestiona. Es la que se encarga de satisfacer las peticiones del usuario que se indican en la vista. Recordemos que el usuario solo interactua con la vista. El modelo contiene todos los métodos para realizar las operaciones de nuestra aplicación. Dar de alta elementos, eliminar, buscar, guardar, cargar, etc. No tiene ninguna constancia de la vista.+  * El **modelo** es la capa que contiene los datos de la aplicación y los gestiona. Es la que se encarga de satisfacer las peticiones del usuario que se indican en la vista. Recordemos que el usuario solo interactua con la vista. El modelo contiene todos los métodos para realizar las operaciones de nuestra aplicación. Dar de alta elementos, eliminar, buscar, guardar, cargar, etc. Es completamente independiente de la vista y del controlador.
  
-  * El **controlador** es la capa que comunica a las otras dos. Al llamar a su constructor, se le pasar como parámetro una instancia de la vista, y otra del modelo. El controlador es quien tiene implementados los manejadores de eventos y se los añade a los componentes de la vista indicados, y también es quien ejecuta las operaciones del modelo en respuesta a esos eventos. +  * El **controlador** es la capa que comunica a las otras dos. Al llamar a su constructor, se le pasa como parámetro una instancia de la vista, y otra del modelo. El controlador es quien tiene implementados los manejadores de eventos y se los añade a los componentes de la __vista__ indicados, y también es quien ejecuta las operaciones del __modelo__ en respuesta a esos eventos. 
  
-Resulta aconsejable que al menos las clases que representan el modelo, la vista y el controlador **estén dentro del mismo paquete** (''package'').+Resulta aconsejable que al menos las clases que representan la vista y el controlador **estén dentro del mismo paquete** (''package''). De este modo podemos hacer uso del modificador ''package-private'', también conocido como //default//.
  
 ==== Vista ==== ==== Vista ====
Línea 655: Línea 663:
     @Override     @Override
     public void actionPerformed(ActionEvent evt) {     public void actionPerformed(ActionEvent evt) {
 +       //El ActionCommand es una propiedad que se define en cada boton
        String comando = evt.getActionCommand();        String comando = evt.getActionCommand();
                
 +       //Dicha propiedad nos sirve para saber qué boton se ha pulsado
        switch(comando){        switch(comando){
           case "nuevo":           case "nuevo":
bloque1/interfaces.1604064803.txt.gz · Última modificación: 2024/09/16 20:55 (editor externo)