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

Actualizar JPanels de un típico JFrame

Estas en el tema de Actualizar JPanels de un típico JFrame en el foro de Java en Foros del Web. Hola, despues de mirar unos libros e Internet no termino de aclararme de como se pueden/deben actualizar los distintos paneles que conforman un JFrame. Los ...
  #1 (permalink)  
Antiguo 05/04/2009, 11:15
msi
 
Fecha de Ingreso: marzo-2005
Mensajes: 70
Antigüedad: 19 años, 8 meses
Puntos: 0
Actualizar JPanels de un típico JFrame

Hola, despues de mirar unos libros e Internet no termino de aclararme de como se pueden/deben actualizar los distintos paneles que conforman un JFrame. Los ejemplos que veo en libros son básicos y todo el código está escrito en una sola clase.

Mi caso es el típico BorderLayout donde existen 4 Paneles:

Código:
public class MainFrame extends JFrame {

		setLayout(new BorderLayout());
		
		JPanel northPanel = new NorthPanel();
		add(northPanel,BorderLayout.NORTH);
		
		Box southPanel = new SouthPanel();
		add(southPanel,BorderLayout.SOUTH);
		
		JPanel westPanel = new WestPanel();
		add(westPanel,BorderLayout.WEST);
		
		JPanel eastPanel = new EastPanel();
		add(eastPanel,BorderLayout.EAST);
		
