style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

ayuda hilo q controla frame

Que tal amigos, estoy desarrollando una aplicación en java, esta aplicación se conecta a un servidor mysql en la red para realizar algunas operaciones, el problema que tengo es el siguiente:

realize un hilo q contiene la llamada al frame, pero si ejecuto el frame 2 veces kiero que por medio de otro hilo se muestre un frame de espera, o en su defecto solo encole la petición de ejecución,
no lo logro, siempre que ejecuto el frame se interrumpe la tarea que ya estaba ejecutando es como si el frame se inicializara por completo aun que sea ejecutado en otra pc, la finalidad es que por medio de un ejecutable .jar los usuarios puedan hacer consultas en el servidor mysql.

he probado con el metodo de la interface runnable invokeAndWait pero aun así no espera a q acabe la accion q es generada por un boton.

un poko de codigo del invoke wait q hago:

 public static void main(String args[]) {
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {

                public void run() {
                    new NewJFrame1().setVisible(true);
                }
            });
        } catch (InterruptedException ex) {
            Logger.getLogger(NewJFrame1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(NewJFrame1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

hasta aki solo abro el frame, despues un boton ejecuta un evento donde hago el proceso largo q tengo q realizar.

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
         
         Tarea();
         tarea2();
         new frameresultados1().setVisible(true);
         new frameresultados2().setVisible(true);
     
    }

Tarea contiene todas las sentencias sql a ejecutar.

entonces qusiera q si el frame ya ha sido llamado aparesca otro frame de espera hasta q se acaben de ejecutar los procesos que realizo con el botón.

espero alguien me pueda ayudar, he probado con algunos joins y con swingbackground por lo q creo q ya confundí algunos conceptos y tal vez alguien tenga una solución mas fácil

Gracias por su atención.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Es decir que quieres mostrar

Es decir que quieres mostrar un solo frame?

Si es así, ¡no crees el objeto dos veces!

Cuando llamas:  new frameresultados1() ( ¿por que diablos le ponen minúsculas a las clases? ) estas creando dos objetos. Ellos no tienen ni la culpa ( ni la responsabilidad ) de que tu intención sea tener solo uno..

Sobre lo de la tarea que se interrumpe y todo eso no te entendí nada y cada vez que releo tu post me desespero un poco más así que ahí te va un ejemplo de lo que yo creo que estás intentando:

1.- Ejecutar una tarea en el servidor
2.- Mientras esa tarea se ejecute ignorar las nuevas peticiones
3- Cuando la tarea termine, permitir nuevas tareas.

Si es esto lo que quieres, tienes que empezar por sacar la lógica de la tarea de la interfaz gráfica donde no pertenece.

Swing es finalmente single thread, todo su ejecución de pintado se realiza a través de un solo hilo que se llama EDT ( event dispatcher thread ) así que es relavitamente sencillo y seguro setear variables para control del flujo por que solo un thread las accede ( el EDT precisamente ).

Luego lo que tienes que hacer es ...

Creo que se entenderá mejor con código.

Aquí va un ejemplo.

  • Imagina que tienes una pantalla donde escribes un query.
  • Cuando oprimes el botón "ejecutar" el query se ejecuta contra el servidor.
  • En ese intermedio ninguna otra ejecución es aceptada.
  • Al terminar la ejecución se pueden aceptar nuevas tareas.
  • El código de ejemplo sería el siguiente ( nota: este es solo un ejemplo y no necesariamente un modelo a seguir, en especial el comando y su control deberían de ser diferentes )

    package busy;

    import static java.lang.System.out;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    /**
     * Ejemplo de ejecutar una tarea a la vez.
     */

    class Busy {
            private final JLabel output;
            private final Command command;

            public Busy() {
                    command = new Command( this );
                    output  = new JLabel("<html><h1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+
                                                  "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+
                                                  "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</h1></html>");

            }
            public void runMain() {
                    JLabel input = new JLabel("<html><h1>SELECT * FROM users WHERE clue > 0;</h1></html>");
                    JButton button = new JButton("Execute");
                    button.addActionListener( new ActionListener(){
                            public void actionPerformed( ActionEvent e ) {
                                    execute();
                            }
                    });

                    JFrame frame = new JFrame();
                    frame.add( input, BorderLayout.NORTH );
                    frame.add( output );
                    frame.add( button , BorderLayout.SOUTH );
                    frame.pack();
                    frame.setVisible( true );
                   
            }
            /**  
             * Ejecuta el comando.
             * Es responsabilidad del comando ejecutarse en un Thread separado
             * y no aceptar más que un trabajo a la vez y no de la interfaz grafica.
             */

            private void execute() {
                    output.setText("<html><h1><i>executing...</i></h1></html>");
                    command.run();
            }
            /**
             * Este metodo es llamado por el comando, cuando el trabajo está terminado.
             */

            public void done() {
                    output.setText( command.result() );
            }
            public static void main( String ... args ) {
                    Busy b = new Busy();
                    b.runMain();
            }
    }
    /**
     * Simula que trabaja en algo en un thread separado.
     * El control lo lleva con una variable de instancia.
     * Como es llamada desde swing  a través del EDT, se
     * ejecuta en un modelo de single thread, por lo que
     * no hace falta sincronizar  el acceso a esta variable
     */

    class Command {

            /** Usado para saber donde hay que notificar que ya terminó */
            private final Busy callback;

            // artificio para simular trabajo
            private final Random random = new Random();

            /** Usada para saber si hay algo corriendo o no */
            private boolean running;

            public Command( Busy callback ) {
                    this.callback = callback;
            }
            /** Regresa el resultado de la operación.
              * Actualiza la fecha de ejecución.
                    */

            public String result() {
                    return String.format("<html><h1>0 rows returned. Time  %tT</h1></html>", new Date() );
            }

            /**
             * Simula trabajo. Crea un nuevo thread
             * y lo duerme por n segundos.
             * n es un valor aleatorio entre 0 y 10
             */

            public void run() {
           
                    new Thread( new Runnable() {
                            public void run() {
                                    // Si ya está corriendo, regresa ... y no hagas nada
                                    if( running ) {
                                            out.println("Ignorando. Estoy trabajando");
                                            return;
                                    }
                                    // Si no estaba corriendo poner la bandera de correr a true
                                    running = true;
                                    // simula carga
                                    int n = random.nextInt( 10 );
                                    out.printf("Working for the next %s seconds %n", n );
                                    try {
                                            Thread.sleep( n * 1000 );
                                    } catch( InterruptedException e ) {
                                    }
                                    out.println("Done");
                                    // regresa la bandera a false
                                    running = false;

                                    // Y dile al principal que ya terminaste
                                    SwingUtilities.invokeLater( new Runnable() {
                                            public void run() {
                                                    callback.done();
                                            }
                                    });
                            }
                    }).start();
            }
    }

    Si das click varias veces en el boton, la tarea te ignorará por que ya está trabajando en algo.

    Resultado:

    Como ves, sacando la lógica de la interfaz gráfica puedes simplificar el control.

    Espero que esto te sirva y te diviertas entendiendole a mi código tanto como yo me divertí haciendolo.

    Buenas noches

Gracias !!!!

ahora mismo comenzare a hacer pruebas, y gracias por descifrar mi explicacion, y ya t cuento como me va.

Funciona correctamente.

Perfecto he probado tu codigo y esta muy bien y con la definicion de los hilos q aportaste pude encapsular bien declaracion e inicio de variables, asi se soluciono mi problema.

Y fue muy interesante comprender y analizar tu código.

Muchas gracias!!!!

Que bueno!

¡¡Que bueno!!, No me desvelé en vano ( me entró un frenesí por terminar ese ejemplo ) :) :) :)

