Link to home
Start Free TrialLog in
Avatar of zzynx
zzynxFlag for Belgium

asked on

Pressing <Enter> differs from pressing <Space Bar> on a focused button

Hi experts,

I have created a wizard panel containing 6 pages.
The panel has a <Previous> and a <Next> button to browse through the pages.
Simple ActionListener's are listening to the pressing of those two buttons.

Problem:
I'm on the 1st page and I tab to give the <Next> button the focus.
Now, when I press the space bar I jump to the 2nd page.
However, when I press <Enter> I jump to the 3rd page. (pressing again brings me to the 5th page)

What happens?
I think when I press <Enter> I jump to the next page and then for some reason
the <Next> button is triggered again, so it brings me in fact two pages further.

Somebody knows any solution or workaround?
Thanks in advance.
Avatar of appxpete
appxpete

Can you post some of your code.  Specifically the code that processes the Next button event.
Avatar of Mick Barry
space will activate the focussed button
enter will activate the default button

add some debug to detemine what events are getting fired
Avatar of zzynx

ASKER

Nothing special in there:

    nextFinishButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextFinishButtonActionPerformed(evt);
            }
        });

    private void nextFinishButtonActionPerformed(java.awt.event.ActionEvent evt) {
        if ( nextFinishButton.getText().equals(
                UserEnvironment.getDefault().getTranslation("next") ) )
            next();     // <<<<<<< Is performed twice when <Enter> is pressed. Once when space bar is pressed
        else
            finish();
    }
try setting the default button

and post the stack traces for the three events getting fired.

Try making this mod and see what events are being fired.  You don't seem to be checking, just blindly processing next() on any event.

    private void nextFinishButtonActionPerformed(java.awt.event.ActionEvent evt) {
System.err.println("nextFinishButtonActionPerformed() event="+evt);
        if ( nextFinishButton.getText().equals(
                UserEnvironment.getDefault().getTranslation("next") ) )
            next();     // <<<<<<< Is performed twice when <Enter> is pressed. Once when space bar is pressed
        else
            finish();
    }
Avatar of zzynx

ASKER

>> add some debug to detemine what events are getting fired
I added the line
      System.out.println("ID = " + evt.getID() + " paramString = " + evt.paramString());

in the function nextFinishButtonActionPerformed()

I get:

When <Enter> is pressed:
ID = 1001 paramString = ACTION_PERFORMED,cmd=Next,when=1149083188829,modifiers=
ID = 1001 paramString = ACTION_PERFORMED,cmd=Next,when=1149083188829,modifiers=
When <Space> is pressed:
ID = 1001 paramString = ACTION_PERFORMED,cmd=Next,when=1149083210790,modifiers=
When <Enter> is pressed:
ID = 1001 paramString = ACTION_PERFORMED,cmd=Next,when=1149083215397,modifiers=
ID = 1001 paramString = ACTION_PERFORMED,cmd=Next,when=1149083215397,modifiers=

>> try setting the default button
How? It's a JPanel

>> and post the stack traces for the three events getting fired.
three events?
You need to get the Root Pane from your JFrame to set the default button.

JRootPane.setDefaultButton(javax.swing.JButton)
> How? It's a JPanel

you set it on the root pane that contains the panel

> three events?

the one when space is pressed
and two when enter is pressed

You could also try calling the evt.consume() method right before you call the next() function.  That should stop the event from being propigated after you processed it.
Avatar of zzynx

ASKER

>> You could also try calling the evt.consume() method right before you call the next() function.
Compile Error: consume() has protected access in java.awt.AWTEvent
Avatar of zzynx

ASKER

Problem solved!

The panel was wrapped in an EscDialog (extending JDialog) to make it disappear when <Escape> is pressed.
That EscDialog also captured the pressing of the <Enter> key.
And in this specific case, this code was performed:

        DefaultKeyboardFocusManager kfMgr = new DefaultKeyboardFocusManager();
        Component compFocused = kfMgr.getFocusOwner();

        if (compFocused instanceof JButton) {
            ((JButton)compFocused).doClick();
        }

So, this triggered the <Next> button for a second time besides the normal trigger.
You couldn't know all that ;°)
Nevertheless, thanks for trying to help me. Appreciated.

I'll ask for a delete of this one.
> That EscDialog also captured the pressing of the <Enter> key.

Thats because it is the default problem as I mentioned earlier.
The stack trace would have shown it up.

I explained what the reason was, and suggested diagnostics to determine the cause.
Avatar of zzynx

ASKER

>> Thats because it is the default problem as I mentioned earlier.
>> I explained what the reason was
Incorrect. That EscDialog really contained code I wrote myself to capture the Enter key.
If that code wouldn't have been there, pressing <Enter> or <Space bar> would have been exactly the same.

So
>> space will activate the focussed button
>> enter will activate the default button
was not the explanation.
And here's a little demo program to prove:

No matter how I trigger the (default!) <Increment> button the counter always increment once.

ButtonTest.java
------------------
/**
 *
 * @author  zzynx
 */
public class ButtonTest extends javax.swing.JFrame {
   
    private int counter = 1;
   
    /** Creates new form ButtonTest */
    public ButtonTest() {
        initComponents();
        updateInfo();
        getRootPane().setDefaultButton(incButton);
    }
   
    private void updateInfo() {
        theLabel.setText("Counter is " + counter);
    }
   
    /** 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() {
        centerPanel = new javax.swing.JPanel();
        theLabel = new javax.swing.JLabel();
        southPanel = new javax.swing.JPanel();
        buttonPanel = new javax.swing.JPanel();
        decButton = new javax.swing.JButton();
        incButton = new javax.swing.JButton();

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

        theLabel.setText("jLabel1");
        centerPanel.add(theLabel);

        getContentPane().add(centerPanel, java.awt.BorderLayout.CENTER);

        southPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));

        decButton.setText("Decrement");
        decButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                decButtonActionPerformed(evt);
            }
        });

        buttonPanel.add(decButton);

        incButton.setText("Increment");
        incButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                incButtonActionPerformed(evt);
            }
        });

        buttonPanel.add(incButton);

        southPanel.add(buttonPanel);

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

        pack();
    }

    private void incButtonActionPerformed(java.awt.event.ActionEvent evt) {
        counter++;
        updateInfo();
    }

    private void decButtonActionPerformed(java.awt.event.ActionEvent evt) {
        counter--;
        updateInfo();
    }
   
    /** 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[]) {
        // Set the system's Look & Feel
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) {}
       
        ButtonTest frame = new ButtonTest();
        frame.setLocationRelativeTo(null);
        frame.show();
    }
   
    // Variables declaration - do not modify
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JPanel centerPanel;
    private javax.swing.JButton decButton;
    private javax.swing.JButton incButton;
    private javax.swing.JPanel southPanel;
    private javax.swing.JLabel theLabel;
    // End of variables declaration
   
}
Avatar of zzynx

ASKER

So as I said, I appreciate you both were trying to help me.
But, as Venabili always says, points are for answers.

And doing a strack trace of the event being fired as I suggested would have made it obvious where the events whetre getting generated from. Its not always answers that solve problems :)

ASKER CERTIFIED SOLUTION
Avatar of ee_ai_construct
ee_ai_construct
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Muy recomendantion appears to have been ignored. My suggestion to check the stack trace would have pointed immediately to the cause of the problem.