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

Hilos con Swing

Estas en el tema de Hilos con Swing en el foro de Java en Foros del Web. Hola, Estoy trabajando con NetBeans y tengo dos clases de hilos hechas, me pidieron que usara Swing, pero solo las tengo hechas para que muestren ...
  #1 (permalink)  
Antiguo 02/01/2012, 12:23
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Hilos con Swing

Hola,
Estoy trabajando con NetBeans y tengo dos clases de hilos hechas, me pidieron que usara Swing, pero solo las tengo hechas para que muestren los resultados por consola.

Se que la pregunta puede ser un tanto básica... pero necesito saber como puedo usar este mismo codigo con swing? (los mensajes ahora van en alertas tipo msgbox)


Código PHP:
threadA.java

package hilos
;

public class 
ThreadA {

    public static 
void main(String[] args){
        
ThreadB b = new ThreadB();
        
System.out.println("Iniciando proceso..");
        
b.start();
        
System.out.println("Proceso iniciado..");

        
synchronized(b){
            try {
                
System.out.println("--> esperando a que B se complete...");
                
b.wait();
                
System.out.println("--> B se ha completado con éxito");
            }
            catch (
InterruptedException ex){
                 
System.out.println(ex);
            }
            
System.out.println("El resultado del calculo en B:" +b.total);
        }
    }

Código PHP:
threadB.java

package hilos
;

class 
ThreadB extends Thread
{
    
long total;

    @
Override
    
public void run(){
        
synchronized(this)
        {
            for(
long i=0i<1000000000;i++)
            
total+=i;
            
System.out.println("----> esperando notificación..");
            
notify();
            
System.out.println("----> notificación realizada..");
        }
    }


Última edición por pcarvajal; 02/01/2012 a las 13:23
  #2 (permalink)  
Antiguo 03/01/2012, 14:26
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Hilos con Swing

Hola,

¿Podrías explicar exactamente que es lo que deseas hacer?

En el código que mostraste existen varios inconvenientes, el primero es que llamas al método wait() en el hilo principal, lo que hace que este se detenga completamente hasta que finalice el segundo hilo. Si el hilo principal espera que finalice el segundo, ¿para que quieres que corra en otro hilo?

Obtienes exactamente el mismo resultado que ejecutar todo en un solo hilo solamente llamando a un método. Si realizaras eso en Swing, toda tu interfaz gráfica se quedaría congelada hasta que termine el segundo hilo, lo mismo que obtienes si lo haces todo en un solo hilo, sin la complejidad de varios hilos y sincronización.

Saludos,
  #3 (permalink)  
Antiguo 03/01/2012, 14:53
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Hola HackmanC
Gracias por responder.

Quería usar ese codigo con swing pero la verdad se me hizo demasiado engorroso hacerlo, asi que comenzé con otro código.

Lo que debo hacer es crear dos hilos independientes (usando swing).
Cada uno de ellos muestra un numero aleatorio en un jtextfield.
Cada uno de ellos tiene los controles "New", "Run", "Wait" y "Stop".

Hasta ahora todo me funciona bien, salvo que cuando hago click en cualquiera de los dos botones "Wait" se me congela el formulario completo (lo que debería hacer es congelar solo el hilo al que corresponde el botón y el otro debería seguir corriendo)
  #4 (permalink)  
Antiguo 03/01/2012, 14:56
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Este es el código que estoy utilizando:

Main.java
Código PHP:
package catedra;

import java.awt.Color;
import javax.swing.JOptionPane;

public class 
Main extends javax.swing.JFrame implements Runnable {

    
/** Creates new form Main */
    
public Main() {
        
initComponents();
        
btnIniciar.setEnabled(false);
        
btnPausa.setEnabled(false);
        
btnDetener.setEnabled(false);
        
btnIniciar2.setEnabled(false);
        
btnPausa2.setEnabled(false);
        
btnDetener2.setEnabled(false);
    }

    
/** 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() {
....
}
    private 
void btnIniciarActionPerformed(java.awt.event.ActionEvent evt) {                                           
      try{
        
Hilo1.iniciarHilo(jTextField1);
        
btnIniciar.setEnabled(false);
        
btnPausa.setEnabled(true);
        
btnDetener.setEnabled(true);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al iniciar el hilo");
      }
    }                                          

    private 
void btnDetenerActionPerformed(java.awt.event.ActionEvent evt) {
      try{
        
Hilo1.detenerHilo(jTextField1);
        
jTextField1.setBackground(Color.LIGHT_GRAY);
        
btnNuevo.setEnabled(true);
        
btnPausa.setEnabled(false);
        
btnDetener.setEnabled(false);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al detener el hilo");
      }
    }

    private 
void btnPausaActionPerformed(java.awt.event.ActionEvent evt) {
      try{
        
Hilo1.pausarHilo(jTextField1);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al pausar el hilo");
      }
    }

    private 
void btnSalirActionPerformed(java.awt.event.ActionEvent evt) {
        
/*
        JOptionPane.showMessageDialog(null, "DISEÑADO POR :\n\n"
        + "ELMER JOSE DIAZ LASSO\n\n"
        + "ESTUDIANTE 5° TS UNIAJC\n\n"
        + "SANTIAGO DE CALI\n\n"
        + "VALLE");     
         */
        //JOptionPane.showMessageDialog(null,Hilo1..interrupted());
        
Hilo1.detenerHilo(jTextField1);
        
Hilo2.detenerHilo(jTextField2);
        
System.exit(0);
    }

    private 
void btnNuevoActionPerformed(java.awt.event.ActionEvent evt) {
      try{  
        
btnNuevo.setEnabled(false);
        
jTextField1.setBackground(Color.white);
        
jTextField1.setText("0");
        
btnIniciar.setEnabled(true);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al crear el hilo");
      }
    }

    
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
private void btnNuevo2ActionPerformed(java.awt.event.ActionEvent evt) {
      try{  
        
btnNuevo2.setEnabled(false);
        
jTextField2.setBackground(Color.white);
        
jTextField2.setText("0");
        
btnIniciar2.setEnabled(true);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al crear el hilo");
      }
    }

    private 
void btnIniciar2ActionPerformed(java.awt.event.ActionEvent evt) {
      try{
        
Hilo2.iniciarHilo(jTextField2);
        
btnIniciar2.setEnabled(false);
        
btnPausa2.setEnabled(true);
        
btnDetener2.setEnabled(true);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al iniciar el hilo");
      }
    }

    private 
void btnPausa2ActionPerformed(java.awt.event.ActionEvent evt) {
      try{
        
Hilo2.pausarHilo2(jTextField2);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al pausar el hilo");
      }
    }

    private 
void btnDetener2ActionPerformed(java.awt.event.ActionEvent evt) {
      try{
        
Hilo2.detenerHilo(jTextField2);
        
jTextField2.setBackground(Color.LIGHT_GRAY);
        
btnNuevo2.setEnabled(true);
        
btnPausa2.setEnabled(false);
        
btnDetener2.setEnabled(false);
      }
      catch (
Exception e){
        
JOptionPane.showMessageDialog(null,"Se produjo un error al detener el hilo");
      }
    }

    
/**
    * @param args the command line arguments
    */
    
public static void main(String args[]) {
        
java.awt.EventQueue.invokeLater(new Runnable() {
            public 
void run() {
                new 
Main().setVisible(true);
                
            }
        });
    }

    
// Variables declaration - do not modify
    
private javax.swing.JButton btnDetener;
    private 
javax.swing.JButton btnDetener2;
    private 
javax.swing.JButton btnIniciar;
    private 
javax.swing.JButton btnIniciar2;
    private 
javax.swing.JButton btnNuevo;
    private 
javax.swing.JButton btnNuevo2;
    private 
javax.swing.JButton btnPausa;
    private 
javax.swing.JButton btnPausa2;
    private 
javax.swing.JButton btnSalir;
    private 
javax.swing.JPanel jPanel1;
    private 
javax.swing.JTextField jTextField1;
    private 
javax.swing.JTextField jTextField2;
    
// End of variables declaration

    
public void run() {
        throw new 
UnsupportedOperationException("Not supported yet.");
    }


  #5 (permalink)  
Antiguo 03/01/2012, 14:57
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Hilo1.java
Código PHP:
package catedra;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextField;

public class 
Hilo1 extends Thread{

    static  
Thread hilo1;
    static  
JTextField num;
    
Random rnd = new Random();
    
    public 
Hilo1(){
       
hilo1=new Thread();
    }
    
    @
Override
    
public void run(){
        while (
true) {
            for (
int i 010i++) {
                
//num.setText(Integer.toString(i));
                
num.setText(Integer.toString( (int) (Math.random ()* 100000000) ));
                
                try {
                    
Thread.sleep(500);
                } catch (
InterruptedException ex) {
                    
Logger.getLogger(Hilo1.class.getName()).log(Level.SEVEREnullex);
                }
            }
        }
    }

    public static  
void iniciarHilo(JTextField num){        
        
hilo1=new Hilo1();
        
hilo1.start();
        
Hilo1.num=num;        
    }
    
    public static  
void detenerHilo(JTextField num){
            
hilo1.stop();
    }
    
    public static  
void pausarHilo(JTextField numthrows InterruptedException{
        try {
            
Thread.sleep(10000); //tiempo en milisegundos.
        
} catch (Exception e) {
            
e.printStackTrace();
        }
    }


  #6 (permalink)  
Antiguo 03/01/2012, 14:57
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Hilo2.java
Código PHP:
package catedra;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextField;

public class 
Hilo2 extends Thread{

    static  
Thread hilo2;
    static  
JTextField num;
    
Random rnd = new Random();
    
    public 
Hilo2(){
       
hilo2=new Thread();
    }
    
    @
Override
    
public void run(){
        while (
true) {
            for (
int i 010i++) {
                
//num.setText(Integer.toString(i));
                
num.setText(Integer.toString( (int) (Math.random ()* 100000000) ));
                
//num.setForeground(Color.red);
                
                
try {
                    
hilo2.sleep(500);
                } catch (
InterruptedException ex) {
                    
Logger.getLogger(Hilo2.class.getName()).log(Level.SEVEREnullex);
                }
            }
        }
    }

    public static  
void iniciarHilo(JTextField num){        
        
hilo2=new Hilo2();
        
hilo2.start();
        
Hilo2.num=num;        
    }
    
    public static  
void detenerHilo(JTextField num){
            
hilo2.stop();
    }
    
    public static  
void pausarHilo2(JTextField num){
  
        try {
            
Thread.sleep(10000); //tiempo en milisegundos.
        
} catch (Exception e) {
            
e.printStackTrace();
        }
    }


Agradezco de antemano tu ayuda.
Saludos
  #7 (permalink)  
Antiguo 03/01/2012, 19:54
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Hilos con Swing

Hola,

Cita:
Iniciado por pcarvajal Ver Mensaje
...
Lo que debo hacer es crear dos hilos independientes (usando swing).
Cada uno de ellos muestra un numero aleatorio en un jtextfield.
Cada uno de ellos tiene los controles "New", "Run", "Wait" y "Stop".
...
La documentación de Swing explicitamente menciona que no está diseñado para multithreading, osea que no puedes usar Swing directamente desde varios hilos.

Las operaciones de new, run, wait y stop las tienes que implementar de forma diferente puesto los metodos stop(), suspend() y resume() de la clase Thread estan 'deprecated' y hay varios motivos por los cuales no se deben utilizar.

Tu aplicación hace exactamente lo contrario.

Cita:
Iniciado por pcarvajal Ver Mensaje
...
Hasta ahora todo me funciona bien, salvo que cuando hago click en cualquiera de los dos botones "Wait" se me congela el formulario completo (lo que debería hacer es congelar solo el hilo al que corresponde el botón y el otro debería seguir corriendo) ...
Algunas veces las aplicaciones no dan problema en situaciones muy específicas aún cuando se use Swing desde varios hilos o se usen métodos que están 'deprecated', pero no significa que se deba hacer en aplicaciones críticas donde seguramente van a dar problemas.

No podría darte una sugerencia sin cambiar todo lo descrito anteriormente puesto que seguramente va a seguir dando problemas de un u otra forma. Pero busca información sobre lo siguente:
  • swing multithreading
  • thread stop resume suspend
  • java atomic synchronization
  • java concurrency collection

Saludos,
  #8 (permalink)  
Antiguo 03/01/2012, 20:40
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Comprendo, gracias por tomarte el tiempo de explicarme todo lo referente a hilos.

A que te refieres con lo siguiente?
Cita:
Tu aplicación hace exactamente lo contrario.
Y disculpa que te lo pregunte, pero las clases que construí no se comportan entonces como un hilo??
  #9 (permalink)  
Antiguo 03/01/2012, 20:55
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Hilos con Swing

Hola,

Me refiero a que el programa hace dos cosas no adecuadas, llama a un método de un JTextField (setText) directamente desde dos hilos diferentes al hilo principal de Swing y usas el método stop() que está deprecated y no es aconsejable usarlo.

Tus clases sí se comportan como hilos adecuadamente, pero tendrías que corregir las dos cosas que mencioné anteriormente para que definitivamente ya no den problemas.

Para corregir el uso de stop() (detener un hilo) hay otras alternativas, para que dos hilos usen un mismo componente Swing también hay otras alternativas, todo depende del método que prefieras usar y las necesidades específicas de tu programa.

Saludos,
  #10 (permalink)  
Antiguo 03/01/2012, 21:07
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

sabes? esto me sonó a que me hablaste en chino :S
la verdad no logré entender bien lo que me dijiste.

Cita:
llama a un método de un JTextField (setText) directamente desde dos hilos diferentes al hilo principal de Swing
que alternativa tengo entonces para hacer esto?
  #11 (permalink)  
Antiguo 03/01/2012, 21:29
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Hilos con Swing

Hola,

Cita:
Iniciado por pcarvajal Ver Mensaje
sabes? esto me sonó a que me hablaste en chino :S
la verdad no logré entender bien lo que me dijiste. ...

Je, je ... tienes toda la razón ... voy a intentar explicar mas detalladamente.

Cita:
Iniciado por pcarvajal Ver Mensaje
... que alternativa tengo entonces para hacer esto?
¿Que es lo que sucede?

Necesitas una aplicación que use dos hilos independientes al hilo principal de Swing para poner unos valores en un JTextField. Al hilo principal se le llama Event Dispatch Thread, es un hilo único donde se inicia la aplicación de Swing y solo el código que corre en ese hilo puede hacer uso de las funciones de Swing, dicho propiamente solamente ese hilo puede usar Swing.

¿Entonces no se puede usar?

Como Swing no es multithreading no puede ser usado desde otro hilo que no sea el Event Dispatch Thread, por lo que los diseñadores de Java crearon algunas herramientas para facilitar este procedimiento, como los Timers, o los SwingWorkers; con el inconveniente que solo se pueden usar para ejecutar procesos cortos.

Existe varios métodos para que se comuniquen dos hilos, uno de ellos es crear una clase que sea atómica, es decir que esté sincronizada para que dos hilos no puedan leer y escribir en la misma al mismo tiempo, uno de los hilos escribe en esa clase y ella guarda el valor. Otro hilo solamente lee de esa clase, así que un hilo guarda un valor en ese objeto y el otro hilo recupera el valor de ese objeto. Por último esa clase notifica con un evento (Listener) al que lee para que realice una actividad, como poner el valor leído en un JTextField.

¿Es el único método?

Existen muchas formas de hacer ese procedimiento, buscando por la red puedes encontrar varios ejemplos sobre 'swing multithreading', el anterior creo no es muy usado aunque es el que yo prefiero porque es difícil de implementar aunque mucho mas eficiente. Inclusive hay métodos que se comunican por programas externos como queues y sockets.

Saludos,

ps:

Si deseas puedo escribir un pequeño programa para demostrar el concepto, pero si realmente estas interesado que últimamente he estado algo ocupado. Aunque acá puedes encontrar un método simple pero diferente a lo que mencionaba : http://www.javaranch.com/journal/200...threading.html

Última edición por HackmanC; 03/01/2012 a las 21:41 Razón: link
  #12 (permalink)  
Antiguo 03/01/2012, 21:46
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Creeme que te agradeceria enormemente si pudieras crear un pequeño programa (lo mas simple posible, a prueba de "pcarvajales") como para poder entender el concepto y asi poder aplicarlo en la aplicaciòn que estoy haciendo (y que dicho sea de paso, es un trabajo con nota, pero que en ningun caso va a ser aplicado en la realidad)
  #13 (permalink)  
Antiguo 04/01/2012, 00:50
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Hilos con Swing

Hola,

Cita:
Iniciado por pcarvajal Ver Mensaje
... lo mas simple posible ...
Eso está realmente difícil, el tema de los hilos es uno de los mas complicados en cualquier lenguaje, si quieres un ejemplo fácil para resolver el problema de Swing multithreading prueba con el vínculo que te mostré donde solamente utilizan el método invokeAndWait.

JavaDesigns-SwingMultithreading
Código Java:
Ver original
  1. javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
  2.                 public void run() {
  3.                     label.setText("" + getPi());
  4.                 }
  5.             });

Yo prefiero utilizar un método diferente, como por ejemplo:

Código Java:
Ver original
  1. package org;
  2.  
  3. import java.awt.Graphics;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.util.concurrent.ThreadLocalRandom;
  7. import java.util.concurrent.atomic.AtomicBoolean;
  8. import java.util.concurrent.atomic.AtomicInteger;
  9. import javax.swing.JButton;
  10. import javax.swing.JFrame;
  11. import javax.swing.JTextField;
  12.  
  13. public class JApp extends JFrame {
  14.  
  15.     private JTextField jTextField1, jTextField2;
  16.     private Threads Thread1, Thread2;
  17.  
  18.     public JApp() {
  19.         initComponents();
  20.     }
  21.  
  22.     private void initComponents() {
  23.         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  24.         getContentPane().setLayout(new java.awt.FlowLayout());
  25.         jTextField1 = new javax.swing.JTextField("1000");
  26.         jTextField2 = new javax.swing.JTextField("1000");
  27.         getContentPane().add(jTextField1);
  28.         getContentPane().add(jTextField2);
  29.  
  30.         JButton button = new JButton("Pausa");
  31.         button.addActionListener(new ActionListener() {
  32.             @Override
  33.             public void actionPerformed(ActionEvent e) {
  34.                 if (Thread1.isPaused()) {
  35.                     Thread1.resume();
  36.                 } else {
  37.                     Thread1.pause();
  38.                 }
  39.             }
  40.         });
  41.         getContentPane().add(button);
  42.  
  43.         pack();
  44.  
  45.         Thread1 = new Threads(this);
  46.         Thread2 = new Threads(this);
  47.         new Thread(Thread1).start();
  48.         new Thread(Thread2).start();
  49.     }
  50.  
  51.     @Override
  52.     public void paint(Graphics g) {
  53.         super.paint(g);
  54.         jTextField1.setText(String.valueOf(Thread1.get()));
  55.         jTextField2.setText(String.valueOf(Thread2.get()));
  56.     }
  57.  
  58.     @Override
  59.     public void dispose() {
  60.         Thread1.stop();
  61.         Thread2.stop();
  62.         super.dispose();
  63.     }
  64.  
  65.     public static void main(String args[]) {
  66.         java.awt.EventQueue.invokeLater(new Runnable() {
  67.             @Override
  68.             public void run() {
  69.                 new JApp().setVisible(true);
  70.             }
  71.         });
  72.     }
  73.  
  74.     private class Threads implements Runnable {
  75.         private AtomicBoolean running = new AtomicBoolean(true);
  76.         private AtomicInteger value = new AtomicInteger(0);
  77.         private AtomicBoolean pause = new AtomicBoolean(false);
  78.         private JFrame frame;
  79.         public Threads(JFrame frame) {
  80.             this.frame = frame;
  81.         }
  82.         @Override
  83.         public void run() {
  84.             try {
  85.                 while (running.get()) {
  86.                     if (pause.get()) {
  87.                         synchronized(this) {
  88.                             wait();
  89.                         }
  90.                     }
  91.                     value.set((int)(ThreadLocalRandom.current().nextInt(1000)));
  92.                     frame.repaint();
  93.                     Thread.sleep(1000);
  94.                 }
  95.             } catch (InterruptedException ex) {
  96.                 System.err.println(ex);
  97.             }
  98.         }
  99.         public void stop() {
  100.             running.set(false);
  101.             if (isPaused()) resume();
  102.         }
  103.         public void pause() {
  104.             pause.set(true);
  105.         }
  106.         public boolean isPaused() {
  107.             return pause.get();
  108.         }
  109.         public void resume() {
  110.             pause.set(false);
  111.             synchronized(this) {
  112.                 notify();
  113.             }
  114.         }
  115.         public Integer get() {
  116.             return value.get();
  117.         }
  118.     }
  119.  
  120. }

Pero es mucho más complicado de entender, cuando realizo una aplicación siempre pienso en que en un momento dado pueda ser que la tenga que mejorar, por ejemplo en esta aplicación no solo podrías mostrar un número sino enviar toda una estructura de datos de un hilo a otro, por supuesto con pequeñas modificaciones.

Saludos,
  #14 (permalink)  
Antiguo 04/01/2012, 12:18
Avatar de pcarvajal  
Fecha de Ingreso: enero-2002
Mensajes: 701
Antigüedad: 22 años, 10 meses
Puntos: 8
Respuesta: Hilos con Swing

Muchas gracias por el ejemplo.

Lo modifiqué un poco para que se ajustara a lo que necesito hacer, pero tengo solo un par de inconvenientes:

1. Necesito que no se inicie automaticamente, sino que se inicie en forma individual. Le agruegué dos botones para esto, pero no supe como hacerlo para hecharlos a andar individualmente.

2. Como puedo hacer para que los numeros del jtexfield1 se vayan desplegando en distintos colores?
(osea, el primero verde, el segundo azul y asi sucesivamente)

3. Como puedo darle la ubicacion y posicion en el formulario a los jtextfield y a los botones? Intenté darle ancho y alto al formulario, a los campo de texto y a los botones en el initComponents con la propiedad setBounds pero no se me reflejaban los cambios al compilar.

Este es el codigo:

Código:
package org;
 
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
 
public class JApp extends JFrame {
 
    private JTextField jTextField1, jTextField2;
    private Threads Thread1, Thread2;
    int aleatorio = 0;
    
    public JApp() {
        initComponents();
    }
 
    private void initComponents() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.FlowLayout());
        jTextField1 = new javax.swing.JTextField("1000");
        jTextField2 = new javax.swing.JTextField("1000");
        getContentPane().add(jTextField1);
        getContentPane().add(jTextField2);
        jTextField1.setEditable(false);
        jTextField2.setEditable(false);

  

        
        JButton button = new JButton("Pausa 1");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (Thread1.isPaused()) {
                    Thread1.resume();
                } else {
                    Thread1.pause();
                }
            }
        });
        getContentPane().add(button);
 
        JButton button2 = new JButton("Pausa 2");
        button2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (Thread2.isPaused2()) {
                    Thread2.resume();
                } else {
                    Thread2.pause();
                }
            }
        });
        getContentPane().add(button2);
  
        JButton button3 = new JButton("Iniciar 1");
        button3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //realizar pregunta para saber si hilo1 esta corriendo, si no está corriendo, darle start
            }
        });
        getContentPane().add(button3);
        
        JButton button4 = new JButton("Iniciar 2");
        button4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //realizar pregunta para saber si hilo2 esta corriendo, si no está corriendo, darle start
            }
        });
        getContentPane().add(button4);
        
        
        JButton button5 = new JButton("Parar 1");
        button5.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Thread1.stop();
            }
        });
        getContentPane().add(button5);  
     
         JButton button6 = new JButton("Parar 2");
        button6.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                 Thread2.stop();
            }
        });
        getContentPane().add(button6);  
        
        
        pack();
 
       Thread1 = new Threads(this);
       Thread2 = new Threads(this);
       new Thread(Thread1).start();
       new Thread(Thread2).start();
    }
 
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        jTextField1.setText(String.valueOf(Thread1.get()));
        jTextField2.setText(String.valueOf(Thread2.get()));
    }
 
    @Override
    public void dispose() {
        Thread1.stop();
        Thread2.stop();
        super.dispose();
    }
 
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JApp().setVisible(true);
            }
        });
    }
 
    private class Threads implements Runnable {
        private AtomicBoolean running = new AtomicBoolean(true);
        private AtomicInteger value = new AtomicInteger(0);
        private AtomicBoolean pause = new AtomicBoolean(false);
        private JFrame frame;
        public Threads(JFrame frame) {
            this.frame = frame;
        }
        @Override
        public void run() {
            try {
                while (running.get()) {
                    if (pause.get()) {
                        synchronized(this) {
                            wait();
                        }
                    }
                    aleatorio = (int) (Math.random ()* 10000);
                    value.set(aleatorio);
                    frame.repaint();
                    Thread.sleep(1000);
                }
            } catch (InterruptedException ex) {
                System.err.println(ex);
            }
        }
        
         public void start() {
            new Thread(Thread1).start();
        }
      
        public void stop() {
            running.set(false);
            if (isPaused()) resume();
        }
        public void pause() {
            pause.set(true);
        }
        public boolean isPaused() {
            return pause.get();
        }
        public void resume() {
            pause.set(false);
            synchronized(this) {
                notify();
            }
        }
        public Integer get() {
            return value.get();
        }
        ///////////////////////////////////////////////////////////
        public void pause2() {
            pause.set(true);
        }
        public boolean isPaused2() {
            return pause.get();
        }        
        
        public void stop2() {
            running.set(false);
            if (isPaused2()) resume2();
        }
        public void resume2() {
            pause.set(false);
            synchronized(this) {
                notify();
            }
        }
    }
 
}
  #15 (permalink)  
