aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes One strange question about listener Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "One strange question about listener" Watch "One strange question about listener" New topic
Author

One strange question about listener

walter wang
Ranch Hand

Joined: Jun 02, 2001
Posts: 154
My question is ::
I regiester windowsEvent two times
one is from baseclass JFrame( all windowsEvent will be
caught and process by processWindowEvent which is
JFrame's method
second i register windows by a anonymous class in line 94)
why if i comment out CallInterface.java line 105
then line 97 will not be invoked when window was closed,
only line 106 will be invoked?
thx for attention
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CallInterface extends JFrame {
JPanel contentPane;
JPanel jPanel1 = new JPanel();
//jpanel1 contains jpanel1a,
//jpanel1a contains jpanel1aa,jpanel1ab,jPanel1ac jpanelaa
//add label,jpanelab add label and textfields jpanelac add
//label and textfields
JPanel jPanel1a= new JPanel(new BorderLayout());
JPanel jPanel1aa=new JPanel();
JPanel jPanel1ab=new JPanel();
JPanel jPanel1ac=new JPanel();
JLabel label=new JLabel("Please Enter IP address and Port Number ");
JLabel audiolabel=new JLabel("Audio");
JLabel vediolabel=new JLabel("Vedio");
JLabel portlabel1 = new JLabel("Port");
JLabel portlabel2 = new JLabel("Port");
JTextField jTextField1 = new JTextField(5);
JTextField jTextField2 = new JTextField(5);
JTextField jTextField3 = new JTextField(5);
JTextField jTextField4 = new JTextField(5);
JTextField jTextField5 = new JTextField(5);
JPanel jPanel2 = new JPanel(new BorderLayout());
JTextField jTextField6 = new JTextField(5);
JTextField jTextField7 = new JTextField(5);
JTextField jTextField8 = new JTextField(5);
JTextField jTextField9 = new JTextField(5);
JTextField jTextField10 = new JTextField(5);
JPanel jPanel3 = new JPanel();
JButton jButton1 = new JButton();
JButton jButton2 = new JButton();
/**Construct the frame*/
public CallInterface() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
setVisible(true);
}
catch(Exception e) {
e.printStackTrace();
}
}
/**Component initialization*/
private void jbInit() throws Exception {
//setIconImage(Toolkit.getDefaultToolkit().createImage(Frame1.class.getResource("[Your Icon]")));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(new BorderLayout());
this.setSize(new Dimension(450, 500));
this.setTitle("Call Setting Interface");
jButton1.setText(" Connect ");
contentPane.add(jPanel1, BorderLayout.NORTH);
contentPane.add(jPanel2, BorderLayout.CENTER);
contentPane.add(jPanel3, BorderLayout.SOUTH );
jPanel1.add(jPanel1a);
jPanel1a.add(jPanel1aa,BorderLayout.NORTH);
jPanel1a.add(jPanel1ab,BorderLayout.CENTER);
jPanel1a.add(jPanel1ac,BorderLayout.SOUTH);
jPanel3.add(jButton1, null);
jPanel2.add(new CallTabbedPane(), BorderLayout.CENTER);
//jPanel2.setSize(400,300);
jPanel1a.add(jPanel1aa, BorderLayout.NORTH);
jPanel1a.add(jPanel1ac, BorderLayout.SOUTH);
jPanel1aa.add(label);
jPanel1ab.add(vediolabel);
jPanel1ab.add(jTextField1, null);
jPanel1ab.add(jTextField2, null);
jPanel1ab.add(jTextField3, null);
jPanel1ab.add(jTextField4, null);
jPanel1ab.add(portlabel2, null);
jPanel1ab.add(jTextField5, null);
jPanel1ac.add(audiolabel, null);
jPanel1ac.add(jTextField6, null);
jPanel1ac.add(jTextField7, null);
jPanel1ac.add(jTextField8, null);
jPanel1ac.add(jTextField9, null);
jPanel1ac.add(portlabel1, null);
jPanel1ac.add(jTextField10, null);

addWindowListener // Line 94
(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing was invoked");//line 97
e.getWindow().dispose();
}
});
}
protected void processWindowEvent(WindowEvent e) {
//if commenet out this line,why windowClosing method will not be invoke?
super.processWindowEvent(e);//line 105
System.out.println("processWindowEvent was invoked");//line 106
}
public static void main(String args[]){
new CallInterface();
}
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* @version 1.1 06/02/99
*/
public class CallTabbedPane extends JPanel {
public CallTabbedPane() {
setLayout(new BorderLayout());
UIManager.put("TabbedPane.selected",null);
JTabbedPane tabbedPane = new JTabbedPane();
String tabs[] = {"Vedio", "Audio"};
Color[] colors = {null, null};
for (int i=0;i<tabs.length;i++) {>
tabbedPane.addTab(tabs, createPane(tabs));
tabbedPane.setBackgroundAt(i, colors);
}
tabbedPane.setSelectedIndex(0);
add(tabbedPane, BorderLayout.CENTER);
//setSize(350,250);
}
JPanel createPane(String s) {
JPanel p = new JPanel();
p.add(new JLabel(s));
return p;
}
}


