2012-02-19 74 views
7

我想在Java Swing中構建一個MVC應用程序。我有一個包含四個JComboBox的JPanel,並且這個JPanel嵌入到父JPanel中。父JPanel除了子JPanel之外還有其他控件。當孩子JPanel中的組件被更新時如何在父JPanel中觸發一個動作(Java Swing)

只要我更改JComboBoxes的值(它基本上是一個日期選擇器,每個年份,月份,月份中的某一天以及每個小時都有一個組合框),就可以正確更新子項JPanel的模型。我無法弄清楚的是,只要其中一個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?"); 
     }   
    } 
} 
+0

父母應該在孩子的模型上有一個監聽器。 – 2012-02-19 05:10:39

+0

或者您可以將事件轉發給父代,如[此處](http://stackoverflow.com/q/2159803/230513)所示。 – trashgod 2012-02-19 05:18:21

回答

15

您可以使用PropertyChangeListener,實際上每個組件都內置一個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"); 
     } 
    } 
} 
+1

+1表示鬆耦合。 – trashgod 2012-02-19 05:25:40

+0

謝謝你,你的解決方案真的很有幫助! – user1002119 2012-02-19 07:29:14

+0

@ user1002119:不客氣!很高興幫助。 – 2012-02-19 11:55:30