Solo hay que tener cuidado con el uso "al descubierto" de las variables cuando se trata de una aplicación con hilos.

Aquí funcionó ( como te digo ) por que la variable de modifica "fuera" de el nuevo hilo donde sigue siendo el EDT el que rige.

Hay también una clase que se llama "SwingWorker" que ayuda a hacer el "callback" te recomiendo que le heches un ojo.

Finalmente, desde Java 1.5 se introdujo una biblioteca para el manejo de threads, también vale la pena revisarla para ver si puedes encolar trabajos con ella.

Imagen de ezamudio

SwingWorker

SwingWorker se introdujo apenas en Java 6; en Java 5 hay que usar un backport. Aquí mismo hubo una discusión al respecto hace tiempo.

Yeap, SwingWorker en Java 1.6

Yeap, SwingWorker en Java 1.6 y java.util.concurrent desde 1.5

Imagen de beto.bateria

Patron Singleton

No se podria aplicar un patron singleton con synchronized, y la clase command heredar directamente de Thread?

Imagen de ezamudio

synchronized?

En dónde quieres meter synchronized?

No se recomienda extender Thread, es mejor implementar Runnable, y luego crear un Thread con tu Runnable.

Imagen de ezamudio

volatile

Lo que sí estaría bueno es hacer volatile la variable running, para hacerlo a prueba de alguien con un mouse/dedo hiper-rápidos...

