Unexpected behaviour for dispatching events...

M

Mark

Hello Everyone.

I came across something weird while trying to understand event dispatching.
In short, I have designed a little form program in both Swing and AWT
versions where one button's event handler dispatches an event to another
button. The funny thing is that dispatching works fine in the AWT version
but does not in the Swing version. What's even spookier is that I've gotten
events to dispatch in other small programs using a Swing context. I just
don't know what to make of it. Below are the two programs in question.
Please note that I'm using the NetBeans IDE which arranges code in a very
specific way.

Any insight on this matter would be appreciated. Thanks.

Mark

//*******************************************
public class TestFormAWT extends java.awt.Frame {

/** Creates new form TestForm */
public TestFormAWT() {
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {
button1 = new java.awt.Button();
button2 = new java.awt.Button();

addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});

button1.setLabel("Button 1");
button1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
button1ActionPerformed(evt);
}
});

add(button1, java.awt.BorderLayout.NORTH);

button2.setLabel("Button 2");
button2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
button2ActionPerformed(evt);
}
});

add(button2, java.awt.BorderLayout.SOUTH);

pack();
}

private void button1ActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
System.out.println("Button 1 event processed.");
button2.dispatchEvent(new java.awt.event.ActionEvent(
button2, java.awt.event.ActionEvent.ACTION_PERFORMED, "Button
2"));
}

private void button2ActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
System.out.println("Button 2 event processed.");
}

/** Exit the Application */
private void exitForm(java.awt.event.WindowEvent evt) {
System.exit(0);
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
new TestFormAWT().show();
}


// Variables declaration - do not modify
private java.awt.Button button1;
private java.awt.Button button2;
// End of variables declaration

}
//*******************************************
public class TestFormSwing extends javax.swing.JFrame {

/** Creates new form TestFormSwing */
public TestFormSwing() {
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();

addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});

jButton1.setText("Button 1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

getContentPane().add(jButton1, java.awt.BorderLayout.NORTH);

jButton2.setText("Button 2");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});

getContentPane().add(jButton2, java.awt.BorderLayout.SOUTH);

pack();
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
System.out.println("Button 2 event processed.");
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
System.out.println("Button 1 event processed.");
jButton2.dispatchEvent(new java.awt.event.ActionEvent(
jButton2, java.awt.event.ActionEvent.ACTION_PERFORMED, "Button
2"));
}

/** Exit the Application */
private void exitForm(java.awt.event.WindowEvent evt) {
System.exit(0);
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
new TestFormSwing().show();
}


// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
// End of variables declaration

}
//*******************************************
 
A

A. Bolmarcich

Hello Everyone.

I came across something weird while trying to understand event dispatching.
In short, I have designed a little form program in both Swing and AWT
versions where one button's event handler dispatches an event to another
button. The funny thing is that dispatching works fine in the AWT version
but does not in the Swing version. What's even spookier is that I've gotten
events to dispatch in other small programs using a Swing context. I just
don't know what to make of it. Below are the two programs in question.
Please note that I'm using the NetBeans IDE which arranges code in a very
specific way.

Any insight on this matter would be appreciated. Thanks.

[programs snipped]

The basic problem is that AWT and Swing use incompatible approaches to
process ActionEvents. With both the AWT and Swing programs invoking
dispatchEvent(AWTEvent) invokes a method in java.awt.Component. That
method invokes processEvent(AWTEvent).

With the AWT program, invoking processEvent, invokes a method in
java.awt.Button that knows how to invoke the ActionListers that were
arguments of the addActionListener method of the same class.

With the Swing program, invoking processEvent, invokes a method in
java.awt.Component. There in no processEvent(AWTEvent) method in
JButton or its parent class AbstractButton where addActionListener
used for a JButton is. The processEvent method in java.awt.Component
knows nothing about the ActinListeners that were the arguments of the
the addActionListener method in AbstractButton.

An approach that can be used in the Swing program is to invoke
doClick(0) on the other JButton instead if dispatch Event.

Some events other than ActionEvents, such as ComponentsEvents, are
processed the same way by AWT and Swing because the event processing
is done within java.awt.component. ActionEvents are processed by
the some components that extend Component: Button, List, MenuItem,
and TextField. It is up to the processEvent(AWTEvent) method in those
classes to process action events.
 
M

Mark

A. Bolmarcich said:
The basic problem is that AWT and Swing use incompatible approaches to
process ActionEvents. With both the AWT and Swing programs invoking
dispatchEvent(AWTEvent) invokes a method in java.awt.Component. That
method invokes processEvent(AWTEvent).

With the AWT program, invoking processEvent, invokes a method in
java.awt.Button that knows how to invoke the ActionListers that were
arguments of the addActionListener method of the same class.

With the Swing program, invoking processEvent, invokes a method in
java.awt.Component. There in no processEvent(AWTEvent) method in
JButton or its parent class AbstractButton where addActionListener
used for a JButton is. The processEvent method in java.awt.Component
knows nothing about the ActinListeners that were the arguments of the
the addActionListener method in AbstractButton.

An approach that can be used in the Swing program is to invoke
doClick(0) on the other JButton instead if dispatch Event.

Some events other than ActionEvents, such as ComponentsEvents, are
processed the same way by AWT and Swing because the event processing
is done within java.awt.component. ActionEvents are processed by
the some components that extend Component: Button, List, MenuItem,
and TextField. It is up to the processEvent(AWTEvent) method in those
classes to process action events.

Thank you for the thorough explanation. After reading it, I revisited my
claim that I was able to successfully dispatch ActionEvents in a Swing
context. Not so, I observed one behaviour and misread it for another. I'm
relieved that my frustration was the result of design philosophy as opposed
to a missing semicolon. I suppose the only question is why Sun decided to
forgo ActionEvent dispatching in JButton. Regardless, I can move on now.

Again, thanks.
Mark
 
J

John C. Bollinger

Mark said:
Thank you for the thorough explanation. After reading it, I revisited my
claim that I was able to successfully dispatch ActionEvents in a Swing
context. Not so, I observed one behaviour and misread it for another. I'm
relieved that my frustration was the result of design philosophy as opposed
to a missing semicolon. I suppose the only question is why Sun decided to
forgo ActionEvent dispatching in JButton. Regardless, I can move on now.

Sun did not forgo ActionEvent dispatching in JButton. What they did was
to use a different event dispatching paradigm in Swing than in AWT.
Swing components inherit some event dispatching from AWT's Component and
Container classes, but for events not defined on those classes, Swing
classes use fireXXX methods to dispatch events instead of submitting
them to a central service and then overriding the processEvent event
demultiplexing method. I think the Swing technique is cleaner. With
reference to ActionEvents specifically, JButtons notify their listeners
of such by means of their fireActionPerformed(ActionEvent) method.


John Bollinger
(e-mail address removed)
 
Joined
Jan 12, 2011
Messages
1
Reaction score
0
I researched how to send custom events to a JFrame, and finally I succeeded in compiling some examples found on the web.

The functional result is visible here:

serge.coude.net/code-source/java.php5#java-MyEventDemo.java

Hoping that it might be useful!

Serge COUDÉ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top