Foros del Web » Programación para mayores de 30 ;) » Java »

Manejo de evento

Estas en el tema de Manejo de evento en el foro de Java en Foros del Web. Estoy (intentando) hacer un programa que se comunica con una impresora de etiquetas conectada al puerto serie del pc. Tengo hecha la clase para recibir ...
  #1 (permalink)  
Antiguo 09/11/2006, 02:07
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Manejo de evento

Estoy (intentando) hacer un programa que se comunica con una impresora de etiquetas conectada al puerto serie del pc.
Tengo hecha la clase para recibir y enviar datos.
El código lo he ido montando a partir copiar y pegar de ejemplos que me he ido encontrando (soy novato en esto de java)...
La parte de lectura es la que no entiendo, entiendo que lo administra a partir de un evento y que en cuanto recibe algo pues se ejecuta el codigo que se encuentra en el metodo serialEvent(SerialPortEvent event).

Lo que yo pretendo hacer es que si la impresora me retorna un error, poder tomar otro rumbo en el programa principal, pero el evento este (creo) se ejecuta a través de un ¿thread?, por lo tanto "paralelamente" al hilo principal y no se como desde un hilo afectar el rumbo del otro... nose si me explico..
  #2 (permalink)  
Antiguo 09/11/2006, 02:10
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Aquí dejo el codigo de la clase:
Código:
package puerto_serie;

import javax.comm.*;
import java.io.*;			//Input & Output Stream
import java.util.*;		//EventListener class



public class ComControl implements Runnable, SerialPortEventListener
{
	static CommPortIdentifier portId;
	
	InputStream 	canalEntrada;
	OutputStream 	canalSalida;
	SerialPort 		puerto;
	Thread 				readThread;
	
	protected String divertCode = "10";
	static String TimeStamp;



	public void main(String[] args)
	{	try
		{	this.portId = CommPortIdentifier.getPortIdentifier("COM1");
		}
		catch(Exception e)
		{	TimeStamp = new java.util.Date().toString();
			System.out.println(TimeStamp + ": COM1 " + this.portId);
			System.out.println(TimeStamp + ": msg1 - " + e);
		}		
	}
	
	//Constructor
	public ComControl()
	{	
		try
		{	this.portId = CommPortIdentifier.getPortIdentifier("COM1");
		}
		catch(Exception e)
		{	TimeStamp = new java.util.Date().toString();
			System.out.println(TimeStamp + ": COM1 " + this.portId);
			System.out.println(TimeStamp + ": msg1 - " + e);
		}		
		
		try
		{	TimeStamp = new java.util.Date().toString();
			this.puerto = (SerialPort) this.portId.open("ComControl", 2000);
		}
		catch(PortInUseException e)
		{	System.out.println("Hay otra aplicación usando el puerto COM1, imposible continuar.");
			return;
		}
		
		try
		{	this.canalEntrada = this.puerto.getInputStream();
			this.canalSalida = this.puerto.getOutputStream();
		}
		catch(IOException e)
		{}
		
                //Como hace referencia esto a serialEvent(SerialPortEvent event)?
		try
		{	this.puerto.addEventListener(this);
		}
		catch(TooManyListenersException e)
		{}
		
		this.puerto.notifyOnDataAvailable(true);
		try
		{ this.puerto.setSerialPortParams(9600,
				SerialPort.DATABITS_8,
				SerialPort.STOPBITS_1,
				SerialPort.PARITY_NONE);
			//this.puerto.setDTR(false);	//Depends on device
			//this.puerto.setRTS(false);	//Depends on device
		}
		catch(UnsupportedCommOperationException e)
		{}
		//Estas dos lineas no las acabo de entender
		this.readThread = new Thread(this);
		this.readThread.start();		
	}
	
	
	//Sobrecargamos el metodo run() de la interface Runnable
//Esto no entiendo a cuento de que viene
	public void run()
	{	try
		{	System.out.println("Buscamos evento");
			Thread.sleep(100);
		}
		catch(InterruptedException e)
		{}
	}
	