Antiguo 04/01/2012, 14:20
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: Hilos con Swing

Hola,

Cita:
Iniciado por pcarvajal Ver Mensaje
... 1. Necesito que no se inicie automaticamente, sino que se inicie en forma individual. Le agruegué dos botones para esto, pero no supe como hacerlo para hecharlos a andar individualmente. ...
Posiblemente, usa el Thread1.stop() para detener el hilo completamente, después crea un nuevo objeto Thread1 = new Threads(elJFrame).

Cita:
Iniciado por pcarvajal Ver Mensaje
... 2. Como puedo hacer para que los numeros del jtexfield1 se vayan desplegando en distintos colores?
(osea, el primero verde, el segundo azul y asi sucesivamente) ...
Revisa la clase java.awt.Color, seguramente tiene métodos para usar colores RGB y generarlos aleatoriamente, o puedes hacer una lista en un array y llevar un índice en un contador, cada vez que se llame al método paint le cambias el color al TextField.

Cita:
Iniciado por pcarvajal Ver Mensaje
... 3. Como puedo darle la ubicacion y posicion en el formulario a los jtextfield y a los botones? Intenté darle ancho y alto al formulario, a los campo de texto y a los botones en el initComponents con la propiedad setBounds pero no se me reflejaban los cambios al compilar. ...
Yo use un FlowLayout, los componentes se van agregando uno tras otro y no se les puede cambiar la posición, solamente el tamaño con setSize, setMaxSize y setMinSize. Para ordenar los componentes en un formulario puedes usar otros Layout que si lo permitan, o no usar Layout y colocarlos manualmente con setBounds.


