proceso en segundo plano que me reemplaza paneles, en modo debugger funciona

Iniciado por jadi, 6 Febrero 2021, 04:33 AM

0 Miembros y 1 Visitante están viendo este tema.

jadi

Hola como estan?.
Estoy tratando de desarrollar un juego, el cual tiene dialogos que se muestran en secuencia.
Dentro del jFrame tengo un panel llamado jPanelCuerpo el cual tiene un panel jPortada que muestra la imagen de presentacion.
los dialogos están en secuencia (estos se instancian en un panel de dialogo) y tienen un atributo estado el cual indica (instanciado=0, en ejcución=1 o finalizado=2), además tienen un indice que apunta al dialogo en proceso.
El proceso en segundo plano verifica el estado del dialogo en proceso si esta instanciado, reemplaza el panel de portada por el panel del dialogo y le pone estado en ejecucion, del mismo panel de dialogo tiene un jlabel con un con evento mouseclic que pone el dialogo es estado finalizado,
Cuando el proceso en segundo plano se entera de que cambio el estado a finalizado pasa al siguiente dialogo.

Si ejecuto el programa solo me muestra el primer dialogo, si ejecuto en modo debugger al ir verificando los pasos se cambian los dialogos sin problema.

Es como si al ir paso a paso el proceso tiene el tiempo para realizar los cambios, al correr normal pareciera que solo pone el primer dialogo

Si alguien me puede orientar que puede ser desde ya muy agradecido
Saludos
Javier

Clase runnable que instancio en un thread que guardo como atributo(hiloJ) del jFrame Juego
Código (java) [Seleccionar]

public class EjecutarSuceso implements Runnable {
   private Jugar fParent;
   private JPanel jPanelCuerpo;
   private Dialogo jpanelJuegoD;               // panel para los dialogos  (multiples instancias)
   private Reto jpanelJuegoR;                  // panel para los retos     (multiples instancias)
   private SieteYMedio jpanelJuegoS;           // panel para el siete y medio
   private EntradaPc jpanelJuegoH;             // panel para el hackeo
   private int ultimoTSuceso;                  // indica el último suceso ejecutado
   
   public EjecutarSuceso(Jugar fp, JPanel jpanel) {
       fParent=fp;
       jPanelCuerpo=jpanel;
   }
   
