Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to trigger an action in parent JPanel when a component in a child JPanel is updated (Java Swing)

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.

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.

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?");
        }        
    }
}
like image 759
user1002119 Avatar asked Feb 19 '12 05:02

user1002119


People also ask

Can you add an action listener to a JPanel?

First off as @Sage mention in his comment a JPanel is rather a container than a component which do action. So you can't attach an ActionListener to a JPanel .

How are components added to a JPanel?

Adding components to JPanel To add GUI components such as JLabel, JTextField, JButton... to the panel, we use the add() method. There are different versions of the add() method, so which method to be used is depending on the layout manager of the panel.

Can I add JScrollPane to JPanel?

getContentPane(). add(scrollPanel); This code will work in general to add JScrollPane to JPanel. Adjust bounds of frame, panel and scrollpane according to your requirements but ensure that the bounds of JScrollPane are within the bounds of the frame otherwise the scrollpane will not be visible.

Is a JPanel a JComponent?

JPanel is a subclass of the JComponent, which is a child of the Container; therefore, JPanel is also considered a container. There are many methods used by JPanel, which it inherits from its parent classes.


1 Answers

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");
      }
   }
}
like image 108
Hovercraft Full Of Eels Avatar answered Sep 21 '22 05:09

Hovercraft Full Of Eels