La idea de mostrarte un ejemplo es para que tengas una base donde investigar y comprender bien los conceptos que lo hacen funcionar. De allí en adelante es tu decisión analizarlo e investigar cada punto, o consultar en el foro cada duda específica que tengas sobre alguna parte del código que no comprendas.

Saludos,
  #16 (permalink)  
Antiguo 31/01/2012, 21:49
 
Fecha de Ingreso: mayo-2007
Ubicación: Tijuana
Mensajes: 26
Antigüedad: 17 años, 6 meses
Puntos: 0
Respuesta: Hilos con Swing

Hola buenas tardes, estoy pidiendo ayuda ya que ando perdido en esto de hilos. solo se que son procesos disparados desde un programa padre y se ejecutan independientes a programa padre, es por eso que me enfoque a este tema.

Necesito hacer un programa que busque ciclicamente dentro de una tabla, valores numericos y dependiendo de este numero, es el procedimiento a llamar de un jar externo.

El problema que veo es que la llamada a ejecucion del procedimiento, no debe hacer que mi programa se espere a tener la respuesta ( pienso yo que por medio de un hilo ), si no que continue buscando valores numericos dentro de la tabla para ejecutar otros procedimientos.

Y tambien saber cuales ejecuciones de procedimientos se tardaron mas de X minutos, y estas poder forzarlas a terminarse.

Etiquetas: clase, hilos, netbeans, string, swing
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:21.