JDK-4546712 : JCK1.4/1.3a, interactive:api/javax_swing/interactive/JMenuItemTests.html fails
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0,1.4.1
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: x86,sparc
  • Submitted: 2001-12-05
  • Updated: 2002-06-12
  • Resolved: 2002-04-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.1 hopperFixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The testcase JMenuItemTest0003 verifies menemonic behavior of JMenuItem(String, int) constructor.

However, menu items does not response to mnemonic keys when menu overlaps test's frame,
and mouse pointer is placed over any item in the menu.

JDK            : jdk1.4.0-b88, JDK 1.4.1-b10
JCK            : JCK1.4-b14
Platform[s]    : RedHat Linux 6.2, Caldera 2.4, RedHat Linux 7.1, sparc sol7/8/9
switch/Mode    : -client -Xmixed
JCK test owner : http://javaweb.eng/jck/usr/owners.jto
Failing Test   : api/javax_swing/interactive/JMenuItemTests.html#JMenuItem [JMenuItemTest0003]

Test source location:
=====================
/net/jdk/export/disk8/local.java/jck1.4/JCK-runtime-14/tests/api/javax_swing/interactive/JMenuItemTests.java

jtr file location:
==================
/net/jtgb4u4c.eng/export/sail15/results/merlin/b88/jck13a/linux/caldera_single_kde_client_linux-7/workDir/api-interactive/javax_swing/interactive/JMenuItemTests_JMenuItem.jtr

How to reproduce:
=================
1. Run the following script (you may need to change JCK and JAVA_HOME paths)
2. Shrink test frame to make menu to ovrlap the frame when menu is opened
3. Press Alt+m to open menu
4. Place mouse pointer over any of menu's items 
5. Press 1
6. Press Esc.

You will see that menu does not respond to keyboard.

--------Script START---------------------
#!/bin/sh

JCK=/net/jdk/export/disk8/local.java/jck1.4/JCK-runtime-14
export JCK
CLASSPATH="${JCK}/classes:${JCK}/javatest.jar"
export CLASSPATH
JAVA_HOME=/net/jdk/export/disk8/local.java/jdk1.4/linux-i386
export JAVA_HOME

$JAVA_HOME/bin/java -showversion -Xfuture         javasoft.sqe.tests.api.javax.swing.interactive.JMenuItem.JMenuItemTests         -TestCaseID JMenuItemTest0003         -TestDirURL file:///$JCK/tests/api/javax_swing/interactive/JMenuItemTests.html#JMenuItem

--------Script END----------------------

Test output:
============
JMenuItemTest0003: Failed. JMenuItem setMnemonic() does not behave as expected.

Specific Machine Info:
======================
Hostname: linux-12
OS: Redhat 6.2/KDE

Hostname: linux-7
OS: Caldera 2.4/KDE

Hostname: jtg-linux13
OS: RedHat 7.1/Gnome

==========================================================================
This bug appears in hopper b10 on sparc machines, too.
I followed the "how to reproduce" procedure as described above and reproduced the bug in hooper.  It fails when mouse is set to "point-to-focus" and passes with "click-to-focus" setting of mouse.

Specific Machine Info:
SunOS jtg-s118 5.7 Generic_106541-20 sun4u sparc SUNW,Ultra-2
SunOS jtg-s120 5.8 Generic sun4u sparc SUNW,Ultra-60
SunOS jtg-s113 5.9 s81_56 sun4u sparc SUNW,Ultra-2

###@###.### 2002-05-06
==========================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: hopper FIXED IN: hopper INTEGRATED IN: hopper VERIFIED IN: hopper
24-08-2004

