Buscar
Social
Ofertas laborales ES

Foro sobre Java SE > Actualizar los datos de JFrame1 desde JFrame2

Tengo la siguiente duda: Si tengo 2 jframes, Jframe1 y Jframe2. En JFrame1 tengo un jLabel y en JFrame2 tengo un Jbutton. Como es posible hacer que cuado de click en Jbutton del JFrame2 se ponga un texto en JLabel de JFrame1, Si ambos frames ya estan abiertos.

Se supone que JFrame1 ya este visible y tenga otra informacion cuando se haga click en JFrame2.

De ante mano Gracias.

abril 29, 2014 | Registered Commentergermymcg

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

/**
<p>
@author Carlos Hoces
*/
public class TestFrames {

/**
@param args the command line arguments
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrameLabel jFrameLabel = new JFrameLabel();
jFrameLabel.setVisible(true);
JFrameButton jFrameButton = new JFrameButton();
jFrameButton.setVisible(true);
jFrameButton.addPropertyChangeListener(new PropertyChangeListener() {

@Override
public void propertyChange(PropertyChangeEvent evt) {
jFrameLabel.setLabel("Botón pulsado en otro frame");
}
});
}
});
}

}

abril 29, 2014 | Registered Commenterchoces

/**
<p>
@author Carlos Hoces
*/
public class JFrameLabel extends javax.swing.JFrame {

/** Creates new form NewJFrameLabel */
public JFrameLabel() {
initComponents();
}

public void setLabel(String contenido) {
jLabel.setText(contenido);
}

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

jLabel = new javax.swing.JLabel();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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()
.addComponent(jLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

// Variables declaration - do not modify
private javax.swing.JLabel jLabel;
// End of variables declaration
}

abril 29, 2014 | Registered Commenterchoces

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
<p>
@author Carlos Hoces
*/
public class JFrameButton extends javax.swing.JFrame {

/** Creates new form NewJFrameButton */
public JFrameButton() {
initComponents();
jButton1.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
JFrameButton.this.firePropertyChange("boton", null, null);
}
});
}

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

jButton1 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("Botón");

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(329, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

// Variables declaration - do not modify
private javax.swing.JButton jButton1;
// End of variables declaration
}

abril 29, 2014 | Registered Commenterchoces

Esta pregunta de pasar datos de un jFrame a otro yo creo que cae todas las semanas.

Tenias que poner un sticky post al respecto, choces; o tener ya el ejemplo preparado en pastebin.

abril 29, 2014 | Unregistered CommenterUnoPorAhi

El foro, que yo sepa, no permite crear stickies.
Lo interesante sería crear un tutorial, lo más completo posible, que contemple todas las opciones.

Aparte de la solución del PropertyChangeListener, que es válida para casos muy sencillos, hay otras dos: el patrón Observer/Observable, y el patrón Publisher/Subscriber.
El primero se puede implementar con el JDK, pero el segundo necesita de librerías externas, como EventBus o Guava.
No son tan triviales de implementar, y para principiantes pueden ser un dolor de cabeza.
La gran ventaja del Publisher/Suscriber es que elimina el acoplamiento entre clases.

Si se usa NetBeans Platform para aplicaciones de escritorio, su Lookup API proporciona las herramientas necesarias.

abril 30, 2014 | Registered Commenterchoces

Buenas choces,

Yo siempre he pensado que los listeners eran un claro ejemplo de aplicacion del patron Observer/Observable. No seria reinventar la rueda?
http://es.wikipedia.org/wiki/Observer_(patr%C3%B3n_de_dise%C3%B1o)

Respecto al publisher/subscriber, en principio lo veo tambien un poco relacionado con la cola de eventos, pero no estoy seguro. Tienes algun link a alguna pagina que implemente la solucion con eventbus o guava?

Siempre aprendo cosas nuevas gracias a ti :-)


Un saludo

abril 30, 2014 | Unregistered CommenterUnoPorAhi

"Siempre aprendo cosas nuevas gracias a ti". Lo mismo puedo decir yo, pero te me has adelantado :)

El problema no es el diseño de los listeners, ni los que incluye Swing por defecto, sino su aplicación concreta. El problema que se plantea en este hilo es un ejemplo muy habitual.
Todavía es peor si se trata de conectar clases que no son de Swing con componentes de Swing. Y si están en packages diferentes, o proyectos diferentes enlazados a uno principal, las complicaciones crecen exponencialmente. El resultado suele ser una maraña de dependencias, con el riesgo añadido de crear dependencias circulares entre clases.

