Search code examples
javaswingjpanelactioneventdispatchevent

Java Passing ActionEvents to parent component


firstly apologies if the title is brief, I've thought it over but can't come up with a summary short enough for my question.

I have a JPanel class which consists of JButtons.

I have my main Swing application class, which has Swing components, AS WELL AS the JPanel class. What I want to do is for the ActionEvents fired from my JPanel class to be dispatched to my Swing application class to process. I've searched examples on the net and forums (including this one), but can't seem to get it to work.

My JPanel class:

public class NumericKB extends javax.swing.JPanel implements ActionListener {
    ...

    private void init() {
        ...
        JButton aButton = new JButton();
        aButton.addActionListener(this);

        JPanel aPanel= new JPanel();
        aPanel.add(aButton);
        ...
    }

    ...

    @Override
    public void actionPerformed(ActionEvent e) {   
        Component source = (Component) e.getSource();

        // recursively find the root Component in my main app class
        while (source.getParent() != null) {            
            source = source.getParent();
        }

        // once found, call the dispatch the current event to the root component
        source.dispatchEvent(e);
    }

    ...
}



My main app class:

public class SimplePOS extends javax.swing.JFrame implements ActionListener {


    private void init() {
        getContentPane().add(new NumericKB());
        pack();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        ...

        // this is where I want to receive the ActionEvent fired from my NumericKB class
        // However, nothing happens

    }
}  


The reason for wanting to write a separate JPanel class is because I want to reuse this in other apps.

Also, the actual code, my main app class has many subcomponents which and the JPanel class is added into one of the subcomponents, thus the recursive .getParent() calls.

Any help would be much appreciated. Thank in advance! Cheers.


Solution

  • You cannot rethrow the event to parent because the parent has no support for delivering of ActionEvents. But in your case you can simply check whether your component has action support and call it. Something like this

    public class NumericKB extends javax.swing.JPanel implements ActionListener {
      ...
    
      private void init() {
        ...
        JButton aButton = new JButton();
        aButton.addActionListener(this);
    
        JPanel aPanel= new JPanel();
        aPanel.add(aButton);
        ...
      }
    
      ...
    
      @Override
      public void actionPerformed(ActionEvent e) {   
        Component source = (Component) e.getSource();
    
        // recursively find the root Component in my main app class
        while (source.getParent() != null) {            
            source = source.getParent();
        }
    
        // once found, call the dispatch the current event to the root component
        if (source instanceof ActionListener) {
          ((ActionListener) source).actionPerformed(e);
        }
      }
    
    ...
    }