2012-02-19 22 views
7

Estoy intentando crear una aplicación MVC en Java Swing. Tengo un JPanel que contiene cuatro JComboBoxes y este JPanel está incrustado en un JPanel padre. El JPanel padre tiene otros controles además del JPanel hijo.cómo desencadenar una acción en JPanel padre cuando se actualiza un componente en un JPanel hijo (Java Swing)

El modelo de JPanel hijo se actualiza correctamente cada vez que cambio los valores de JComboBoxes (básicamente es un selector de fechas con un cuadro combinado para cada año, mes, día del mes y hora del día). Lo que no puedo entender es cómo puedo activar el modelo de JPanel padre para que se actualice a sí mismo para que coincida con el valor almacenado en el modelo de JPanel hijo siempre que se modifique uno de los JComboBoxes.

A continuación se muestra un despojado de SSCCE de la estructura de lo que tengo hasta ahora. Gracias.

import java.awt.event.*; 
import javax.swing.*; 

public class Example extends JFrame { 
    public Example() { 
     super(); 
     OuterView theGUI = new OuterView(); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setResizable(false); 
     add(theGUI); 
     pack(); 
     setVisible(true);   
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new Example(); 
      } 
     });   
    } 
} 

class OuterView extends JPanel { 
    public OuterView() { 
     super(); 
     InnerView innerPanel = new InnerView(); 
     JButton button = new JButton("display OuterView's model"); 
     button.addActionListener(new ButtonListener()); 
     add(innerPanel); 
     add(button); 
    } 

    private class ButtonListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent ae) { 
      System.out.println("button was clicked"); 
     } 
    } 
} 

class InnerView extends JPanel { 
    public InnerView() { 
     super(); 
     String[] items = new String[] {"item 1", "item 2", "item 3"}; 
     JComboBox comboBox = new JComboBox(items); 
     comboBox.addActionListener(new ComboBoxListener()); 
     add(comboBox); 
    } 

    private class ComboBoxListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent ae) { 
      String text = ((JComboBox) ae.getSource()).getSelectedItem().toString(); 
      System.out.println("store " + text + " in InnerView's model"); 
      System.out.println("now how do I cause OuterView's model to be updated to get the info from InnerView's model?"); 
     }   
    } 
} 
+0

El padre debe tener un oyente en el modelo del niño. –

+0

O puede _enviar_ el evento al padre, como se muestra [aquí] (http://stackoverflow.com/q/2159803/230513). – trashgod

Respuesta

15

Puede usar un PropertyChangeListener, y de hecho uno está integrado en cada componente. por ejemplo:

import java.awt.event.*; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class Example extends JFrame { 
    public Example() { 
     super(); 
     OuterView theGUI = new OuterView(); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setResizable(false); 
     add(theGUI); 
     pack(); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      new Example(); 
     } 
     }); 
    } 
} 

class OuterView extends JPanel { 
    private String innerValue = ""; 

    public OuterView() { 
     super(); 
     InnerView innerPanel = new InnerView(); 
     innerPanel.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      if (evt.getPropertyName().equals(InnerView.COMBO_CHANGED)) { 
       innerValue = evt.getNewValue().toString(); 
       System.out.println("new value from inside of OuterView: " 
        + innerValue); 
      } 
     } 
     }); 
     JButton button = new JButton("display OuterView's model"); 
     button.addActionListener(new ButtonListener()); 
     add(innerPanel); 
     add(button); 
    } 

    private class ButtonListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent ae) { 
     System.out.println("button was clicked. innerValue: " + innerValue); 
     } 
    } 
} 

class InnerView extends JPanel { 
    public static final String COMBO_CHANGED = "Combo Changed"; 
    // private SwingPropertyChangeSupport pcSupport = new 
    // SwingPropertyChangeSupport(this); 
    String oldValue = ""; 

    public InnerView() { 
     super(); 
     String[] items = new String[] { "item 1", "item 2", "item 3" }; 
     JComboBox comboBox = new JComboBox(items); 
     comboBox.addActionListener(new ComboBoxListener()); 
     add(comboBox); 

    } 

    private class ComboBoxListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent ae) { 
     String text = ((JComboBox) ae.getSource()).getSelectedItem() 
       .toString(); 
     firePropertyChange(COMBO_CHANGED, oldValue, text); 
     oldValue = text; 
     System.out.println("store " + text + " in InnerView's model"); 
     } 
    } 
} 
+1

+1 para acoplamiento flojo. – trashgod

+0

¡Gracias, su solución fue realmente útil! – user1002119

+0

@ user1002119: ¡De nada! Me alegro de que haya ayudado. –

Cuestiones relacionadas