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

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
bloque1:interfaces [2020/10/30 13:30] – [Tipos Eventos y Manejadores] fernandobloque1:interfaces [2020/11/19 00:10] (actual) – [UIDesigner para IntelliJ] fernando
Línea 345: Línea 345:
 https://docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html https://docs.oracle.com/javase/tutorial/uiswing/components/editorpane.html
  
-===== Manejadores de Eventos ===== 
  
-==== Eventos ==== 
-Un evento es una acción, provocada en la mayoría de los casos por el usuario, y que supone un cambio en el estado de algún componente (por ejemplo, botón). 
-Los eventos, permiten llevar a cada la funcionalidad de las aplicaciones basadas en una GUI.  
- 
-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).  
- 
-<code java> 
-public void actionPerformed(ActionEvent evento) 
- //El código de este método se ejecuta cuando se poduce un evento 
-} 
-</code> 
- 
-Después debemos vincular los elementos gráficos que queremos que respondan a los eventos. Para esto añadimos el objeto manejador de eventos al componente que queramos. 
- 
-<code java> 
-JButton btnNuevo = new JButton("Nuevo"); 
- btnNuevo.addActionListener(manejadorEventos); 
-</code> 
- 
-Para tener un objeto que maneje eventos, podemos usar dos planteamientos: utilizando una clase anónima que implemento el método **actionPerformed()** o creando una clase concreta que implemente la //interface// **ActionListener**. 
-==== Interfaces ==== 
- 
-<code java> 
- 
-public class ManejadorEventos implements ActionListener{ 
- 
- ... 
-// código de la clase 
- 
-@Override 
-public void actionPerformed(ActionEvent arg0) { 
-   //Código del manejador de eventos 
- 
-} 
- 
-} 
- 
-</code> 
- 
-Una vez que tengamos una clase que sirva de manejador de eventos, asociamos un objeto de dicha clase a cada componente sobre el que queramos responder a sus eventos: 
-<code java> 
- 
-ManejadorEventos listener = new ManejadorEventos(); 
- 
-boton.addActionListener(listener); 
- 
-</code> 
- 
-**Esta forma es la más correcta.** 
-==== 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 e 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**: 
- 
-<code java> 
- 
-JButton btnNuevo = new JButton("Nuevo"); 
- 
-//Usamos una clase anónima que implementa la interface ActionListener 
-btnNewNuevo.addActionListener(new ActionListener() { 
-   @Override 
-   public void actionPerformed(ActionEvent evento) { 
-      //código que se ejecuta al producirse el evento 
-   } 
-}); 
- 
-</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**. 
- 
-==== Tipos Eventos y Manejadores ==== 
-A continuación se indican los tipos de eventos más habituales y las interfaces que implementan métodos //listener//: 
- 
-^ Tipo Evento^Interface^Descripción^Métodos^ 
-|ActionEvent|ActionListener|Al pulsar botones|**actionPerformed**()| 
-|KeyEvent|KeyListener|Al pulsar teclas|**keyTyped**(); **keyPressed**(); **keyReleased**()| 
-|ListSelectionEvent|ListSelectionListener|Al seleccionar o deseleccionar en una lista|**valueChanged**()| 
-|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**()| 
-|ContainerEvent|ContainerListener|Cuando añado o quito elementos de un contenedor|**componentAdded**(); **componentRemoved**()| 
-|TableModelEvent|TableModelListener|Al modificar valores de celdas|**tableChanged**()| 
-|PropertyChangeEvent|PropertyChangeListener|Al cambiar alguna propiedad del elemento|**propertyChange**()| 
-|ChangeEvent|ChangeListener|Al realizar cualquier cambio en el elemento|**stateChange**()| 
-|ComponentEvent|ComponentListener|Al cambiar la propiedad ''visible'' o redimensionar elementos|**componentHidden**(); **componentMoved**(); **componentResized**(); **componentShown**()| 
 ===== Diseñadores de interfaces ===== ===== Diseñadores de interfaces =====
  
Línea 479: Línea 393:
 === Ventana sin Layout Manager === === 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.**+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:contentpane.png?300 |}}