public class Walter { public boolean is_Working_Now (boolean is_boss_Coming) { return is_boss_Coming; }
Sean MacLean
author
Ranch Hand

Joined: Nov 07, 2000
Posts: 621
Walter,
I think you may have more luck with this question in the Swing... forum so I'm moving you post there.
Sean
Manfred Leonhardt
Ranch Hand

Joined: Jan 09, 2001
Posts: 1492
Hi Walter,
That is because you are overriding the processWindowEvent method. The default functionality is to notify all the component's registered listeners. Since you are overridding that functionality and not performing it the windowClosing method will not be called. By calling the parent processWindowEvent you are restoring the default functionality.
It is not normal to override processXXXXEvent methods unless you want to change the default behavior or have some need to be the first to know when an event is about to happen.
Regards,
Manfred.
walter wang
Ranch Hand

Joined: Jun 02, 2001
Posts: 154
Originally posted by Manfred Leonhardt:
Hi Walter,
That is because you are overriding the processWindowEvent method. The default functionality is to notify all the component's registered listeners. Since you are overridding that functionality and not performing it the windowClosing method will not be called. By calling the parent processWindowEvent you are restoring the default functionality.
It is not normal to override processXXXXEvent methods unless you want to change the default behavior or have some need to be the first to know when an event is about to happen.
Regards,
Manfred.

Dear Manfred
Thx for your explaination
yeah i checked processWindowEvent in java.awt.Window.java
After analyse code i find ,if i close window
processWindowEvent will notify all reigestered windowsListerner
by windowListener.windowClosing(e);
but if i subclass(CallInterface.java) i register
two WindowsListerners , so when i close windows
two WindowsListerners will be notified
but look code
windowListener.windowClosing(e), seems only could notify
one windowListener
i check windowListener in java.awt.Window.java
it is transient (transient WindowListener windowListener
How does it work out?
just declaring windowListener as transient
then by calling windowListener.windowClosing(e)
then it will notfiy all the registered WindowListeners
just by one line ?
regards
protected void processWindowEvent(WindowEvent e) {
if (windowListener != null) {
switch(e.getID())
case WindowEvent.WINDOW_OPENED:
windowListener.windowOpened(e);
break;
case WindowEvent.WINDOW_CLOSING:
windowListener.windowClosing(e);
break;
Manfred Leonhardt
Ranch Hand

Joined: Jan 09, 2001
Posts: 1492
HI,
It works because of what WindowListener is declared as. It has nothing to do with being transient or not.
WindowListener is declared as an AWTEventMulticaster which simply put is a vector or AWTEvent listeners. That is why one call does it all!
See here for the API:
http://java.sun.com/products/jdk/1.2/docs/api/java/awt/AWTEventMulticaster.html
Check out the java.awt.Window method addWindowListeners to see how it is used.
Regards,
Manfred.
[This message has been edited by Manfred Leonhardt (edited November 19, 2001).]
walter wang
Ranch Hand

Joined: Jun 02, 2001
Posts: 154
Originally posted by Manfred Leonhardt:
HI,
It works because of what WindowListener is declared as. It has nothing to do with being transient or not.
WindowListener is declared as an AWTEventMulticaster which simply put is a vector or AWTEvent listeners. That is why one call does it all!
See here for the API:
http://java.sun.com/products/jdk/1.2/docs/api/java/awt/AWTEventMulticaster.html
Check out the java.awt.Window method addWindowListeners to see how it is used.
Regards,
Manfred.
[This message has been edited by Manfred Leonhardt (edited November 19, 2001).]

Dear Manfred thx for your hints, follow your hints
i explore a little bit, i 'd like to share my explored
result with everyone.
Window.java has one method processWindowEvent
has a transient WindowListener windowListener;
/* Window.java
if u did set enableWindowEvent to ture,then when WindowEvent ocurring
processWindowEvent will send WindowEvent to the registered WindowEvent listeners
example.if WindowEvent.WINDOW_CLOSING:
it will call windowListener.windowClosing(e),by calling this,
all registered listeners, what ever how many, all will be notified.
When u closing Window how does windowListener.windowClosing(e) will notify all registered listners just by one line code?
Now we discuss what is the machanisim behind it.
//Window 's method
protected void processWindowEvent(WindowEvent e) {
if (windowListener != null) {
switch(e.getID()) {
case WindowEvent.WINDOW_OPENED:
windowListener.windowOpened(e);
break;
case WindowEvent.WINDOW_CLOSING:
windowListener.windowClosing(e);
break;
// Window 's method
public synchronized void addWindowListener(WindowListener l) {
if (l == null) {
return;
}
windowListener = AWTEventMulticaster.add(windowListener, l);
....
}
*/
So if you have a SubWindow extends Window
in SubWindow's constructor you regsiter 3 different listerners
like this
public SubWindow(){
addWindowListener(listernerA);
addWindowListener(listernerB);
addWindowListener(listernerC);
....
}
so you will call 3 times addWindowListener method in Window.java
first time you call addWindowListener
windowListener(variable in Window.java)= listenerA;
second time
windowListener= new AWTEventMulticaster(frist time's windowListener,listenerB);
third time
windowListener= new AWTEventMulticaster(second time'swindowListener,listenerC);
for details you should check AWTEventMulticaster.java
when u closing SubWindow
you will invoke Window.java's processWindowEvent'method's line windowListener.windowClosing(e);
at this time windowListener is new AWTEventMulticaster(second time'swindowListener,listenerC);
you could take it as new AWTEventMulticaster(new AWTEventMulticaster(listenerA,listenerB),listenerC);
so at this moment calling windowListener.windowClosing(e) will invoke AWTEventMulticaster's
windowClosing method firstly,
then it was invoking like this
//AWTEventMulticaster' method
public void windowClosing(WindowEvent e) {
//actually(WindowListener)new AWTEventMulticaster(listenerA,listenerB) is still AWTEventMulticaster type
// so it will recursively invoke AWTEventMultcaster's windowClosing method until it was decompressed to
// listenerA and listenerB,then will invoke listenerA and listenerB's own windowClosing method seperately
((WindowListener)new AWTEventMulticaster(listenerA,listenerB) ).windowClosing(e);

//inovke it's self 's windowClosing(e) in this case. invoke listenerC's windowClosing()
((WindowListener)listenerC).windowClosing(e);//because it is not AWTEventMulticaster type anymore,so it will

}
but this way. you could register any listeners to Window.java , then in Window.java's
by simply calling windowListener.windowClosing(e) once, it will invoke all listeners windowClosing methods
/ ****************** AWTEventMulticaster.java 's method*******************
protected AWTEventMulticaster(EventListener a, EventListener b) {
this.a = a; this.b = b;
}
public static WindowListener add(WindowListener a, WindowListener b) {
return (WindowListener)addInternal(a, b);
}
protected static EventListener addInternal(EventListener a, EventListener b) {
if (a == null) return b;
if (b == null) return a;
return new AWTEventMulticaster(a, b);
}
public void windowClosing(WindowEvent e) {
((WindowListener)a).windowClosing(e);
((WindowListener)b).windowClosing(e);
}
*******************************************************************/
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: One strange question about listener