JMenu/JPopupMenu disappear on mouseEntered?

S

Sam Brightman

Hi,

Can anyone explain the following? First, I click on a JMenu and its
JPopupMenu appears full of JMenuItems. Next, click a JMenuItem that
launches another JDialog (or similar, here it's a FileDialog). When the
dialog is closed, click the JMenu again. The JPopupMenu displays.
However, when attempting to use the resulting JPopupMenu, it seems that
the mouseEntered event causes it to vanish. This requires the user to
move the mouse back over (no click) the JMenu to make the JPopupMenu
visible again (the second time it *is* usable). I've spent hours trying
to fix this simple but frustrating problem with no success. I'm sure it
must be simple but I can't find an answer on Google yet...

--
sam brightman

(To reply by e-mail use spam instead of ham and lose the jam)



import java.awt.FileDialog;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame {
public Test() {
JMenuBar jmb = new JMenuBar();
JMenu jm = new JMenu("Test");
JMenuItem jmi = new JMenuItem("test");
jmi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { load(); }
});
jm.add(jmi);
jmb.add(jm);
setJMenuBar(jmb);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
pack();
show();
}

public static void main(String[] argv) {
Test t = new Test();
}

public void load() {
FileDialog f=new FileDialog(this,"Open",FileDialog.LOAD);
f.show();
}
}
 
A

Andrew Thompson

....
Can anyone explain the following? First, I click on a JMenu and its
JPopupMenu appears full of JMenuItems.

Not in the code below it doesn't.
Did you cut and paste?

[ There is no JPopupMenu in the code ]
..Next, click a JMenuItem that
launches another JDialog (or similar, here it's a FileDialog).

Actually it is not similar - light and heavyweight components
do not mix, use a JFileChooser for this.

That may fix the problem, otherwise get us
the _complete_ self-contained, compileable
example of the problem.. ;-)
 
S

Sam Brightman

Andrew said:
Sam Brightman said:
Can anyone explain the following? First, I click on a JMenu and its
JPopupMenu appears full of JMenuItems.

Not in the code below it doesn't.
Did you cut and paste?

[ There is no JPopupMenu in the code ]

Well, it does really. I should have been clearer: although there is no
JPopupMenu in the code, one certainly appears: the anonymous one created
by the JMenu (?). This is what displays JMenuItems under a JMenu.
Actually it is not similar - light and heavyweight components
do not mix, use a JFileChooser for this.

Well, it's similar enough for this example! Again, I should have been
clearer - the same problem occurs with my JDialog derived classes. I
have read about the problem of mixing light and heavyweight components
and don't believe it to be the cause.
That may fix the problem, otherwise get us
the _complete_ self-contained, compileable
example of the problem.. ;-)

I did try ;) Maybe the code followed these guidelines but the
explanation did not... anyway here is the code using a JFileChooser:

import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame {
public Test() {
JMenuBar jmb = new JMenuBar();
JMenu jm = new JMenu("Test");
JMenuItem jmi = new JMenuItem("test");
jmi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { load(); }
});
jm.add(jmi);
jmb.add(jm);
setJMenuBar(jmb);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
pack();
show();
}

public static void main(String[] argv) {
Test t = new Test();
}

public void load() {
JFileChooser f=new JFileChooser();
f.showOpenDialog(this);
}
}
 
A

Andrew Thompson

I have to head off, but if nobody has discovered
the problem by the time I return I will have a
close look at your code.
 
S

Sudsy

Sam said:
I did try ;) Maybe the code followed these guidelines but the
explanation did not... anyway here is the code using a JFileChooser:

import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame {
public Test() {
JMenuBar jmb = new JMenuBar();
JMenu jm = new JMenu("Test");
JMenuItem jmi = new JMenuItem("test");
jmi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { load(); }
});
jm.add(jmi);
jmb.add(jm);
setJMenuBar(jmb);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
pack();
show();
}

public static void main(String[] argv) {
Test t = new Test();
}

public void load() {
JFileChooser f=new JFileChooser();
f.showOpenDialog(this);
}
}

Code tested with Java 1.4.2_02 on Linux kernel 2.2.16 showed
no abberant behaviour.
 
A

Andrew Thompson

Sam Brightman said:
import java.awt.event.*;
import javax.swing.*; .....
public class Test extends JFrame {
public Test() {
JMenuBar jmb = new JMenuBar();
JMenu jm = new JMenu("Test");
JMenuItem jmi = new JMenuItem("test");
jmi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { load(); }
});
jm.add(jmi);
jmb.add(jm);
setJMenuBar(jmb);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
pack();
show();
}

public static void main(String[] argv) {
Test t = new Test();
}

public void load() {
JFileChooser f=new JFileChooser();
f.showOpenDialog(this);
}
}

Interesting problem Sam.. I played with it and
observed exactly the behaviour you described.

Then I resized the frame, that solved the problem.

What I _think_ the problem here is that the app
is confused between whether the mouse pointer has
a) entered the sub-menu, _or_
b) left the application entirely.