Línea 493: Línea 407:
  
  
-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//.+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|}} {{ :bloque1:addeventhandler2.png?300|}}
Línea 513: Línea 427:
   - Marcar el checkbox **Create bound class**, e indicar el nombre   - 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.+En la siguiente videoclase se enseña la creación de una aplicacion MVC desde 0, con el IDE IntelliJ.
  
 {{ vimeo>296086288?medium }} {{ vimeo>296086288?medium }}
 +
 +===== 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 ====
 +Un evento es una acción, provocada en la mayoría de los casos por el usuario, y que supone un cambio en el estado de algún componente (por ejemplo, botón).
 +Los eventos, permiten llevar a cada la funcionalidad de las aplicaciones basadas en una GUI. 
 +
 +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)''
 +
 +<code java>
 +public void actionPerformed(ActionEvent evento)
 + //El código de este método se ejecuta cuando se poduce un evento
 +}
 +</code>
 +
 +Después debemos vincular los elementos gráficos que queremos que respondan a los eventos. Para esto añadimos el objeto manejador de eventos al componente que queramos.
 +
 +<code java>
 +JButton btnNuevo = new JButton("Nuevo");
 + btnNuevo.addActionListener(manejadorEventos);
 +</code>
 +
 +Para tener un objeto que maneje eventos, podemos usar dos planteamientos: 
 +  * utilizando una clase anónima que implemento el método **actionPerformed()** 
 +  * creando una clase concreta que implemente la //interface// **ActionListener**.
 +
 +==== Usando Clases Anónimas ====
 +
 +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>
 +
 +JButton btnNuevo = new JButton("Nuevo");
 +
 +//Usamos una clase anónima que implementa la interface ActionListener
 +btnNewNuevo.addActionListener(new ActionListener() {
 +
 +   //Y por lo tanto está obligada a implementar sus métodos
 +   @Override
 +   public void actionPerformed(ActionEvent evento) {
 +      //código que se ejecuta al producirse el evento
 +   }
 +}); //Fin de la llamada al método addActionListener()
 +
 +</code>
 +
 +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**.
 +
 +==== 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>
 +
 +public class ManejadorEventos implements ActionListener{
 +
 + ...
 +// código de la clase
 +
 +//Método de la interface ActionListener que se ejecutará al capturar un evento
 +@Override
 +public void actionPerformed(ActionEvent arg0) {
 +   //Código del manejador de eventos
 +
 +}
 +
 +}
 +
 +</code>
 +
 +Una vez que tengamos una clase que sirva de manejador de eventos, asociamos un objeto de dicha clase a cada componente sobre el que queramos responder a sus eventos:
 +<code java>
 +
 +ManejadorEventos listener = new ManejadorEventos();
 +
 +boton.addActionListener(listener);
 +
 +</code>
 +
 +==== Tipos Eventos y sus Interfaces Listener ====
 +A continuación se indican los tipos de eventos más habituales y las interfaces que implementan métodos //listener//:
 +
 +^ Tipo Evento^Interface^Descripción^Métodos^
 +|ActionEvent|ActionListener|Al pulsar botones|**actionPerformed**()|
 +|KeyEvent|KeyListener|Al pulsar teclas|**keyTyped**(); **keyPressed**(); **keyReleased**()|
 +|ListSelectionEvent|ListSelectionListener|Al seleccionar o deseleccionar en una lista|**valueChanged**()|
 +|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**()|
 +|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**()|
 +|TableModelEvent|TableModelListener|Al modificar valores de celdas|**tableChanged**()|
 +|PropertyChangeEvent|PropertyChangeListener|Al cambiar alguna propiedad del elemento|**propertyChange**()|
 +|ChangeEvent|ChangeListener|Al realizar cualquier cambio en el elemento|**stateChange**()|
 +|ComponentEvent|ComponentListener|Al cambiar la propiedad ''visible'' o redimensionar elementos|**componentHidden**(); **componentMoved**(); **componentResized**(); **componentShown**()|
  
 ===== Patrón de diseño: Modelo-Vista-Controlador ===== ===== Patrón de diseño: Modelo-Vista-Controlador =====
Línea 521: 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 651: 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.1604064614.txt.gz · Última modificación: 2020/10/30 13:30 por fernando