United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4389332 Focus owner is null for applications which have menus only.
JDK-4389332 : Focus owner is null for applications which have menus only.

Details
Type:
Bug
Submit Date:
2000-11-15
Status:
Resolved
Updated Date:
2001-06-22
Project Name:
JDK
Resolved Date:
2001-06-22
Component:
client-libs
OS:
windows_nt,generic,windows_2000
Sub-Component:
javax.swing
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.0
Fixed Versions:
1.4.0 (beta2)

Related Reports
Duplicate:
Duplicate:
Duplicate:
Duplicate:

Sub Tasks

Description
java version "1.4.0beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0beta-b40)
Java HotSpot(TM) Client VM (build 1.4beta-B40, mixed mode)

This bug appears to have been introduced during the focus manager enhancements at build 35. It doesnt' appear in b34. This bug appears on both Windows and Solaris but I haven't done a lot of exhaustive testing on Solaris.

Upon initialization of the following application, the focus owner appears to be null. If the button is added to the center of the content pane the the focus owner is correctly set to the button. I'm not sure what the exact circumstances is for setting the focus but in previous builds, the focus was set to one of the JMenus upon initialization.

If you use "% java Bug true" to start up the test application then the timer will report the focus owner every 2 seconds.

>>>> Bug.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.border.*;

public class Bug extends JFrame {
    private Timer timer;
    private JButton timerButton;

    public Bug() {
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	Container content = getContentPane();
	content.setLayout(new BorderLayout());
	content.add("North", createMenuBar("1 - First Menu", true));
	content.add("South", createMenuBar("2 - Second Menu", false));

	ActionListener timerListener = new ActionListener() {
		public void actionPerformed(ActionEvent evt) {
		    reportFocusStatus();
		}
	    };

	timer = new Timer(2000, timerListener);
	
	timerButton = new JButton("Start");
	timerButton.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent evt) {
		    if (timer.isRunning()) {
			timer.stop();
			timerButton.setText("Start Timer");
		    } else {
			timer.start();
			timerButton.setText("Stop Timer");
		    }
		}
	    });
	//	content.add(timerButton, BorderLayout.CENTER);

	pack();
	show();
    }

    public void startTimer() {
	timer.start();
    }

    public void stopTimer() {
	timer.stop();
    }
	
    public JMenuBar createMenuBar(String str, boolean bFlag) {
	JMenuBar menubar = new JMenuBar();
	JMenuItem menuitem;
		
	JMenu menu = new JMenu(str);
	menu.setMnemonic(str.charAt(0));
		
	menubar.add(menu);
	for(int i = 0; i < 10; i ++) {
	    menuitem = new JMenuItem("JMenuItem" + i);
	    if(bFlag)
		menuitem.setMnemonic('0' + i);
	    menu.add(menuitem);
	}
	return menubar;
    }

    // Focus diagnostic
    public void reportFocusStatus() {
	//	KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
	//	Component comp = fm.getFocusOwner();
	Component comp = this.getFocusOwner();
	String className = "null";
	if (comp != null) {
	    className = comp.getClass().getName();
	}
	System.out.println("FocusManager: getFocusOwner = " + className);
    }

    // 
    // Use "true" as the first arg to start the focus status timer.
    public static void main(String argv[]) {
	Bug bug = new Bug();

	if (argv.length > 0 && argv[0].equals("true")) {
	    bug.startTimer();
	}
    }
}
<<<< end Bug.java	

                                    

Comments
EVALUATION

Commit to fix in Merlin (regression).  
eric.hawkes@eng 2000-11-29


Name: osR10079			Date: 05/17/2001

If i understand correctly we have two issues in this bug:

1. In new Focus API JMenu is not accepted by
LayoutFocusTraversalPolicy (default Swing focus traversal policy).
Submitter says that this is a regression.  I'm not sure that this is a
bug (i'm going to ask the author of new API about it).  But even if
this is a bug, this is a bug in Swing since JMenu and
LayoutFocusTraversalPolicy are Swing classes.
  
2. When focus owner is null all accelerators in Swing don't work.  I
couldn't fix this problem as part of 4390019, because this is a pure
Swing problem.  But now i recommend to Swing to reimplement
accelerators using post-processor's API (see interface
java.awt.KeyEventPostProcessor).
###@###.### 17 May 2001.


Yes, the previous evaluator is exactly right, Swing should install a KeyEventPostProcessor that will process key bindings when it receives the event and the source is NOT a JComponent.
A ramification of this is that the Swing top level components (JFrame, JDialog and JApplet) no longer need to override processKeyEvent. As this is an api change I'll file a separate RFE on this.
scott.violet@eng 2001-05-23
                                     
2001-05-23
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
merlin
merlin-beta2

FIXED IN:
merlin-beta2

INTEGRATED IN:
merlin-beta2


                                     
2004-09-17



Hardware and Software, Engineered to Work Together