Once the frame is made bigger the situation is
no longer in conflict, the mouse has definitely
entered the submenu.

Why this problem manifest itself the _first_ time
the menu is used after calling a Dialog ..I could make
a lot of things up, but am afraid I have no idea (shrugs).

My advice is to add a button, textfield, textarea..
anything to the frame - I can almost guarantee you
this behaviour will cease.

HTH
 
S

Sam Brightman

Andrew said:
Then I resized the frame, that solved the problem.

What I _think_ the problem here is that the app
is confused between whether the mouse pointer has
a) entered the sub-menu, _or_
b) left the application entirely.

Once the frame is made bigger the situation is
no longer in conflict, the mouse has definitely
entered the submenu.

Yes, it appears that resizing the frame does not in itself solve the
problem - what is important is that the mouse is inside the main frame
when the dialog closes.
Why this problem manifest itself the _first_ time
the menu is used after calling a Dialog ..I could make
a lot of things up, but am afraid I have no idea (shrugs).

I tried to start debugging this using the Eclipse debugger but can't
seem to get enough info about variables inside the libraries. I was
thinking it is a bug in the libraries but maybe with it being Windows
specific it is a JVM problem? Should we report it to Sun?
My advice is to add a button, textfield, textarea..
anything to the frame - I can almost guarantee you
this behaviour will cease.

Unfortunately, my real application already has a bunch of other stuff
and it doesn't help because the pointer is usually outside the main
frame when the dialogs close.

I'm going to try debugging this a little more and then post back what I
find. There is another, less annoying, problem that may well be related:
if you open the menu and then minimise the window it is not open when
the window is restored. However, the grey background of the popup is
still visible... Do you get this as well Andrew?

Has anyone else got any ideas on this? (P.S. Apologies if this should
have been posted to c.l.j.gui - my (mistaken) belief was that this group
was for general programming and c.l.j.gui was for GUI _design_. Would it
be acceptable to repost there?)
 
S

Sudsy

Andrew said:
...



$#?%! ^&*#$% #$ ()*)*@ Windoze!

A.

Andrew: don't be so quick to blame the platform. I wasn't aware that
the test involved trying it without resizing the window. Whenever I
get a window that tiny on my desktop I expand it, without even thinking,
so that I don't lose it in the backgound.
But a window with a menu bar and no content doesn't make much sense
to me.
 
S

Sam Brightman

Sudsy said:
Andrew: don't be so quick to blame the platform. I wasn't aware that
the test involved trying it without resizing the window. Whenever I
get a window that tiny on my desktop I expand it, without even thinking,
so that I don't lose it in the backgound.
But a window with a menu bar and no content doesn't make much sense
to me.

Sudsy, it's supposed to be the smallest test case (it doesn't have to
make sense!). My actual application has the same problem. It doesn't use
a huge window but it has a full JMenuBar and JTextArea etc. Could you
confirm that you get the problem on GNU/Linux if you don't resize? I
only have a Windows box up at the moment.
 
S

Sudsy

Sam said:
Sudsy, it's supposed to be the smallest test case (it doesn't have to
make sense!). My actual application has the same problem. It doesn't use
a huge window but it has a full JMenuBar and JTextArea etc. Could you
confirm that you get the problem on GNU/Linux if you don't resize? I
only have a Windows box up at the moment.

Well I'd be...
Fascinating! Just as you said, under 1.4.2_02 the menu disappear when
you try to move to it on the second invocation. Moving back to the
cascase button on the menu bar brings it back. I have multiple VMs
installed on my Linux box so I decided to try it out on 1.3.1 as well.
It works as expected on that version so it must have broken somewhere
in between. Have you checked the bug parade on Sun's site?
 
A

Andrew Thompson

Sudsy said:
...
Andrew: don't be so quick to blame the platform.

Never let the truth get in the way of a
good story, Sudsy! ;-)

[ But yeah, sounds like there is a lot more to this
quirky behaviour than I first thought.. ]

A.
 
A

Andrew Thompson

Sudsy said:
Well I'd be...
Fascinating! Just as you said, under 1.4.2_02 the menu disappear when
you try to move to it on the second invocation. Moving back to the
cascase button on the menu bar brings it back. I have multiple VMs
installed on my Linux box so I decided to try it out on 1.3.1 as well.
It works as expected on that version so it must have broken somewhere
in between.

Just to add a further nugget of info, my VM
version is 1.4.1_02-b06. So we can constrain
the introduction of this behaviour to the range
1.3 -> 1.4.1_02-b06..
 
A

Andrew Thompson

Sam Brightman said:
...
Yes, it appears that resizing the frame does not in itself solve the
problem - what is important is that the mouse is inside the main frame
when the dialog closes.

Not on my system. At least, here are my results..

Test using Dialog
The mouse does _not_ need to be inside the frame
when the dialog is dismissed - so long as the frame
has been resized (by so much as a few pixels) the
menu will appear reliably.