Imagen de beto.bateria

Encuentro esta parte como que

Encuentro esta parte como que muy "repetitiva", creo que se podria hacer mas sencilla.

public void run() {
new Thread( new Runnable() {
public void run() {
// codigo
}).start();
}

Ademas me esta indicando que cada vez que pulse el buttom se creara un thread (no le veo caso que existan mas), por lo que creo que hay que asegurar que la variable running solo se accedida (no se si este bien utilizada esta palabra) por un thread a la vez., ya que en el momento menos esperado va a dar problemas.

Lo que trataria de hacer es que solo existiera un solo thread ejecutandose a la vez, poniendo antes de execute() un if o implementando un singleton adaptado al caso u otra opcion.

public void actionPerformed( ActionEvent e ) {
execute();
}

tal ves ahi valdria la pena poner el running.

Imagen de ezamudio

refactor

Yo simplemente cambiaría el nombre de Command.run a Command.execute() o algo así, luego haría que Command implemente Runnable, y el Command.run() sería el que está definido en el Runnable anónimo que se pasa al Thread.

Y luego el if (running) lo pondría en el método execute(). Algo así:

class Command implements Runnable {
  //blabla las otras variables
  private volatile boolean running;
  //blabla los otros métodos

  //Este originalmente era el run
  public void execute() {
    if (!running) {
      new Thread(this).start();
    }
  }

  //Y este es el nuevo run
  public void run() {
    running = true;
    //blabla todo el demás código, pero luego primero avisamos que ya acabamos
    SwingUtilities.invokeLater( new Runnable() {
      public void run() {
        callback.done();
      }
    });
    //y ahora sí ponemos la bandera en falso
    running = false;
  }
}

Yeap, es repetitiva y en vez

Coincido en que hay varios puntos de mejora. Es repetitiva y en vez de usar un nuevo thread debería de usarse un executor o algo así del paquete java.util.concurrent y combinarlo con el SwingWorker ( momento creo que eso ya lo dije )

Para este ejemplo el control lo lleva el thread mismo negandose a trabajar:

// Si ya está corriendo, regresa ... y no hagas nada
if( running ) {
    out.println("Ignorando. Estoy trabajando");
    return;
}
//

jeje

Repito aquí mi nota:

" nota: este es solo un ejemplo y no necesariamente un modelo a seguir, en especial el comando y su control deberían de ser diferentes "

Saludos.

Imagen de ezamudio

cambios

Si usas un thread pool de un solo hilo, creado con Executors.newSingleThreadExecutor(), entonces podrías ni siquiera validar si ya está corriendo algo o no; simplemente cada vez que aprieten el botón creas un nuevo Command (que ya lo hice Runnable) y lo encolas en el ExecutorService. Como es de un solo hilo, siempre se va a ejecutar uno a la vez... pero tal vez no es lo que quieras; si quieres asegurarte de negar la acción si es que ya está ejecutando, entonces un thread pool no te va a ayudar.

Imagen de beto.bateria

Discusion productiva.

Creo que es una critica muy constructiva de que se ofrezcan opciones de como mejorar el codigo, en vez de discutir si es mejor java que .net, linux que bsd, gnome que kde, que la verdad no llegan a nada :)

Imagen de ezamudio

no llegan a nada

porque aquí todos sabemos que <sarcasmo>Java es mejor que .NET, Linux es mejor que BSD, Gnome es mejor que KDE, y vi es mejor que emacs</sarcasmo>.

Hubiera preferido que los

<sarcasm>
Hubiera preferido que los ordenaras al revés para que el sarcasmo tuviera sentido:

<sarcasmo>.net es mejor que Java, bsd que linux, kde que gnome y emacs que vi ( ahora sí ) </sarcasmo>

</sarcasm>

Imagen de benek

Tira Ecol

Me recordaron a esta Tira Ecol, en la que se refleja toda la armonía y entendimiento que hay en el mundo Linux. :')

Salute. xD

Re: Hubiera preferido que los

Negación de una negación!!!
Sarcasmo de un sarcasmo!!!

Que recursividad ni que nada, eso si está freak o_O

Imagen de ezamudio

Violencia

Luego por qué clasifican a ciertas películas como violentas...

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">