3

I have a MainPanel. It contains SubPanel1, SubPanel2 etc. SubPanel can have any combination of JComponents like buttons, radio buttons, text boxes etc. One SubPanel may or may not be the same as another.

How do I make the MainPanel listen and respond to the actions taking place inside the SubPanels ? Please show me some good example with commented code which teaches me how to do this.

Photo -

enter image description here

david blaine
  • 5,683
  • 12
  • 46
  • 55
  • `SubPanel[] panels` sounds like a decent start. Then just iterate over it, and apply the same ActionListener to it. – Shark Apr 02 '13 at 07:35
  • @Shark - but the source (from getSource()) of the events will be the individual components of the SubPanel and not the SubPanel. I want to know which panel caused an event and handle the events. – david blaine Apr 02 '13 at 07:43
  • 2
    You really need to have a read through [How to write event listeners](http://docs.oracle.com/javase/tutorial/uiswing/components/label.html). The baid idea is you either need to provide your own listener interface or allow your panels to act as a proxy, exposing the listeners you want to allow people to register to (as per my previous answer) – MadProgrammer Apr 02 '13 at 07:57
  • There are two ways of handling events - letting every component register it's own event handler - or implementing `ActionListener` in your application and making all components `registerActionListener(this)`. Then you will make a method which will catch the pressed/interacted component and you can react accordingly there. – Shark Apr 02 '13 at 08:19
  • Crossposted: http://www.coderanch.com/t/608631/GUI/java/Listening-responding-events-Panel – camickr Apr 02 '13 at 15:24

3 Answers3

4

You may be looking for the observer pattern. Java Swing programs may use any of several ways to implement the pattern; some examples are cited here. Because a component may accept an arbitrary number of listeners, one important heuristic is to look for an existing sub-panel component to which the parent can listen. In the particular case of sub-panels, it may also be possible to forward events to a parent's listener, as suggested here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Looks like swing is not so simple after all. Maybe, I should just create an anonymous ActionLister for all components inside the main Panel. – david blaine Apr 02 '13 at 08:56
  • 1
    @davidblaine One of the main features of Swing is its flexibility. It doesn't (often) restrict you to a given style or makes assumptions about how you might use its components. It does, however, require you to put some effort in to build up a series of libraries to fit your requirements and needs - IMHO – MadProgrammer Apr 02 '13 at 10:20
  • @MadProgrammer and trashgod - the observer pattern will fail if MyClass needs to implement JPanel (ie a JPanel full of normal buttons) and also Observable. As shown in the diagram, a button panel is contained by a main panel. The button panel should be observed by the main panel. How to work around this problem ? – david blaine Apr 26 '13 at 09:37
  • @davidblaine Why? The main panel is observing the sub panel? The decision you need to make is what and how to make this happen. What does the main panel want to respond to and how to make that happen. If all the main panel cares about is a state change then you could use the `ChangeListener`. The sub panel would provide means to register a `ChangeListener` and manage the notification to those listeners based on some change in its state... – MadProgrammer Apr 26 '13 at 09:46
  • @MadProgrammer - I don't know if i am thinking correctly about it. I want to make a reusable class called button holder which extends JPanel. This will hold a grid of buttons, each of which has a unique value/name. The button holder can be used by any device like elevator panel, calculator etc. These devices are panels which hold a text field and button holder. They will find out which button is pressed inside button holder and then put the name of button in text field. – david blaine Apr 26 '13 at 09:55
  • @davidblaine An observer pattern should be capable of this, in particular an `ActionListener`. I'd basically have a `addActionListener` and `removeActionListener` method on your sub panel. This would just pass the call to each button (so that each button received the same `ActionListener`), this allows the sub panel to act as a proxy between the `ActionListener` and the buttons... – MadProgrammer Apr 26 '13 at 10:01
  • @davidblaine: Agree with MadP; also, `java.util.Observable` is conceptually simple, but a class is limited to one `extends` clause. In contrast, a class can fire any number of `PropertyChangeEvent` instances or have an `EventListenerList` holding any number of differently-typed listeners. – trashgod Apr 26 '13 at 10:38
1

Code is collected from Oracle JavaSE Tutorial:

public class Beeper ... implements ActionListener {
...
//where initialization occurs:
    //notice this line
    button.addActionListener(this);
...
public void actionPerformed(ActionEvent e) {
    ...//Make a beep sound...
}
}

This is how you typically register a handler right ???

What this means here ???

    button.addActionListener(this);

It means ,call current object's (which this refers) *actionPerformed method whenever a action happens with that button object. So if you pass your MainPanel's reference instead of this and your main panel has a method actionPerformed and it implements ActionListener* , whenever button fires an event , your Mainwindows's *actionPerformed** will be called.

So changed this line like this :

    button.addActionListener(RefOfMainPanel);

That's all. Yup , it's that easy :)

MD. Sahib Bin Mahboob
  • 20,246
  • 2
  • 23
  • 45
0

Create your action listeners in the MainPanel and use the same in sub panels. The source of events should let you identify the sub panel from where the event is generated.

Sudhanshu Umalkar
  • 4,174
  • 1
  • 23
  • 33