840 likes | 1.13k Views
Entrada/Salida – GUI - Eventos. Informática III. Temario. Modelo de I/O basado en streams Tipos de streams de I/O Serialización GUI – Patrones relacionados Modelos de interacción – Programación orientada a eventos Estrategias actuales de notificación y manejo de eventos.
E N D
Entrada/Salida – GUI - Eventos Informática III
Temario • Modelo de I/O basado en streams • Tipos de streams de I/O • Serialización • GUI – Patrones relacionados • Modelos de interacción – Programación orientada a eventos • Estrategias actuales de notificación y manejo de eventos
Introducción Entrada/Salida • Casi todos los programas para funcionar tienen que comunicarse con el “exterior” • De este “exterior” deben obtener datos y a su vez enviarle información • También podrían tener que reaccionar a eventos que ocurren en este “exterior”
Introducción Entrada/Salida • La entrada y salida de información comparten propiedades en común, tal como el movimiento unidireccional de datos, es decir una secuencia de bytes y caracteres, además del soporte para el acceso a dichos datos.
Introducción Entrada/Salida • Hay muchos tipos de fuentes de entrada de datos: • Lectura de un archivo en cualquier tipo de medio de almacenamiento físico • Recepción de una página web de un server remoto • Recepción de un mensaje a través de una red de comunicaciones • Recepción de una señal de un sensor de un robot, o un scanner/videocamara,… • Mouse, teclado, memoria, joystick,…
Introducción Entrada/Salida • En forma similar, hay muchos tipos de destinos de salida de datos: • Escritura a un archivo en cualquier tipo de medio de almacenamiento físico • Envío de un pedido de información a un web server remoto • Envío de un mensaje a través de una red de comunicaciones. Envío de un comando a un controlador de un robot o de datos a memoria • Imprimir un documento en una impresora/fax • Mostrar gráficos en una pantalla
Modelo de I/O en programación orientada a objetos • Se utiliza una abstracción común a todo tipo de I/O, a través del concepto de streams (flujo de datos de entrada o salida) para representar la secuencia ordenada de datos • Los streams proporcionan una interface entre el programa y un dispositivo de I/O orientada a objetos, uniforme, fácil de usar
Modelo de I/O en programación orientada a objetos • Se trata de ocultar tanto como sea posible los detalles de las fuentes/destinos reales de I/O • Se podría imaginar un stream como un camino a lo largo del cual fluyen los datos, tal como un río o tubería por donde fluye agua
Modelo de I/O en programación orientada a objetos Fuente Válvula que conecta fuente con stream Stream Destino Vista conceptual del stream
Streams de I/O – División básica • De acuerdo a la dirección del stream podemos tener: Streams de entrada Streams de salida Conceptualmente los dos tipos están separados
Streams de I/O – División básica • Un stream de entrada (salida) es una secuencia de bytes ligada a alguna(ún) fuente de entrada (destino de salida). Se pueden leer (escribir) en orden secuencial de a uno o de a varios bytes. Input Stream reads Source Program Output Stream writes Program Target
Streams de I/O – División básica • A grandes rasgos, para leer un stream: Abrir un stream s while (hay mas datos en s) read algo más de datos close s • Idem para la escritura • Importante: los programas deben tomar recaudos para cerrar los streams cuando ya no se necesiten, de otra forma se pierden recursos
Streams de I/O – División básica • Basado en los tipos de datos con que operan: Byte stream Character stream Hoy en lenguajes OO char!=byte, por tanto están separados
Streams de I/O – División básica • Síncronos (blocking) y asíncronos (non-blocking). El bloqueo se refiere a la situación donde la operación de lectura o escritura en un stream no retornan hasta terminar la misma. • Si, por ejemplo, la comunicación de datos de una fuente es extremadamente lenta o intermitentemente retardada por largos períodos, el bloqueo puede ser un problema. Se consumen recursos de un thread durante estos períodos muertos, esperando que la transferencia de datos se restablezca.
Tipos de streams • Los conceptos de enviar datos de un stream a otro (como un pipe alimentando a otro pipe) hizo de los streams una herramienta potente para el procesamiento de archivos (files) • Se pueden transformar objetos en streams de bytes (serialización) y reconstruirlos posteriormente a partir de dichos streams (deserialización) • Conectar streams puede actuar como filters, produciendo streams compuestos de mayor utilidad.
Problema de diseño • Hay muchas variantes en la lectura/escritura de datos: • Leer tipos de datos complejos (líneas de texto, objetos, enteros, números en punto flotante) • Buffering de datos por eficiencia • Necesitar “devolver” caracteres o bytes cuando se han leído demasiados • Llevar la cuenta del número de línea al leer
Problema de diseño • Si incluiríamos todas las variantes en todos los tipos de streams se tendría mucho código duplicado y sería muy difícil de añadir nuevos tipos de streams • Normalmente no se utilizan todas las combinaciones posibles a la vez
Solución: Patrón decorator (decorador), wrapper o filter • En lugar de crear clases nuevas para tener en cuenta todas las combinaciones, los decoradores añaden capas de funcionalidad a las clases de I/O. El decorador se ajusta a la interfaz del componente que decora de manera que su presencia es transparencia a los clientes. El decorador redirige sus peticiones al objeto interno que “envuelve”
Ejemplo en Java BufferedReader BufferedReader (Reader r) readLine() Reader read() read() ... ... ... ...
Ejemplo en Java public class type { public static void main(String[] args) { try { BufferedReader reader = new BufferedReader(new FileReader(args[0])); String line; while ((line=reader.readLine())!=null) System.out.println(line); } catch (IOException ioe) { System.err.println(“Reading failed.”); } }}
Ejemplo en Java: encadenamiento de decoradores try { DataInputStream input = new DataInputStream( new BufferedInputStream( new FileInputStream(args[0]))); } catch (FileNotFoundException fnfe) { // ...} read() read() read() Data Buffered File readShort()
Pipes • Los streams piped se usan como parejas de I/O. Los datos que se escriben en el stream de salida de una pareja son los datos que se leen del stream de entrada. El conducto de transmisión mantiene un buffer interno, con una capacidad definida por la implementación, que permite que la lectura y escritura se realicen a diferentes velocidades. • Proporcionan un mecanismo basado en I/O y en el paradigma productor/consumidor para comunicar datos entre diferentes hilos. • Puede suspender las operaciones de I/O debido a: • Lectura: debido a que el buffer esté vacío • Escritura: debido a que el buffer esté lleno
Serialización/Deserialización • Serialización: proceso de convertir un objeto en un único stream de bytes • Deserialización: la reconstrucción de un objeto a partir de un stream de bytes que lo representa
Entradas/Salidas en una GUI • Las operaciones de entrada y salida relacionadas con una interface gráfica de usuario usualmente se tratan en forma separada • Casi todos los programas actuales incorporan una GUI: el usuario controla el programa via esta interface • Esto conduce a un diferente estilo de programación: manejada por eventos
Modelo de interacción • Hay 2 formas de modelar la manera de interactuar entre un programa que se está ejecutando y su(s) usuario(s): • Interacción controlada por la computadora o el programa • Interacción controlada por el usuario • La diferencia entre ambas es clara: ¿quién controla la interacción? ¿quién determina en qué momento tendrá lugar la interacción? ¿quién determina cuál será la siguiente entrada provista al programa?
Interacción controlada por la computadora • Antes de la manipulación directa de las GUI, la interacción estaba a cargo del programa • En forma simplificada un programa:
Interacción controlada por el usuario • Manipulación directa de interfaces gráficas. La arquitectura es mucho más complicada puesto que el usuario y no el programa lleva el control • Se presenta al usuario objetos concretos sobre una pantalla • Se responde a la manipulación del usuario de esos objetos. Aunque limitado al manejo de los objetos provisto en la IG el usuario decide cuál es el siguiente objeto a seleccionar
Eventos y notificación de eventos • Las modernas GUIs se comunican mediante eventos, o más exactamente mediante notificación de eventos con: • Otras aplicaciones • Partes de ella misma • El código que implementa la funcionalidad de la GUI Un evento ocurre, en general, por cada acción del usuario involucrando la GUI
Eventos y notificación de eventos • Son dos conceptos distintos • Un evento ocurre cuando el usuario manipula algún dispositivo de entrada • La notificación del evento ocurre cuando la aplicación es notificada de la ocurrencia del mismo • Normalmente se trata que el tiempo ocurrido entre la ocurrencia del evento y la notificación del mismo a la aplicación sea pequeño
Windowing systems • Es una capa de soft supervisor que facilita el uso de GUIs • Maneja el estado “real” de la pantalla: • Respondiendo a requerimientos de la aplicación para crear, organizar y destruir ventanas (o widgets) • Permitiendo al usuario controlar el tamaño y ubicación de las ventanas (window manager)
Jerarquías de ventanas • Usualmente se mantiene una jerarquía tipo árbol para todas las ventanas • La raíz de esta jerarquía es la pantalla. Puede haber más de una ventana en la raíz de esta jerarquía
¿Qué es una ventana? • Aunque la terminología varía en los distintos sistemas, usualmente es un objeto que tiene dos partes: • Una región de la pantalla con una imagen visual (caja de texto, slider, check box,etc) • Una instancia de una clase que recibirá notificación de los eventos relevantes a la ventana y responderá a los mismos • La imagen de la misma es usualmente rectangular • Normalmente organizadas en jerarquías tanto por el windowing system y las aplicaciones que las usan
¿A quién pertenece una ventana? • En general una aplicación es la “propietaria” de una ventana • En particular, algunas aplicaciones pueden permitir que parte de su espacio de ventanas sea controlado por otra aplicación (Ej.:en OLE una planilla de Excel que se pega en un documento Word; Excel “controla” el espacio donde está pegado la planilla)
¿Qué son los “widgets”? • Son los objetos que aparecen normalmente en una GUI, se los suele llamar controles atómicos. • Ej.: sliders, listas desplegables, botones, cajas de texto • La clase asociada a los mismos normalmente es provista usando alguna subclase provista por el lenguaje utilizado o por la aplicación misma, para ganar acceso a todas las funcionalidades del mismo
Gestión de ventanas • Los usuarios pueden requerir mover o cambiar el tamaño de las ventanas en la raíz de la jerarquía • Estos requerimientos se envían al componente window manager del windowing system que lleva el registro de cómo las ventanas van ocupando el espacio visual de la pantalla • Además estos requerimientos se pasan al código de la ventana tal que pueda responder adecuadamente
Por ejemplo... • Cuando el usuario hace click en una barra de títulos de una ventana y la arrastra, se está enviando al window manager un requerimiento de mover esa ventana • Esto obviamente afecta la posición de la ventana en la pantalla, la cual debe registrarse aunque, también puede provocar que todo o parte de otras ventanas queden expuestas u ocultas • La notificación de estos eventos se envían a las ventanas afectadas de forma tal que puedan responder
Construcción de una aplicación con GUI • Casi todos los lenguajes modernos proveen facilidades para evitar muchos de los detalles requeridos para construir una aplicación • Proveen mecanismos para una inicialización de los componentes visuales y manejos de eventos. Simplemente se tienen que identificar qué eventos intersa registrar en la aplicación
Algunos patrones asociados a GUIs • Observer – Manejo de eventos • Strategy – Layout managements • Composite - Contenedores • Decorator – Scrollbars (Se añade funcionalidad manteniendo la misma interface. Por ejemplo a una lista se la puede “envolver” para añadirle barras de desplazamiento)
Patrón composite • Compone objetos (que pueden servir como contenedores) en estructuras de árbol para representar jerarquías parte-todo. Permite que los clientes traten de manera uniforme a los objetos individuales y a los compuestos • Ejemplo: en una GUI un panel puede contener a otro que a su vez contiene un botón
Ejemplo en Java Container north = new JPanel(new FlowLayout()); north.add(new JButton("Button 1")); north.add(new JButton("Button 2")); Container south = new JPanel(new BorderLayout()); south.add(new JLabel("Southwest"), BorderLayout.WEST); south.add(new JLabel("Southeast"), BorderLayout.EAST); Container cp = getContentPane(); cp.add(north, BorderLayout.NORTH); cp.add(new JButton("Center Button"), BorderLayout.CENTER); cp.add(south, BorderLayout.SOUTH);
Strategy • Strategy: Objetos que contienen algoritmos alternativos que resuelven un problema • Un layout manager tiene la responsabilidad de disponer visualmente los componentes dentro de una ventana contenedora • Los layout managers normalmente son tratadas como estrategias. Este patrón se utiliza cuando se tienen muchas clases relacionadas que difieren sólo en su comportamiento.
Ejemplo en Java Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(0,2));//tantas filas como necesita contentPane.add(new JButton("Button 1"));
Decorator • Objetos que envuelven a otros para añadir características útiles
Ejemplo en Java // JScrollPane decorates GUI components JTextArea area = new JTextArea(20, 30); JScrollPane scrollPane = new JScrollPane(area); contentPane.add(scrollPane);
Lazo de eventos • Initialization While (not time to quit) { Get next event E Dispatch event E } • La parte sustanciosa del programa está en el código que maneja “dispacth”
Eventos • Comenzaron como estructuras simples tipo registros (tipo estructuras de C) • Creadas por una combinación de código en el SO y el programa que se está ejecutando • El SO responde a una interrupción causada por algo como un click del mouse o una tecla pulsada • El sistema pasa tales detalles a una rutina de suporte del runtime conectada con la aplicación • Esta rutina llena una estructura con los datos del evento. Por ej.:”Evento pulsado del botón izquierdo del mouse, en el instante ..., coordinadas del cursor en la pantalla...,...” • Podrían ser procesados inmediatamente, usualmente se meten en una cola para su posterior procesamiento.