Test using JFileChooser
Rather baffling results..
- The menu needs two times when frame unresized.
- The menu needs two times when frame resized a
few pixels and dialog dismissed outside the frame
extent.
- The menu needs 1 time when the frame is so large
that the mouse is inside the frame bounds when
dialog dismissed. [ This agrees with your result ]
- but even more bizarre..
The mouse needs _1_ time when you
a) open a dilaog
b) drag it so the 'cancel' button is _outside_ the frame
c) cancel it.

Rather inconsistent behaviour, with no clear
distinction between the work and no work
situations.. :-/
 
S

Sam Brightman

Andrew said:
Just to add a further nugget of info, my VM
version is 1.4.1_02-b06. So we can constrain
the introduction of this behaviour to the range
1.3 -> 1.4.1_02-b06..

I'm on 1.4.2_01.
 
S

Sam Brightman

Andrew said:
Not on my system. At least, here are my results..

I suspect all previous results have been invalidated by something I
found tonight... read on. I have not checked Sun's site for the bug - I
followed a link there once about another bug and it looked like you
needed a subscription or some such thing. I do find it hard to believe
that no one else has seen this behaviour.
Test using Dialog
The mouse does _not_ need to be inside the frame
when the dialog is dismissed - so long as the frame
has been resized (by so much as a few pixels) the
menu will appear reliably.

Nope, it always works for me with a JDialog. I'm using a plain one with
just a title bar. However, nearly all my real dialogs are JDialog
derived and behave as below!
Test using JFileChooser
Rather baffling results..
- The menu needs two times when frame unresized.

Yes, subject to below.
- The menu needs two times when frame resized a
few pixels and dialog dismissed outside the frame
extent.

Umm.. not really. But *very* subject to below.
- The menu needs 1 time when the frame is so large
that the mouse is inside the frame bounds when
dialog dismissed. [ This agrees with your result ]

Not any more!
- but even more bizarre..
The mouse needs _1_ time when you
a) open a dilaog
b) drag it so the 'cancel' button is _outside_ the frame
c) cancel it.

Don't know.. by this point I was just confused!
Rather inconsistent behaviour, with no clear
distinction between the work and no work
situations.. :-/

Will first off, I'll agree with the "bizarre" part. Unfortunately I have
been unable to test over the weekend because I went to visit family (and
now I'm going to bed so I can't test any more!) Briefly, tonight I ran
through your tests only to find that my results (with JFileChooser)
started to contradict yours and my previous ones. The catch is that the
problem appears to be "sticky" in some way in that once it is working it
can stay working and once not it can stay not! I haven't had time yet to
figure out what precisely causes the state change but I think the
previous tests people have done might have been affected by the order in
which they were performed. The small amount of "debugging" I did on the
libraries may also be irrelevant of course, so the mouseEntered event
may not be the real trigger. I shall be back tomorrow....
 
A

Andrew Thompson

....
...The catch is that the
problem appears to be "sticky" in some way in that once it is working it
can stay working and once not it can stay not! I haven't had time yet to
figure out what precisely causes the state change but I think the
previous tests people have done might have been affected by the order in
which they were performed.

I'm coming to the conclusion that it is how you
hold your face as you click on it.. Either that or
it has something to do with animal sacrifice. ;-)
 
S

Sam Brightman

Andrew said:
I'm coming to the conclusion that it is how you
hold your face as you click on it.. Either that or
it has something to do with animal sacrifice. ;-)

Believe me, I considered it. After spending a few hours messing around
in the Java runtimes with the Eclipse debugger I had narrowed it down to
a bug in the event handling. Essentially, either one of two things
appeared to be happening: either the event dispatcher was sending a
MOUSE_EXIT event when it shouldn't or someone was forgetting to null the
targetLastEntered variable in the enter/exit handler when launching
another dialog. mouseExited on the JMenuItem removes the last item from
the selectedPath so this vanishes the popup.

Finally I gave up and conceded my personal information to Sun. The bug
is already on their bug parade (it is unique to modal dialogs
apparently) and our detective work seems accurate. It is marked fixed
for 1.5 and a work around is provided. Yey! Now I only wish I'd checked
earlier or thought of the obvious work-around... simply override the
mouseExited to make sure that the last item on selectedPath isn't a
JPopupMenu and then do a UIManager.put("MenuItemUI", "YourClass").
 
A

Andrew Thompson

Sam Brightman said:
Andrew Thompson wrote: ...
Finally I gave up and conceded my personal information to Sun. The bug
is already on their bug parade (it is unique to modal dialogs
apparently) and our detective work seems accurate. It is marked fixed
for 1.5 and a work around is provided. Yey!

Thanks for getting back to us Sam.
...Now I only wish I'd checked
earlier or thought of the obvious work-around... simply override the
mouseExited to make sure that the last item on selectedPath isn't a
JPopupMenu and then do a UIManager.put("MenuItemUI", "YourClass").

Live, learn. :)
 

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,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top