I can’t update jFrame from a Java thread

Asked

Viewed 472 times

1

I have a code that reads the Serial Port through a thread, but when I try to update a label I can’t. I implemented a Serialread Runnable class, and in this class I run a loop to read the serial port. So far so good, I can read the serial port and print it on the console. More when I try to update the jLtempoatual Label, nothing happens in the graphical interface. I have already tested if it is running in EDT and running everything in EDT. However jLtempoatual is not updating at runtime in jFrame.

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.awt.EventQueue;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 *
 * @author bruno
 */
public class Controle extends javax.swing.JFrame {

    /**
     * Creates new form Controle
     */
    public Controle() {

        initComponents();


    }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          


    private void jLtempatualMouseMoved(java.awt.event.MouseEvent evt) {                                       

    }                                      

       public void Transporte(final String comando) {  


jLtempatual.setText(comando);

    } 




     public  void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); // portName é o nome da porta que vai ser aberta para comunicação
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.out.println("Error: Porta está atualmente em uso");
        }
        else
        {
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);

            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE); //Parametros de comunicação, o primeiro numero é a velocidade de comunicação.

                InputStream in = serialPort.getInputStream();
                //OutputStream out = serialPort.getOutputStream();


                  Thread Leitura = new Thread(new SerialReader(in), "Leitura thread");  
        Leitura.setDaemon(true);  
        Leitura.start(); 


               // (new Thread(new SerialWriter(out))).start();

            }
            else
            {
                System.out.println("Error: Somente as portas seriais são suportadas.");
            }
        }     
    }

public class  SerialReader implements Runnable 
    {
        InputStream in;
        String teste;
        public  SerialReader ( InputStream in )
        {
            this.in = in;
        }


        //EventQueue.invokeLater(new Runnable() {
        public void run ()
        {

            byte[] buffer = new byte[1024];
            int len = -1;

            try
            {
                while ( ( len = this.in.read(buffer)) > -1 ) //Ler a serial e coloca na variavel buffer
                {
                    teste=new String(buffer,0,len);
                    EventQueue.invokeLater(new Runnable() {  
                        public void run() {  
                    System.out.print(teste); //Imprime o resulatado no console


                    jLtempatual.setText(teste);

           jTprompt.append(teste);
               Transporte(teste);
                        }

                    });


                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            

    }
    }
    private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {                                         
  String nome="";

  nome=jButton5.getText();
  if(nome.equals("FAN OFF")) {
      jButton5.setText("FAN ON");
        } else {
      jButton5.setText("FAN OFF");

    }                                        

    }

      public static class SerialWriter implements Runnable 
    {
        OutputStream out;

        public SerialWriter ( OutputStream out )
        {
            this.out = out;
        }

        public void run ()
        {
            try
            {                
                int c = 0;
                while ( ( c = System.in.read()) > -1 )
                {
                    this.out.write(c); //Envia 0 pela serial??
                }                
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }
      public static void main ( String[] args )
    {
         EventQueue.invokeLater(new Runnable() {  
                        public void run() {
        try
        {

            (new Controle()).connect("/dev/ttyUSB1"); //Passa o nome da porta como parametro para classe connect
                  final Controle frame = new Controle();   
frame.setVisible(true); 
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
                        }});
    }

    /**
     * @param args the command line arguments
     */



}
  • What’s the problem? What’s wrong? Click [Edit] and add more details to your question

  • The question seems clear to me, but its code is not. There are several problems, especially of Javabeans conventions. It seems to me that you are/were developer C#. In Java, class names start with uppercase letters, variable names, and methods with minuscule letters and camelCase. Your method Transporte looks more like class name. Going back to your code, we don’t see what’s going on with the initComponents, It may be that the read thread happens faster than the screen is able to draw the components. And in your initComponents he overwrites what’s on his Jlabel

  • Hi Gabriel, thanks for answering. Use Thread.Sleep(1000); in my thread to take a little time. What is your suggestion?

  • 1

    Thank you all! I discovered the stupid mistake, I was in trouble because I called the conect method before the jframe. I made the correction and now the code works as expected.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.