Applying Thread Race in an interface (it does not refresh)

1

I quickly explain what I intend, I have two runners running threads simulating running (sum of random value), it is a thread that executes and must for each iteration of the loop in the thread make a setvalue (distance run-time) in progressbar of the interface.

I think my problem is that it does not refresh the jframe and the changes are not seen at 2 progressbar

Corridor Class:

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package carrerahilos_con_interfaz;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Josel
 */
public class Corredor extends Thread {

    private String nombre;
    private int distancia_recorrida;

    public Corredor(String nombre) {
        this.nombre = nombre;
        this.distancia_recorrida = 0;
    }

    @Override
    public void run() {

        while (true) {
            mostrarDistanciaRecorridaActual();
            this.distancia_recorrida += avanzar();
            try {
                sleep(1000);
            } catch (InterruptedException ex) {
                System.out.println("Error Sleep Metho Corredor.run()");
            }

        }

    }

    public int avanzar() {
        int distancia_avanzada = 0;

        distancia_avanzada = (int) Math.floor(Math.random() * (10 - 1 + 1) + 1);  // Valor entre M y N, ambos incluidos.

        return distancia_avanzada;
    }

    public void mostrarDistanciaRecorridaActual() {
        System.out.println("[" + this.nombre + "]Distancia recorrida: " + getDistanciaRecorrida());
    }

    public int getDistanciaRecorrida() {
        return this.distancia_recorrida;
    }

}

Class Interface:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package carrerahilos_con_interfaz;

/**
 *
 * @author Josel
 */
public class interfaz extends javax.swing.JFrame {

    private Corredor c1 = new Corredor("Ernesto");
    private Corredor c2 = new Corredor("Jesus");

    public interfaz() {
        initComponents();
        setVisible(true);
        setLocationRelativeTo(null);


        pb_c1.setMaximum(100);
        pb_c2.setMaximum(100);
        pb_c1.setValue(0);
        pb_c2.setValue(0);
    }

    /**
     * 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 initComponents() {

        jSlider1 = new javax.swing.JSlider();
        jButton1 = new javax.swing.JButton();
        btn_empezarCarrera = new javax.swing.JButton();
        pb_c1 = new javax.swing.JProgressBar();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        pb_c2 = new javax.swing.JProgressBar();

        jButton1.setText("Salir");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        btn_empezarCarrera.setBackground(java.awt.Color.green);
        btn_empezarCarrera.setText("Empezar Carrera");
        btn_empezarCarrera.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_empezarCarreraActionPerformed(evt);
            }
        });

        jLabel1.setText("Corredor 1");

        jLabel2.setText("Corredor 2");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(btn_empezarCarrera, javax.swing.GroupLayout.PREFERRED_SIZE, 149, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE)
                        .addComponent(pb_c1, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(42, 42, 42))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addGap(18, 18, 18)
                        .addComponent(pb_c2, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btn_empezarCarrera, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(40, 40, 40)
                        .addComponent(pb_c1, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(49, 49, 49)
                        .addComponent(jLabel1)))
                .addGap(44, 44, 44)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pb_c2, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(9, 9, 9)
                        .addComponent(jLabel2)))
                .addContainerGap(104, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        
public int avanzar() {
        int distancia_avanzada = 0;

        distancia_avanzada = (int) Math.floor(Math.random() * (10 - 1 + 1) + 1);  // Valor entre M y N, ambos incluidos.

        return distancia_avanzada;
    }
    private void btn_empezarCarreraActionPerformed(java.awt.event.ActionEvent evt) {                                                   

        c1.start();
        c2.start();

        while (true) {            
            //pb_c1.setValue(c1.getDistanciaRecorrida());
            pb_c1.setValue(c1.getDistanciaRecorrida());
            pb_c2.setValue(c2.getDistanciaRecorrida());
           // revalidate(); no funciona
            //repaint(); no funciona
        }

    }                                                  

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(interfaz.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(interfaz.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(interfaz.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(interfaz.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new interfaz().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btn_empezarCarrera;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JSlider jSlider1;
    private javax.swing.JProgressBar pb_c1;
    private javax.swing.JProgressBar pb_c2;
    // End of variables declaration                   
}

Class main:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package carrerahilos_con_interfaz;

/**
 *
 * @author Josel
 */
public class CarreraHilos_con_interfaz {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {


        interfaz i = new interfaz();

    }
}
    
asked by josanangel 04.05.2018 в 22:49
source

1 answer

2

What happens to you is that you block the main thread with this infinite cycle, so the interface is blocked too:

    while (true) {            
        //pb_c1.setValue(c1.getDistanciaRecorrida());
        pb_c1.setValue(c1.getDistanciaRecorrida());
        pb_c2.setValue(c2.getDistanciaRecorrida());
        // revalidate(); no funciona
        //repaint(); no funciona
    }

Instead of doing that, pass the JProgressBar of runner X to its corresponding thread, and update its status (value) within the thread. To achieve this you must make several changes.

1 - Modify the implementation of the class Corredor so that you can pass the JProgreeBar and that the value of this is updated each time the distance traveled is updated.

class Corredor extends Thread {

    private String nombre;
    private int distancia_recorrida;
    private javax.swing.JProgressBar progressBar;// NUEVO

    public Corredor(String nombre, javax.swing.JProgressBar progressBar) {
        this.nombre = nombre;
        this.progressBar = progressBar;// NUEVO. Deberías validar que no sea null
        this.distancia_recorrida = 0;
    }

    @Override
    public void run() {

        while (true) {
            mostrarDistanciaRecorridaActual();
            this.distancia_recorrida += avanzar();
            progressBar.setValue(distancia_recorrida);// NUEVO
            try {
                sleep(1000);
            } catch (InterruptedException ex) {
                System.out.println("Error Sleep Metho Corredor.run()");
            }

        }

    }

    // Resto de métodos omitidos    
}

2 - Change in the class interfaz the mode of instantiating the attributes c1 and c2 , corresponding to the corridors, so that you can pass the JProgressBar already created. You must do this in the class constructor.

class interfaz extends javax.swing.JFrame {

    private Corredor c1;// NUEVO
    private Corredor c2;// NUEVO

    public interfaz() {
        initComponents();
        setVisible(true);
        setLocationRelativeTo(null);

        pb_c1.setMaximum(100);
        pb_c2.setMaximum(100);
        pb_c1.setValue(0);
        pb_c2.setValue(0);

        c1 = new Corredor("Ernesto", pb_c1);// NUEVO
        c2 = new Corredor("Jesus", pb_c2);// NUEVO
    }

    // Resto del código omitido
}

3 - Finally remove the cycle% co_of% infinite, and problematic, from the method code while of class btn_empezarCarreraActionPerformed() .

private void btn_empezarCarreraActionPerformed(java.awt.event.ActionEvent evt) {
    c1.start();
    c2.start();
}
  

Note: Notice that the lines where the comment interfaz appears have been modified or added new.

    
answered by 05.05.2018 в 00:46