Por eso existen esos patrones, con la intención de resolver esas complicaciones.
Lo malo del Observer/Observable es que mantiene el acoplamiento entre clases, igual que si se usan directamente los listeners.

Sin embargo, el Publisher/Subscriber permite eliminar la interdependencia entre clases "observadas" y "que observan", porque lo que se envía y recibe son únicamente "datos": simples POJO. Las que reciben y las que envían "no saben nada unas de las otras".

He usado mucho EventBus, antes de empezar con NetBeans Platform. Con Guava no tengo ninguna experiencia. Incluso he tenido que desarrollar mi propia implementación de Publisher/Subscriber con el Lookup API de NB Platform.

https://java.net/projects/eventbus

https://code.google.com/p/guava-libraries/wiki/EventBusExplained

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/eventbus/EventBus.html

abril 30, 2014 | Registered Commenterchoces

Ejemplos con EventBus:

http://developmentality.wordpress.com/2010/05/11/eventbus-introduction-and-troubleshooting-for-annotation-problems/

http://www.zdnet.com/catching-the-bus-in-java-2062034699/

Aparte los tests que están en la base de código de EventBus :)

abril 30, 2014 | Registered Commenterchoces

Acabo de modificar tu ejemplo usando el eventbus de Guava.
https://github.com/unoporahi/TestEventBusGuava

La verdad es que resulta bastante cómodo y fácil de usar, aunque supongo que sus verdaderas ventajas no se observan realmente hasta que se tiene una aplicación compleja con muchos componentes.

Un saludo

mayo 1, 2014 | Unregistered CommenterUnoPorAhi

He visto ya esa modificación.
Lo que no me convence de Guava EventBus es la necesidad de ésto:

public static EventBus appEventBus = new EventBus();

Con EventBus de Michael Bushe, solo se necesita registrar los subscribers, dentro de la propia clase que los usa, y mediante anotaciones es muy simple de hacer en el mismo constructor.
Cada método que se subscribe se anota igualmente con la clase POJO que contiene los datos, y no es necesario hacer nada más.
La publicación es trivial.

mayo 1, 2014 | Registered Commenterchoces

El mismo ejemplo, con EventBus, más un contador de pulsaciones del botón.
No hay ninguna referencia al EventBus.

public class TestFrames {

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrameLabel jFrameLabel = new JFrameLabel();
jFrameLabel.setVisible(true);
JFrameButton jFrameButton = new JFrameButton();
jFrameButton.setVisible(true);
}
});
}
}

mayo 1, 2014 | Registered Commenterchoces

private final String cadena;
private final int contador;

public EventBusData(String cadena, int contador) {
this.cadena = cadena;
this.contador = contador;
}

/**
@return the cadena1
*/
public String getCadena() {
return cadena;
}

/**
@return the contador
*/
public int getContador() {
return contador;
}
}

mayo 1, 2014 | Registered Commenterchoces

import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.bushe.swing.event.annotation.EventSubscriber;

public class JFrameLabel extends javax.swing.JFrame {

/** Creates new form NewJFrameLabel */
public JFrameLabel() {
AnnotationProcessor.process(JFrameLabel.this);
initComponents();
}

@EventSubscriber(eventClass = EventBusData.class)
public void setNuevaEtiqueta(EventBusData data) {
jLabel.setText(data.getContador() + " " + data.getCadena());
}

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

jLabel = new javax.swing.JLabel();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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()
.addComponent(jLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

// Variables declaration - do not modify
private javax.swing.JLabel jLabel;
// End of variables declaration
}

mayo 1, 2014 | Registered Commenterchoces

import org.bushe.swing.event.EventBus;

public class JFrameButton extends javax.swing.JFrame {

/** Creates new form NewJFrameButton */
public JFrameButton() {
initComponents();

jButton1.addActionListener(new ActionListener() {
private int contador = 0;

@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
EventBus.publish(new EventBusData("Botón pulsado", contador));
contador++;
}
});
}

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

jButton1 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("Botón");

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(329, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

// Variables declaration - do not modify
private javax.swing.JButton jButton1;
// End of variables declaration
}

mayo 1, 2014 | Registered Commenterchoces