	//Definimos el evento del puerto serie
	public void serialEvent(SerialPortEvent event)
	{	switch (event.getEventType()) 
		{	case SerialPortEvent.BI:
			case SerialPortEvent.OE:
			case SerialPortEvent.FE:
			case SerialPortEvent.PE:
			case SerialPortEvent.CD:
			case SerialPortEvent.CTS:
			case SerialPortEvent.DSR:
			case SerialPortEvent.RI:
			case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
				break;
			case SerialPortEvent.DATA_AVAILABLE:
				 byte[] bufferLectura = new byte[20];
					try 
					{	while( canalEntrada.available() > 0 ) 
						{	int nBytes = canalEntrada.read( bufferLectura );
            }
						System.out.println( new String(bufferLectura) );
					} catch( IOException e ) {}
        break;
		}
     
	}
	
	public void enviaDatos(String loque)
	{	try
		{	this.canalSalida.write(loque.getBytes());
		}
		catch(IOException e)
		{	}
		
		try
		{	System.out.println("Duermo 2000");
			Thread.sleep(2000);	//Nos aseguramos que da tiempo a enviar los datos antes de cerrar la conexion			
		}
		catch(Exception e)
		{}		
	}
	
	public void cierraPuerto()
	{	this.puerto.close();
	}
}
  #3 (permalink)  
Antiguo 09/11/2006, 02:20
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Hay ciertas partes dela clase que no acabo de entender...