   @Override
   public void run(){
       int tipoSuceso;
       boolean lupdateui=false;
       boolean linstancio=false;
       
       ultimoTSuceso=0;
       // tengo que recorrer el array de los sucesos del escenario, tomando
       // en cuenta el estado del escenario si no termino y el estado del suceso
       // si el estado del escenario indica que termino finalizo ya que puedo desde otra
       // parte indicar que termine
       // si el estado del suceso es que esta instanciado invoco al evento correspondiente
       // actualizando el estado del suceso a estado en ejecución
       // si el estado del suceso esta en ejecucion no hago nada, espero a que cambie
       // su estado desde otra parte del juego
       // si el estado del suceso es finalizado paso al siguiente y si no hay un siguiente
       // pongo en el estado de escenario fin y salgo del while
       while (true){
       
           // si el escenario se marco como terminado salgo del while
           if (fParent.getEscenario().getEstado()==Sistema.EEND) {
               break;
           }
           // si el suceso instanciado termino
           if (fParent.getEscenario().getCurrentSuceso().getEstado()==Sistema.EEND) {
               // si no hay un siguiente suceso pongo en el escenario el atributo estdo como terminado y salgo del while
               if (!(fParent.getEscenario().setNextIndice())){
                   fParent.getEscenario().setEstado(Sistema.EEND);
                   break;
               }
           }

           // si el suceso esta en estado creado
           if (fParent.getEscenario().getCurrentSuceso().getEstado()==Sistema.ECREADO) {

               // pongo a false linstacio
               linstancio=false;
               // vemos segun el tipo de suceso si ya instanciado el objeto o sino lo instancio
               // almaceno el tipo del suceso en curso
               tipoSuceso=fParent.getEscenario().getCurrentSuceso().getTipoSuceso();
               switch (tipoSuceso){
                   // Dialogos
                   case Sistema.DIALOGO:
                       // si no esta instanciado el objeto panel dialogo lo instancio
                       // sino actualizo los componentes
                       if (jpanelJuegoD==null){
                           jpanelJuegoD = new Dialogo(fParent);
                           linstancio=true;
                       }
                       break;
                   // Retos
                   case Sistema.DESAFIO:
                       if (jpanelJuegoR==null){
                           jpanelJuegoR = new Reto((Jugar)fParent);
                           linstancio=true;
                       }
                       break;
                   // Siete y Medio
                   case Sistema.OBJETIVO_SIETEYMEDIO:
                       // si es objetivo hay que ver si es siete y medio o hackeo
                       if (jpanelJuegoS==null){
                           jpanelJuegoS = new SieteYMedio((Jugar) fParent);
                           linstancio=true;
                       }
                       break;
                   // por defecto si no es uno de los sucesos anteriores es el hackeo
                   default:
                       if (jpanelJuegoS==null){
                           jpanelJuegoH = new EntradaPc((Jugar) fParent, jPanelCuerpo);
                           linstancio=true;
                       }
                       break;
               }
               
               // si el suceso a ejecutarse es distinto al que su anterior verifico
               // que quede un solo componente en jPanelCuerpo
               if ((tipoSuceso!=ultimoTSuceso) && (jPanelCuerpo.getComponentCount()>1)){
                   jPanelCuerpo.remove(0);
                   lupdateui=true;
               }
               
               // tengo que poner el setvisible del panel portada en false si esta visible
               if (jPanelCuerpo.getComponent(jPanelCuerpo.getComponentCount()-1).isVisible()){
                   jPanelCuerpo.getComponent(jPanelCuerpo.getComponentCount()-1).setVisible(false);
               }

               // si es un DIALOGO, hay multiples DIALOGOS
               if (Sistema.DIALOGO==tipoSuceso){
                   if (tipoSuceso!=ultimoTSuceso) {
                       // fParent.cambiarPanel(jpanelJuegoD);
                       jPanelCuerpo.add(jpanelJuegoD, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 870, 525),0);
                       // hago visible el jpanelJuego
                       jPanelCuerpo.getComponent(0).setVisible(true);
                       if (!linstancio){
                           jpanelJuegoD.updatePanel();
                       }
                   }
                   // si el suceso es del mismo tipo quel anteriior solo actualizo para el suceso los componentes
                   else {
                       jpanelJuegoD.updatePanel();
                   }
               }
               // si es un DESAFIO, hay multiples DESAFIOS
               else if(Sistema.DESAFIO==tipoSuceso){
                   if (tipoSuceso!=ultimoTSuceso) {
                       jPanelCuerpo.add(jpanelJuegoR, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 870, 525),0);
                       // hago visible el jpanelJuego
                       jpanelJuegoR.setVisible(true);
                       if (!linstancio){
                           jpanelJuegoR.updatePanel();
                       }
                   }
                   // si el suceso es del mismo tipo quel anteriior solo actualizo para el suceso los componentes
                   else {
                           jpanelJuegoR.updatePanel();
                   }
               }
               // si es el objetivo SIETE Y MEDIO solo hay UNA INSTANCIA
               else if(Sistema.OBJETIVO_SIETEYMEDIO==tipoSuceso){
                   jPanelCuerpo.add(jpanelJuegoS, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 870, 525),0);
                   // hago visible el jpanelJuego
                   jpanelJuegoS.setVisible(true);
               }
               // sino solo puede ser el HACKEO, solo hay UNA INSTANCIA
               else{
                   jPanelCuerpo.add(jpanelJuegoH, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 870, 525),0);
                   // hago visible el jpanelJuego
                   jpanelJuegoH.setVisible(true);
               }

               // indico que se esta ejecutando
                   fParent.getEscenario().getCurrentSuceso().setEstado(Sistema.ERUN);
               // cargo la fecha de inicio
               fParent.getEscenario().getCurrentSuceso().setFechaIni(new Date());
               ultimoTSuceso=tipoSuceso;
               jPanelCuerpo.invalidate();
               jPanelCuerpo.updateUI();
               try {
                   // pongo a dormir el hilo del procesos
                   fParent.getHiloJ().sleep(20);
               } catch (InterruptedException ex) {
                   Logger.getLogger(EjecutarSuceso.class.getName()).log(Level.SEVERE, null, ex);
               }
           }
       }
   }
}






rub'n

Que tal doc, usa Geshi con Java, para que añadas una descripcion basica mas detallada, en las lineas mas potenciales si es posible.

Estas variables podria aplicar locks con synchronized() {} (siempre como ultima instancia, para evitar deadlocks), hacerlas inmutables o con Referencias atomicas, dado que estan en un background thread

- fParent
- jPanelCuerpo

Mismo para estas variables booleanas dentro del Thread Referencia Atomica

Código (java) [Seleccionar]
AtomicBoolean atomicBoolean = new AtomicBoolean();
- lupdateui
- linstancio

Aun asi, necesitaria mas codigo, sobre todo de las variables de instancia.




Otra cosa que no entiendo es la siguiente, si necesitas que los paneles se muestren de manera secuencial, es decir no paralela, porque implementas a Runnable?

Has intentado hacer todo sin sobreescribir el método run() ? el run es asíncrono, paralelo no secuencial, si quieres añade la clausula synchronized al método ya creado y comprueba su comportamiento


Código (java) [Seleccionar]
@Override
public synchronized void run(){ }


rubn0x52.com KNOWLEDGE  SHOULD BE FREE!!!
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen