如何更新子JPanel中的组件时如何在父JPanel中触发操作(Java Swing) [英] how to trigger an action in parent JPanel when a component in a child JPanel is updated (Java Swing)

查看:133
本文介绍了如何更新子JPanel中的组件时如何在父JPanel中触发操作(Java Swing)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to build an MVC application in Java Swing. I have a JPanel that contains four JComboBoxes and this JPanel is embedded into a parent JPanel. The parent JPanel has other controls in addition to the child JPanel.

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

The child JPanel's model gets correctly updated whenever I change the values of the JComboBoxes (it's basically a date picker with one combo box each for year, month, day of month, and hour of day). What I cannot figure out is how I can trigger the parent JPanel's model to update itself to match the value stored in the child JPanel's model whenever one of the JComboBoxes is changed.

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

Below is a stripped down SSCCE of the structure of what I have so far. Thank you.

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,实际上每个组件都内置了一个。例如:

You could use a PropertyChangeListener, and in fact one is built into every component. e.g.:

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

这篇关于如何更新子JPanel中的组件时如何在父JPanel中触发操作(Java Swing)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