EVALUATION Name: pzR10082 Date: 12/05/2001 Here's a simplified test that can be used to reproduce this bug. Just open the menu and try pressing up and down arrow keys: import javax.swing.*; public class bug4546712 { public static void main(String args[]) { JMenu menu = new JMenu("File"); menu.add(new JMenuItem("Open...")); menu.add(new JMenuItem("Save...")); menu.add(new JMenuItem("Exit")); JMenuBar mbar = new JMenuBar(); mbar.add(menu); mbar.add(new JLabel(" ")); JFrame frame = new JFrame("Bug 4546712"); frame.setJMenuBar(mbar); frame.pack(); frame.setVisible(true); } } This code works with beta86. With betas 87 and 88, arrow keys only work when mouse pointer is inside the frame and not over the menu popup. When mouse pointer is placed over the popup or outside the frame, pressing keys generates no key events at all. ###@###.### 2001-12-05 ====================================================================== Name: pzR10082 Date: 12/05/2001 This bug exists on Linux and Solaris, but not on Windows. ###@###.### 2001-12-05 ====================================================================== This is already logged as 4530925, closing as a dupliate. ###@###.### 2001-12-05 Name: dmR10075 Date: 12/14/2001 I am unable to reproduce the bug on RH with Gnome using b89 when focus policy is Click-to-focus. On Point-to-focus it surely will not work if mouse is out of Frame - window manager will not send any key events to us. If mouse is in the frame it works fine. If you point the menu using the mouse you make it _focused_ while in our design Windows (not Frames) are not destined to become focused, instead Frame should track focus for them. This contradication causes the behaviour you described however this problem doesn't deserve to be called showstopper - if user pointed the menu by mouse he with a big chance will click it with mouse and this is an acceptable workaround. On KDE when menu overlaps frame Frame loses the focus. When Frame loses focus any other key events processing becomes impossible. This looks like a bug and could be filed for further investigation, however I want to highlight that we don't officially support KDE: by default everything should work similiarly on Gnome and KDE, and it does, but if something doesn't work on KDE in particular we don't investigate it except it is something very horrible. ###@###.### 12-14-2001 ====================================================================== Name: dmR10075 Date: 12/16/2001 I found the cause of the Point-to-focus problem. When user moves mouse into the menu it becomes focused. AWT send correct event about it - FOCUS_LOST for focus owner, WINDOW_LOST_FOCUS for JFrame, WINDOW_GAINED_FOCUS for HeavyweightPopupWindow - menu's underlaying window. However, this window is not focusable so after that focus owner is null. Popup's window is not focusable because of two reasons - it was made so by call to setFocusableWindowState(false) from constructor (Popup.java:206 and because it has empty focys cycle. Focus cycle is empty because the component which may become focus owner - JPopupMenu - is also made non-focusable by the call to setFocusable(false) from BasicPopupMenuUI.java:60. After I modified the code: 1) commented setFocusableWindowState(false) - Popup.java:260 2) commented setFocusable(false) - BasicPopupMenuUI.java:60 3) added setFocusable(true) to JPopupMenu contructor problem disappeared. I'm still investigating problem with KDE. So far I found that it depends on version of KDE - on some versions the problem is not reproducible. ###@###.### 12-17-2001 ====================================================================== Name: dmR10075 Date: 12/16/2001 After I applied the changes proposed above to the code KDE problem has also disappeared. ###@###.### 12-17-2001 ====================================================================== As Peter mentions, this worked with 86, but not 87. I tried running with the swing class files in 87 on 86 and the problem did not exist, which seems to imply there was a focus change somewhere else that triggered this outside of swing. ###@###.### 2001-12-18 We are expecting the window not to cause a focus change, and the spec indicates this is possible. As a focus change is happening, and the bug appears to be the result of an awt change, I am reassigning to awt. We will continue investigating a workaround on our side. ###@###.### 2001-12-19 JCK has agreed to put this on the exclude list. Downgrading and comitting to Hopper. ###@###.### 2001-12-21 Name: dmR10075 Date: 04/05/2002 We agree that Swing may expect non-focusable Window to not receive any focus events and to not cause focus changes to the owning frame so we made some change in AWT specifically for Swing and this bug which will make all the Swing popups truly non-focusable. See suggested fix for details. ###@###.### 2002-05-04 ====================================================================== Name: dmR10075 Date: 05/21/2002 The bug is reproducible with b11 on Sawfish WM (Linux) with point-to-focus focus policy, with 'enter-exit' sub-option. This option is WM specific and user settings specific - the user can instead set 'enter-only' sub-option (which is equivalent to how other WMs implement point-to-focus). 'enter-only' mode is still point-to-focus and bug is not reproducible in this mode. So, the problem is too specific and it is questionable should we support this or not. After discussing this issue with Igor Chebykin(###@###.###) we decided to file a new bug for Mantis for this issue and leave 4546712 intact. We will try (if at all possible) to fix this issue in Mantis. ###@###.### 2002-05-21 ======================================================================
21-05-2002

