|
| |
Given Java's producer/consumer delegation model, it is possible for:
- many consumers (listeners) to listen to a single producer
- a single consumer to listen to many producers
- both
Here's an example of a simple application that illustrates this.
Note
the following:
- The Create Frame button has a single listener --
MulticastPanel
- The Close All button has multiple listeners -- every
SimpleFrame
- The WindowListener,
m_windowListener, an instance member of
MulticastPanel, is a single listener that listens for window
closing events from every SimpleFrame.
package swingExamples;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* The main panel for the Multicaster main frame
*/
class MulticastPanel extends JPanel
implements ActionListener
{
public MulticastPanel()
{
m_newButton = new JButton("Create Frame");
m_newButton.addActionListener(this);
add(m_newButton);
m_closeAllButton = new JButton("Close All");
m_closeAllButton.setEnabled(false);
add(m_closeAllButton);
// Listens for SimpleFrames to close
m_windowListener = new WindowAdapter()
{
public void windowClosing(WindowEvent ev)
{
// One fewer SimpleFrame visible
if (--m_totalFrameCount == 0)
{
// Once there are no more SimpleFrames left,
// disable the Close All button.
m_closeAllButton.setEnabled(false);
}
}
};
}
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
if (source == m_newButton)
{
// Create Frame button click causes
// a SimpleFrame to be created
SimpleFrame frame = new SimpleFrame(++m_nextFrameNo);
// Keeps track of how many SimpleFrames
// are currently up.
m_totalFrameCount++;
// SimpleFrame listens for Close All button clicks.
m_closeAllButton.addActionListener(frame);
// At least one SimpleFrame up, so enable the
// Close All button.
m_closeAllButton.setEnabled(true);
// Listens for SimpleFrame to close
frame.addWindowListener(m_windowListener);
// Makes SimpleFrame visible
frame.setVisible(true);
}
}
/////////// Private data //////////
private JButton m_newButton;
private JButton m_closeAllButton;
private WindowListener m_windowListener;
private static int m_nextFrameNo = 0;
// Frame number for next frame
private static int m_totalFrameCount = 0;
// Count of frames currently visible
}
/**
* Frame to be displayed when user clicks on
* "Create Frame" button.
*/
class SimpleFrame extends JFrame
implements ActionListener
{
SimpleFrame(int frameNumber)
{
setSize(300, 200);
// Calculate an offset to locate the SimpleFrame
// on the screen
int offset = 30 * ( (frameNumber - 1) % 10);
setLocation(offset, offset);
// Give it a title
setTitle("Frame " + frameNumber);
}
public void actionPerformed(ActionEvent ev)
{
// This method is invoked by a Close All button click
// Make the frame invisible
setVisible(false);
// The above doesn't generate an event, so create one
// and dispatch it so that the window listener is informed
dispatchEvent(new WindowEvent(
this,
WindowEvent.WINDOW_CLOSING));
// Get rid of this frame's resources
dispose();
}
}
/**
* The "main" frame class
*/
class MulticastFrame extends JFrame
{
public MulticastFrame()
{
setTitle("MulticastTest");
setSize(100, 50);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.add(new MulticastPanel());
pack(); // Size, based on contents of frame
}
}
public class Multicaster
{
public static void main(String[] args)
{
MulticastFrame frame = new MulticastFrame();
frame.setVisible(true);
}
}
|
When the application starts, there are no SimpleFrames, and so the Close
All button is disabled:

When the Create Frame is clicked, a SimpleFrame is created and made
visible, and the Close All button is enabled. This continues as long as
there is at least one SimpleFrame visible.
When the last SimpleFrame is closed, the Close All button is once again
disabled.
Here's what the application looks like with a set of simple frames visible:

|