		Box centerPanel = new CenterPanel();
		add(centerPanel,BorderLayout.CENTER);

Cada uno de estos Paneles es una clase Java situada en un fichero distinto. Por ejemplo el EastPanel contiene una serie de botones y el CenterPanel contiene un TabbedPane.

Yo quiero que cuando se ejecute un método del CenterPanel automáticamente se modifique la vista del EastPanel (por ejemplo que se active uno de los botones), es decir, que los componentes del EastPanel cambien según las indicaciones.

He conseguido tener la gestión de los eventos del CenterPanel, tal como:

Código:
public class CenterPanel extends Box {

public CenterPanel() {
.....

XXX.addPropertyChangeListener(new PropertyChangeListener(){
	public void propertyChange(PropertyChangeEvent event) {
		firePropertyChangeEvent(new PropertyChangeEvent(this,"propertyCualquiera",false,false));
	}
});

De esta forma, en mi JFrame puedo leer cuando se ha ejecutado el método del CenterPanel que es el que debería hacer activar un botón del EastPanel. He aquí como me ha quedado el código:

Código:
public class MainFrame extends JFrame {

setLayout(new BorderLayout());
		
JPanel northPanel = new NorthPanel();
add(northPanel,BorderLayout.NORTH);

Box southPanel = new SouthPanel();
add(southPanel,BorderLayout.SOUTH);
		
JPanel westPanel = new WestPanel();
add(westPanel,BorderLayout.WEST);
	
JPanel eastPanel = new EastPanel();
add(eastPanel,BorderLayout.EAST);

Box centerPanel = new CenterPanel();
add(centerPanel,BorderLayout.CENTER);

centerPanel.addPropertyChangeListener(new PropertyChangeListener() {
	public void propertyChange(PropertyChangeEvent evt) {
		System.out.println("CENTERPANEL leyendo");
                // ¿COMO HAGO AQUÍ PARA HACER CAMBIAR AL EASTPANEL?
               //eastPanel.hazAlgo()      <--- Esto no se puede, dice que no esta definido en la clase, aunque yo si tengo el método
	}
});
En este punto consigo que cuando ejecuto un método en CenterPanel, desencadeno un PropertyChange desde el CenterPanel y esto es leido en el MainFrame. He intentado crear un método en EastPanel para llamarlo e intentar que ahí se activen los botones pero no puedo hacer esta llamada.

¿Alguna idea para hacer cambiar un botón que esté en otro Panel del JFrame? ¿Como se gestionan pues este tipo de casos? Porque supongo que mi problema es bastante común.

Un saludo.
  #2 (permalink)  
Antiguo 05/04/2009, 15:09
msi
 
Fecha de Ingreso: marzo-2005
Mensajes: 70
Antigüedad: 19 años, 8 meses
Puntos: 0
Respuesta: Actualizar JPanels de un típico JFrame

Bueno, queria hacer una puntualización. Se cómo hacer que funcione pero me parece un poco "chapucero". Si ese botón lo declaro en el JFrame, puedo pasarlo como parámetro al panel EastPanel para que se muestre y en el CenterPanel para gestionar su funcionamiento, algo como:


Código:
public class MainFrame extends JFrame {

final JButton boton = new JButton("probando");


setLayout(new BorderLayout());
		
JPanel northPanel = new NorthPanel();
add(northPanel,BorderLayout.NORTH);
		
Box southPanel = new SouthPanel();
add(southPanel,BorderLayout.SOUTH);
		
JPanel westPanel = new WestPanel();
add(westPanel,BorderLayout.WEST);
		
JPanel eastPanel = new EastPanel(boton);
add(eastPanel,BorderLayout.EAST);
		
Box centerPanel = new CenterPanel(boton);
add(centerPanel,BorderLayout.CENTER);

¿Acaso tengo que usar este método para conseguir mi propósito? ¿Qué pasaría si en vez de 1 componente son 100? ¿tendría que que pasarlos todos? Me resisto a creer que esta es la forma correcta y pienso que debe haber otra manera más limpia para interactuar entre los distintos JPanels de un JFrame.

A la espera de nuevas noticias...
  #3 (permalink)  
Antiguo 06/04/2009, 04:41
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 20 años, 1 mes
Puntos: 454
Respuesta: Actualizar JPanels de un típico JFrame

Hola:

En el primer post, el código que pones par el JFrame no está muy claro, ya que declaras la clase y te pones a hacer código directamente, sin poner constructor ni nada.

En el propertyChangeListener (y en cualquier listener/hilo en general) no puesdes usar una variable local de otro sitio (en tu caso, eastPanel). Ten en cuenta que el listener se ejecuta más adelante, cuando cambie la propiedad y es posible que la variable local haya desaparecido entonces (no su contenido, sino la variable). En el siguiente ejemplo

Código:
public void unMetodo (...) {
   int unaVariableLocal = ...;
   unBoton.addActionListener (new ActionListener () {
      public void actionPerformed(ActionEvent e) {
           // Aquí no puedo usar unaVariableLocal.
      }
   });
}
unaVariableLocal existe mientras estás en unMetodo(), pero la ejecución de unMetodo() puede haber acabado mucho antes de que pulses el botón y se ejecute el actionPerfomed, por lo que unaVariableLocal hace tiempo que ha dejado de existir y por eso no puede usarse.

Si quieres usar esa variable (eastPanel), debes declararlo como atributo de la clase, así existe mientras existe la clase.

Código:
public class UnaClase {
    int unaVariable;

   public void unMetodo (...) {
      unaVariable = ...;
      unBoton.addActionListener (new ActionListener () {
      public void actionPerformed(ActionEvent e) {
           // Aquí SI puedes usar unaVariable
      }
   });
}
La otra opción, aunque a mí me gusta menos, es dejar la variable como local, pero declararla final. De esta forma, sí se tiene acceso a ella.

Código:
public void unMetodo (...) {
   final int unaVariableLocal = ...;
   unBoton.addActionListener (new ActionListener () {
      public void actionPerformed(ActionEvent e) {
           // Aquí SI puedo usar unaVariableLocal.
      }
   });
}
Una vez solucionado esto, supongo que queda resuelta la duda del segundo post. No necesitas que el mainframe vea el botón. Símplemente declara el eastPanel de la misma forma que has declarado el JButton. Me da la impresión de que has usado la opción de final, pero ya te digo que no se puede saber seguro porque no has puesto si ese código está en un método o no.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #4 (permalink)  
Antiguo 06/04/2009, 12:29
msi
 
Fecha de Ingreso: marzo-2005
Mensajes: 70
Antigüedad: 19 años, 8 meses
Puntos: 0
Respuesta: Actualizar JPanels de un típico JFrame

Gracias chuidiang por contestar y por los ejemplos, no escribí todo el código porque me parecía que sólo hacía que confundir y lo resumí. No había caido en declarar el JPanel como final, lo he probado y ya puedo llamar al método que haya creado a tal fin.

También he visto otra posibilidad de tener la gestión de los eventos en cada uno de los JPanels en vez de tener esta gestión en el JFrame. Si declaro el JPanel que implemente la interface PropertyChangeListener, desde el JFrame puedo tener:

centerPanel.addPropertyChangeListener(eastPanel);

y así ya la clase eastPanel tendría su método de gestión propertyChange() donde meter el código. Lo malo es que seguramente tenga que hacer también eastPanel.addPropertyChangeListener(centerPanel) ya que los paneles son dependientes entre sí, así que no se como quedará al final.

Hasta otra!
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 13:45.