如何更新子JPanel中的组件时如何在父JPanel中触发操作(Java Swing)

我正在尝试在Java Swing中构建一个MVC应用程序。 我有一个包含四个JComboBox的JPanel,这个JPanel嵌入到父JPanel中。 除了子JPanel之外,父JPanel还有其他控件。

每当我更改JComboBoxes的值时,子JPanel的模型都会正确更新(它基本上是一个日期选择器,每个日期,月份,月份和一小时都有一个combobox)。 我无法弄清楚的是,无论何时更改其中一个JComboBox,我都可以触发父JPanel的模型更新自身以匹配存储在子JPanel模型中的值。

下面是我所掌握的结构的简化SSCCE。 谢谢。

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?"); } } } 

您可以使用PropertyChangeListener,实际上每个组件都内置了一个。 例如:

 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"); } } }