Tenemos esto que crea un detector de eventos sobre el puerto,
lo que no entiendo es como hace esto referencia a la función que se desea se llame al ejecutarse el evento, en este caso serialEvent(SerialPortEvent event)
Código:
try
{	this.puerto.addEventListener(this);
}
catch(TooManyListenersException e){}
Siguiente:
Tampoco entiendo exactamente que es lo que hace esta linea, se que es digamos como el main de una clase, pero aplicado a la clase Thread.
No se que papel juega... :(
Código:
public void run()
{	try
	{	Thread.sleep(100);
	}
	catch(InterruptedException e)
	{}
}
  #4 (permalink)  
Antiguo 09/11/2006, 02:28
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Esta es la clase que uso para ininciar al programa

Código:
import java.io.*;
import java.util.*;

public class start
{	puerto_serie.ComControl controlSerie;
	
	public static void main(String[] args)
	{	start control= new start();
	
		//Iniciamos conexión con impresora
		control.controlSerie= new puerto_serie.ComControl();
	char XON=(char)17;
	char XOFF=(char)19;
	char LF=(char)10;
	char CR=(char)13;
	String cadena=XON+CR+LF+
	"N"+CR+LF+
	"X0,0,4,60,100"+CR+LF+
	"LO0,50,50,4"+CR+LF+
	"LO40,100,4,100"+CR+LF+
	"A40,100,1,1,1,1,N,\"MADE IN YEAH\""+CR+LF+
	"B50,60,0,1,2,3,96,B,\"S 000001\""+CR+LF+
	"P1"+CR+LF+XOFF;
		
	control.controlSerie.enviaDatos(cadena);
	control.controlSerie.cierraPuerto();		
	return;
	}
}
De momento es muy sencillo, el programa envia los datos y si ocurre un error cn la impresora se muestra el error por pantalla.
Pero pretendo hacer un interfaz gafico y quisiera poder poner opciones como "volver a intentar", "resumir impresion", etc...
Osea dependiendo del error ejecutar un metodo u otro de la clase principal. No se si es posible esto.
  #5 (permalink)  
Antiguo 13/11/2006, 08:27
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Bueno, investigando ahora ya se que significa esto y como estan relacionados los eventos con los listeners
Código:
try
{	this.puerto.addEventListener(this);
}
catch(TooManyListenersException e){}

Pero sigo sin entender que pinta el thread ahi:
Código:
public void run()
{	try
	{	Thread.sleep(100);
	}
	catch(InterruptedException e)
	{}
}
Reptio lo que quiero conseguir...
Necesito poder enviar datos a la impresora (lo tengo solucionado), y recibir los datos que esta me envie, asi como responder estos mensajes.

Los mensajes que me envie la impresora no tienen xq emitirse despues de recibir i procesar los mios, pueden ser en cualquier momento (apertura de la tapa, error de impresion...) y tambien tengo que poder responderle a estos mensajes.

Tan solo pretendo que me orienteis, no que alguien me haga el codigo (es mas, diria que lo tengo casi listo pero no se acabar de cuadrar las cosas).
Espero que alguien pueda ayudarme
  #6 (permalink)  
Antiguo 13/11/2006, 08:59
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 21 años, 1 mes
Puntos: 51
Hola,

Lo primero que te recomendaría es echarle un vistazo al tema del multiproceso con Threads en Java (por ejemplo en http://java.sun.com/docs/books/tutor...l/concurrency/) y así entenderás un poco más la sintaxis.

La idea es más o menos la siguiente. Tu lanzas tu programa y quieres que este escuchando del puerto y que pueda recibir comandos a la vez, no? Para eso tiene que estar "escuchando" de dos sitios diferentes. Para poder escuchar de la impresora se lanza un proceso que no hace "nada" y que se ejecuta en paralelo, escuchando eventos y reaccionando a ellos.

El problema es que los trozos de codigo que has pegado no "casan" muy bien entre ellos. El Thread que lanzas en paralelo solo duerme 100ms y luego se muere (al acabar el metodo run() un Thread simplemente desaparece) así que si no ocurre nada en 100m, se acabó.

Cuando tienes varios procesos, entonces tienes que usar los mecanismos para que se comuniquen entre ellos (básicamente pasarse referencias entre ellos y llamarse a metodos) y para sincronizarlos (métodos sincronizados, wait, notify, join, en Java 5 hay más cosas...).

Si no has hecho nunca programación concurrente, no es un tema trivial (Java aparte) por que entonces te recomendaría ir poco a poco con algún texto básico. Algo como: http://www.mcs.drexel.edu/~shartley/ConcProgJava/

Suerte
  #7 (permalink)  
Antiguo 13/11/2006, 10:40
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Cita:
Tu lanzas tu programa y quieres que este escuchando del puerto y que pueda recibir comandos a la vez, no?
Bueno, me refiero a que yo le pueda enviar datos y a la vez recibir, no se si te refieres a eso...

Lo de que no casan mucho ya lo veo, realmente necesito el thread? No basta con el eventListener?
Por lo poco (aún) que he leido veo que se podria hacer algo asi tambien:
Código:
public void run()
{	while(true)
	{	try
		{	if(SerialPortEvent.DATA_AVAILABLE==1)
			{ byte[] bufferLectura = new byte[20];
				try 
				{	while( outputStream.available() > 0 ) 
					{	int nBytes = outputStream.read( bufferLectura );
                                         }
				        System.out.println( new String(bufferLectura) );
			         } catch( IOException e ) {}
			}
			Thread.sleep(10);
		}
		catch(InterruptedException e)
		{}			
	}		
}
  #8 (permalink)  
Antiguo 14/11/2006, 04:20
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Bueno, creo que ya lo tengo solucionado, al final hice esto:
//Archivo com.java
Código:
import javax.comm.*;
import java.io.*;
import java.util.*;


public class com implements SerialReaderListener
{
	protected Enumeration ports;						//Listado de puertos
	protected CommPortIdentifier port_id;		
	public	SerialPort	puerto;					//Subclase de CommPort
		
	//protected	InputStream inputStream;			//Para el envio de datos al dispositivo (Subclase de CommPort)
	//protected	OutputStream outputStream;				//Subclase de CommPort
	
	private InputStream inputStream;	//Para el envio de datos al dispositivo.
	private OutputStream outputStream;			//Para la lectura del dispositivo
		
		
	protected String response;					//Ultima linea leida desde el puerto serie
	protected boolean debug = true;			//flag para el controlar la salida debug
		
	private final int TIMEOUT = 30;		//Tiempo de espera maximo para abrir el puerto	
		
	//Constructor
	com()
	{	ports=CommPortIdentifier.getPortIdentifiers();
	}
	
	
	//Busca los puertos disponibles en el PC
	public ArrayList listarPuertos()
	{	
		ArrayList<String> nombre_puertos = new ArrayList<String>();
		CommPortIdentifier temp_port;
		while(ports.hasMoreElements())
		{	temp_port=(CommPortIdentifier)ports.nextElement();
			if( CommPortIdentifier.PORT_SERIAL==temp_port.getPortType() )
			{	nombre_puertos.add( (String) temp_port.getName());
			}
		}
		return nombre_puertos;
	}
	
	
	//Abrir puerto
	public Object abrirPuerto(String nombre_puerto)
	{	//Cogemos el identificador del puerto
		try
		{	this.port_id = CommPortIdentifier.getPortIdentifier(nombre_puerto);
		}
		catch(Exception e)
		{	return (String)e.getMessage();
		}
		
		//Intentamos abrir el puerto
		try
		{	puerto = (SerialPort) this.port_id.open("Impresión Etiquetas", TIMEOUT*1000);
		}
		catch(PortInUseException e)
		{	return "Ya hay otra aplicación usando el puerto "+nombre_puerto+".\nEscoge otro.";
		}
		catch(Exception e)
		{	return "Problema abriendo el puerto";
		}
		
		//Configuramos el puerto
		try
		{ puerto.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
		}
		catch(UnsupportedCommOperationException e)
		{}
		
		//Creamos los canales de entrada/salida de datos
		try
		{	//inputStream = puerto.getInputStream();
			outputStream = puerto.getOutputStream();
			//puerto.notifyOnDataAvailable(true);
		}
		catch(IOException e)
		{	return (String) e.getMessage();
		}
		
		//Start the thread that reads the serial comm
		(new SerialReaderThread(this, this.puerto)).start();

		return "1";	//Todo OK
	}
	
	
	public void send(String loQue)
	{
		try
		{	this.outputStream.write(loQue.getBytes());
		}
		catch(IOException e)
		{}
		
		try
		{	Thread.sleep(100);
		}
		catch(Exception e)
		{}
	}
	
	
	//Acciones a realizar al recibir datos
	public void newData(int data)
	{	System.out.print("Datos: "+(char)data);
	}
	
	
	//Cerrar puerto
	public void cerrarPuerto()
	{	try
		{	puerto.close();
		}
		catch(Exception e){}
	}

}
Archivo SerialReaderThread.class
Código:
import java.io.*;
import javax.comm.*;

public class SerialReaderThread extends Thread
{	
	private SerialReaderListener listener;
	public SerialPort puerto;
	
	//Constructor
	public SerialReaderThread(SerialReaderListener listener, SerialPort puerto)
	{	this.listener = listener;
		this.puerto = puerto;
	}
	
	public void run()
	{	DataInputStream p = null;
		try
		{	p = new DataInputStream(this.puerto.getInputStream());
			int input;
			while((input=p.read())!=-1)
				listener.newData(input);
			
		}
		catch(IOException e)
		{}
		finally
		{	try
			{	p.close();
			}
			catch(IOException e)
			{}
		}
	}

}
Y por ultimo el interface SerialReaderListener.class
Código:
import javax.comm.*;

interface SerialReaderListener
{	void newData(int data);
}
Con esto puedo por fin leer del puerto serie, pero me surgen dos dudas:
1- Los comandos que me envia la impresora pueden estar compuestos por mas de un caracter, pero el codigo arriba escrito no me trata como conjunto todo un comando, sino que simplemente va recibiendo caracteres (y de momento imprimiendolos por pantalla). Como puedo tratar a un conjunto de caracteres como un comando?
Habia pensado en ir metiendo en un array los caracteres a medida que me llegaran, i a la que dejara de recibir datos pasar este array al metodo newData... pero no se como afrontarlo

2-Los caracteres me llegan en formato ASCII, pero no estoy muy convencido de la manera en q los estoy visualizando... (Se que el caracter 13 corresponde al salto de linea, pero en vez de eso se muestra un simbolo muy raro).

Última edición por clinisbut; 14/11/2006 a las 05:00
  #9 (permalink)  
Antiguo 14/11/2006, 05:46
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 21 años, 1 mes
Puntos: 51
Si no lanzas un Thread aparte, tu programa principal seria el que se quedaria en un bloque infinito escuhando del puerto de la impresora, por lo que no podrias "interactuar" con el. Si eso es lo deseable, pues no hacen falta más cosas.

Pero lo normal es que el programa principal sea interactivo (poder recibir comandos como "apagate") y por eso hace falta un Thread aparte.

Y añadir solo el EventListener no basta (in meterte en un bucle infinito) ya que si no, cuando el main termina tu programa acaba y se cierra.

PD: He visto ahora tu nuevo mensaje, te respondo más tarde que ahora estoy "mucho liado"
  #10 (permalink)  
Antiguo 15/11/2006, 01:44
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 21 años, 1 mes
Puntos: 51
1.- En este caso, como el Thread se bloquea cuando intenta leer más caracteres, lo habitual es que el bucle que lee vaya metiendo los caracteres en una "cola" y que otro Thread compruebe periodicamente a ver si se ha recibido un comando completo o no. Cuando se ha recibido completo lo procesa y borrar esos caracteres de la cola. Habría que poner unos timeouts etc para que un comando que se quede a mitad no lo haga cascar todo, etc, pero la idea básica sería esa.

2.- Habria que comprobar como te llegan los caracteres (en que codificacion) y si los estas leyendo como toca. Java no tiene, por ejemplo, unsigned int, así que si te los mandaran en ese formato, por ejemplo, tendrías que tener en cuenta que la representacion de lo recibido y lo que muestras sería distinta. Y pintarlos por la consola MS-DOS a veces no ayuda ya que los caracteres no imprimibles los suele pintar desde Java de forma rara.
  #11 (permalink)  
Antiguo 15/11/2006, 10:34
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Bueno finalmente lo solucioné, cuadno pueda posteo el codigo

Programa.java (Archivo principal)
Código:
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.*;
import java.util.*;

public class Programa extends JApplet implements SerialReaderListener 
{	private ArrayList puertos;
	private com controlCom;
	private String PUERTO_SELECCIONADO;
	
	char XON=(char)17;
	char XOFF=(char)19;
	char LF=(char)10;
	char CR=(char)13;

	//GUI
	private JComboBox puertosCombo;
	private JPanel contenido;
	private JButton imprimirBtn;
	private JLabel informacionLbl;
	private JTextArea comandos;
	private JLabel respuestaLbl;
	
	//Constructor
	//Programa()
	public void init()
	{ //Creamos el panel de contenido
		contenido = new JPanel();
		contenido.setLayout(new FlowLayout());
		
		//Creamos el objeto puerto
		controlCom=new com(this);
		puertos=controlCom.listarPuertos();

		buildGUI();
	}
	
	private void buildGUI()
	{	//Añadimos un label
		JLabel caption_1Lbl = new JLabel("Selecciona el puerto:");
		contenido.add(caption_1Lbl);
		
		//Generamos y añadimos el comboBox
		buildCombo();
		imprimirBtn = new JButton("Imprimir etiqueta.");
		imprimirBtn.addActionListener(new pulsaImprimir());
		imprimirBtn.setEnabled(false);
		contenido.add(imprimirBtn);
		
		informacionLbl = new JLabel("", JLabel.RIGHT);
		contenido.add(informacionLbl);
		
		
		//Textarea para las pruebas
		comandos = new JTextArea(3, 10);
		comandos.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
		JButton comandoBtn= new JButton("Ejecutar comando.");
		comandoBtn.addActionListener(new pulsaComando());
		contenido.add(comandos);
		contenido.add(comandoBtn);
		
		respuestaLbl = new JLabel("");
		contenido.add(respuestaLbl);
		
		//Conf window
		setContentPane(contenido);
		//pack();		
		//setTitle("Impresión etiquetas");
		//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300,200);
		//setLocationRelativeTo(null);		//Centrar ventana
	}
	
	
	//Generamos el combo que contiene la lista de puertos serie
	private void buildCombo()
	{	puertosCombo = new JComboBox();
		int tamanyo=puertos.size();
		for(int i=0; i < tamanyo; i++)
		{	puertosCombo.addItem( (String) puertos.get(i) );
		}		
		puertosCombo.setSelectedIndex(-1);
		puertosCombo.addActionListener(new itemStateChange());
		contenido.add(puertosCombo);
	}
	
	
	//Inner class para el listener del JComboBox
	class itemStateChange implements ActionListener
	{	Object comodin;
		public void actionPerformed(ActionEvent e)
		{	PUERTO_SELECCIONADO=(String)puertosCombo.getSelectedItem();
			System.out.println( PUERTO_SELECCIONADO );
			controlCom.cerrarPuerto();
			comodin=controlCom.abrirPuerto(PUERTO_SELECCIONADO);
			String cadena=LF+
			"jF"+LF+
			"US"+LF+
			"eR,2,Q"+LF+
			"Q801,32"+LF+
			"q801"+LF+
			"S2"+LF+
			"D8"+LF+
			"ZB"+LF;
			controlCom.send(cadena);
		
			if(!comodin.equals("1"))
			{	JOptionPane.showMessageDialog(null,"Error:\n"+(String)comodin);
				puertosCombo.setSelectedIndex(-1);
			}
			
		}
	}	
	
	//Imprimir etiqueta
	class pulsaImprimir implements ActionListener
	{	
		public void actionPerformed(ActionEvent e)
		{	imprimirBtn.setEnabled(false);
			String cadena=LF+
			"N"+LF+
			"X0,0,4,60,100"+LF+
			"LO0,50,50,4"+LF+
			"LO40,100,4,100"+LF+
			"A40,100,1,1,1,1,N,\"MADE IN YEAH\""+LF+
			"B50,60,0,1,2,3,96,B,\"S 000001\""+LF+
			"P1"+LF;
		
			controlCom.send(cadena);
			informacionLbl.setText("Imprimiendo...");
		}
	}
	
	class pulsaComando implements ActionListener
	{	char XON=(char)17;
		char XOFF=(char)19;
		char LF=(char)10;
		char CR=(char)13;
		public void actionPerformed(ActionEvent e)
		{	String valor=LF+comandos.getText()+LF;
			controlCom.send(valor);
		}
	}
	
	public static void main(String[] args)
	{	Programa app= new Programa();
		app.setVisible(true);
	}
	
	//Acciones a realizar al llegar datos
	public void newData(byte[] data)
	{	String mensaje=new String(data).trim();
		respuestaLbl.setText(mensaje);	
		[.....]
	}
}

Última edición por clinisbut; 16/11/2006 a las 01:53
  #12 (permalink)  
Antiguo 16/11/2006, 01:54
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
com.java //Clase para la comunicacion con el puerto serie
Código:
import javax.comm.*;
import java.io.*;
import java.util.*;
import javax.swing.*;


public class com
{
	protected Enumeration ports;						//Listado de puertos
	protected CommPortIdentifier port_id;		
	public	SerialPort	puerto;					//Subclase de CommPort
		
	private InputStream inputStream;	//Para el envio de datos al dispositivo.
	private OutputStream outputStream;			//Para la lectura del dispositivo
		
		
	protected String response;					//Ultima linea leida desde el puerto serie
	protected boolean debug = true;			//flag para el controlar la salida debug
		
	private final int TIMEOUT = 30;		//Tiempo de espera maximo para abrir el puerto	
		
	private boolean tapa_abierta=false;	
	private JPanel contenido;
	private Programa app;
		
	//Constructor
	//com(JPanel contenido)
	com(Programa app)
	{	ports=CommPortIdentifier.getPortIdentifiers();
		//this.contenido = contenido;
		this.app = app;
	}
	
	
	//Busca los puertos disponibles en el PC
	public ArrayList listarPuertos()
	{	
		ArrayList<String> nombre_puertos = new ArrayList<String>();
		CommPortIdentifier temp_port;
		while(ports.hasMoreElements())
		{	temp_port=(CommPortIdentifier)ports.nextElement();
			if( CommPortIdentifier.PORT_SERIAL==temp_port.getPortType() )
			{	nombre_puertos.add( (String) temp_port.getName());
			}
		}
		return nombre_puertos;
	}
	
	
	//Abrir puerto
	public Object abrirPuerto(String nombre_puerto)
	{	//Cogemos el identificador del puerto
		try
		{	this.port_id = CommPortIdentifier.getPortIdentifier(nombre_puerto);
		}
		catch(Exception e)
		{	return (String)e.getMessage();
		}
		
		//Intentamos abrir el puerto
		try
		{	puerto = (SerialPort) this.port_id.open("Impresión Etiquetas", TIMEOUT*1000);
		}
		catch(PortInUseException e)
		{	return "Ya hay otra aplicación usando el puerto "+nombre_puerto+".\nEscoge otro.";
		}
		catch(Exception e)
		{	return "Problema abriendo el puerto";
		}
		
		//Configuramos el puerto
		try
		{ puerto.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
		}
		catch(UnsupportedCommOperationException e)
		{}
		
		//Creamos los canales de entrada/salida de datos
		try
		{	//inputStream = puerto.getInputStream();
			outputStream = puerto.getOutputStream();
			//puerto.notifyOnDataAvailable(true);
		}
		catch(IOException e)
		{	return (String) e.getMessage();
		}
		
		//Start the thread that reads the serial comm
		(new SerialReaderThread(app, this.puerto)).start();

		return "1";	//Todo OK
	}
	
	
	public void send(String loQue)
	{
		try
		{	this.outputStream.write(loQue.getBytes());
		}
		catch(IOException e)
		{}
		
		try
		{	Thread.sleep(100);
		}
		catch(Exception e)
		{}
	}
	
	
	//Cerrar puerto
	public void cerrarPuerto()
	{	try
		{	puerto.close();
		}
		catch(Exception e){}
	}

}
  #13 (permalink)  
Antiguo 16/11/2006, 01:55
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
SerialReaderListener.java //Un interface
Código:
import javax.comm.*;

interface SerialReaderListener
{	void newData(byte[] data);
}
SerialReaderThread.java
Código:
import java.io.*;
import javax.comm.*;

public class SerialReaderThread extends Thread
{	
	private SerialReaderListener listener;
	public SerialPort puerto;
	
	//Constructor
	public SerialReaderThread(SerialReaderListener listener, SerialPort puerto)
	{	this.listener = listener;
		this.puerto = puerto;
	}
	
	public void run()
	{	DataInputStream p = null;
		try
		{	p = new DataInputStream(this.puerto.getInputStream());
			int input;
			byte[] b=new byte[20];
			while((input=p.read(b))!=-1)
			{	listener.newData(b);
				b=new byte[20];
			}
		}
		catch(IOException e)
		{
		}
		finally
		{	try
			{	p.close();
				System.out.println("Cierro");
			}
			catch(IOException e)
			{}
		}
	}

}
  #14 (permalink)  
Antiguo 16/11/2006, 03:28
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 21 años, 1 mes
Puntos: 51
Como comentario, decir que los catch "ciegos" que tienes en el código suelen dar problemas a medio/largo plazo, cuando has de depurar algun problema insospechado y no tienes informacion de lo que pasa excepto que "no funciona".

Siempre es bueno hacer algo, aunque sea un minimo printStackTrace() para que si ocurre un error al menos sepas dónde y qué pasó.

Y es bueno ponerlos desde el principio, no sólo por que ayudaran durante la depuración que si no luego te olvidas y pasa lo que pasa.

Unos buenos logs de errores valen su peso en oro.

Última edición por GreenEyed; 16/11/2006 a las 03:48
  #15 (permalink)  
Antiguo 16/11/2006, 03:34
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Aha.. lo tendre en cuenta
  #16 (permalink)  
Antiguo 17/11/2006, 02:28
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Bueno... vuelvo a estar aqui, aunque no se si abrir otro hilo ya q el problema que tengo ahora es diferente al de los eventos...

Ahora que la applicación funciona como applet, cada vez que recargo la pagina donde este se encuentra, el comboBox que contiene la lista de puertos crece, es decir:
Si mi pc tiene dos puertos serie (COM1 y COM2), la primera vez que se carga el applet el comboBox tiene dos elementos (COM1 y COM2).
Si recargo la pagina, aparecen 4 elementos (COM1, COM2, COM1 y COM2).

Debugando en el codigo, he llegado a la conclusion de que quien devuelve ese mayor numero de puertos es la linea que contiene:
Código:
   ports=CommPortIdentifier.getPortIdentifiers();
Al principio pensé que no vaciaba la lista donde guardaba los puertos encontrados en el public void start(), pero ya he mirado y no es eso, la linea que he puesto es la que me devuelve un numero de puertos incorrectos a partir de la primera vez (a cada RELOAD aumenta en 2).
  #17 (permalink)  
Antiguo 17/11/2006, 08:28
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 21 años, 1 mes
Puntos: 51
Parece que es una cuestion de la clase inicializandose solo en un bloque estático y no estando muy preparada para ser llamada de forma sucesiva. Aquí, al final, sugieren una solución:

http://forum.java.sun.com/thread.jsp...sageID=2873814
  #18 (permalink)  
Antiguo 05/12/2006, 02:13
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 11 meses
Puntos: 0
Uis... despues de visitar ese link sigo sin entender cual es exactamente el problema :(
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:23.