SUGGESTED FIX Name: dmR10075 Date: 04/05/2002 We create the windows which are used by the Swing for heavy-weight popups with override_redirect flag as true, as the result they behave like truly non-focusable windows. All other windows (including marked non-focusable) are created as usual. To distinguish between Swing and non-swing Windows we use name property of the window, it should be set to '###overrideRedirect###' to make window behave as non-focusable. This change affects the following Swing components: Tooltip, ComboBox, PopupMenu, Menu, general heavyweight Popup. Below are the partial diffs (only most meaningful deltas): *** /tmp/geta1512 Mon Mar 4 17:40:24 2002 --- Popup.java Mon Mar 4 17:37:45 2002 *************** *** 201,206 **** --- 201,207 ---- HeavyWeightWindow(Window parent) { super(parent); setFocusableWindowState(false); + setName("###overrideRedirect###"); } public void update(Graphics g) { *************** *** 2029,2045 **** AwtGraphicsConfigDataPtr defConfig; jobject gd = NULL; jobject gc = NULL; - #ifdef __linux__ char *cname; jstring jname; - #endif AWT_LOCK(); target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target); if (JNU_IsNull(env, target)) { ! JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } --- 2123,2137 ---- AwtGraphicsConfigDataPtr defConfig; jobject gd = NULL; jobject gc = NULL; char *cname; jstring jname; AWT_LOCK(); target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target); if (JNU_IsNull(env, target)) { ! JNU_ThrowNullPointerException(env, "null target"); AWT_UNLOCK(); return; } *************** *** 2189,2201 **** XtSetArg(args[argc], XmNtransient, True); argc++; XtSetArg(args[argc], XmNtransientFor, parent_widget); argc++; - #ifdef __linux__ /* Fix Forte Menu Bug. If Window name is "###overrideRedirect###", * then set XmNoverrideRedirect to prevent Menus from getting focus. * In JDK 1.2.2 we created Windows as xmMenuShellWidgetClass, * so we did not need to do this. Swing DefaultPopupFactory's * createHeavyWeightPopup sets Window name to "###overrideRedirect###". */ jname = (*env)->GetObjectField(env, target, componentIDs.name); if (!JNU_IsNull(env, jname)) { cname = (char *)JNU_GetStringPlatformChars(env, jname, NULL); --- 2281,2296 ---- XtSetArg(args[argc], XmNtransient, True); argc++; XtSetArg(args[argc], XmNtransientFor, parent_widget); argc++; /* Fix Forte Menu Bug. If Window name is "###overrideRedirect###", * then set XmNoverrideRedirect to prevent Menus from getting focus. * In JDK 1.2.2 we created Windows as xmMenuShellWidgetClass, * so we did not need to do this. Swing DefaultPopupFactory's * createHeavyWeightPopup sets Window name to "###overrideRedirect###". */ + /** + * Fix for 4476629. Allow Swing to create heavyweight popups which will + * not steal focus from Frame. + */ jname = (*env)->GetObjectField(env, target, componentIDs.name); if (!JNU_IsNull(env, jname)) { cname = (char *)JNU_GetStringPlatformChars(env, jname, NULL); *************** *** 2208,2215 **** } } (*env)->DeleteLocalRef(env, jname); - #endif - } DASSERT(!(argc > MAX_ARGC)); wdata->winData.shell = XtCreatePopupShell(shell_name, shell_class, --- 2303,2308 ---- *** /tmp/geta944 Tue Apr 2 21:25:47 2002 --- BasicPopupMenuUI.java Tue Apr 2 21:25:43 2002 *************** *** 184,190 **** private transient static MouseGrabber mouseGrabber = null; private static class MouseGrabber ! implements MouseListener, MouseMotionListener, MouseWheelListener, WindowListener,ComponentListener, ChangeListener { Vector grabbed = new Vector(); MenuElement lastGrabbed = null; --- 184,190 ---- private transient static MouseGrabber mouseGrabber = null; private static class MouseGrabber ! implements MouseListener, MouseMotionListener, WindowFocusListener, MouseWheelListener, WindowListener,ComponentListener, ChangeListener { Vector grabbed = new Vector(); MenuElement lastGrabbed = null; *************** *** 303,308 **** --- 303,309 ---- if(c instanceof java.awt.Window) { ((java.awt.Window)c).addWindowListener(this); ((java.awt.Window)c).addComponentListener(this); + ((java.awt.Window)c).addWindowFocusListener(this); grabbed.addElement(c); } synchronized(c.getTreeLock()) { *************** *** 332,337 **** --- 333,339 ---- cpn = (Component)grabbed.elementAt(i); if(cpn instanceof java.awt.Window) { ((java.awt.Window)cpn).removeWindowListener(this); + ((java.awt.Window)cpn).removeWindowFocusListener(this); ((java.awt.Window)cpn).removeComponentListener(this); } else { cpn.removeMouseListener(this); *************** *** 402,417 **** } public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) { - /* cancelPopupMenu(); cannot do this because - this might happen when using cascading heavy weight - menus - */ } public void windowDeactivated(WindowEvent e) { ! /* cancelPopupMenu(); cannot do this because ! this might happen when using cascading heavy weight ! menus ! */ } } --- 404,416 ---- } public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { ! } ! public void windowLostFocus(WindowEvent e) { ! cancelPopupMenu(); ! } ! public void windowGainedFocus(WindowEvent e) { } } ###@###.### 2002-05-04 ======================================================================
04-05-2002