Details
-
Bug
-
Resolution: Fixed
-
P3
-
7u9
-
b94
-
x86
-
windows_xp
Description
FULL PRODUCT VERSION :
java version " 1.7.0_09 "
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) Client VM (build 23.5-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
If the target for " requestFocusInField " is already disabled at the moment of execution, the window containing the component can't be activated/focused anymore.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In the example attached start ViewA, press " Open " .
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The new window should open and come to the front. The focus should shift to the next focusable field or the window itself (exactly the behavior that is shown when the field is disabled after the window is focused).
ACTUAL -
The new window opens and stays in the background. The window can't be activated/focused by clicking anywhere, focus is always transferred back to ViewA
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class ViewA extends JFrame {
public static void main(String[] args) {
new ViewA().open();
}
public void open() {
setLayout(new GridLayout(0, 2));
add(new JLabel( " test " ));
add(new JTextField());
JButton btn;
btn = new JButton( " Open " );
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new ViewB().open();
}
});
add(btn);
btn = new JButton( " Exit " );
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
add(btn);
pack();
setVisible(true);
}
}
public class ViewB extends JFrame {
private JTextField tf;
public void open() {
setLayout(new GridLayout(0, 2));
add(new JLabel( " test " ));
tf = new JTextField();
add(tf);
pack();
// disabling before requesting focus fails
tf.setEnabled(false);
tf.requestFocus();
// disabling after requesting focus works!
//tf.setEnabled(false);
setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
There's no public API to force focus transfer in this case. The public " transferFocus " fails because focus owner not cleared. Our workaround looks like
protected void hookFixFocus() {
Container window;
window = getParent();
while (window != null && !(window instanceof Window)) {
window = window.getParent();
}
if (window != null) {
Component c = ((Window) window).getMostRecentFocusOwner();
if (c != null && !c.isEnabled()) {
c.setFocusable(false);
c.setFocusable(true);
}
}
}
Maybe one should include the check for enablement in " requestFocusInWIndow " ?
java version " 1.7.0_09 "
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) Client VM (build 23.5-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
If the target for " requestFocusInField " is already disabled at the moment of execution, the window containing the component can't be activated/focused anymore.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In the example attached start ViewA, press " Open " .
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The new window should open and come to the front. The focus should shift to the next focusable field or the window itself (exactly the behavior that is shown when the field is disabled after the window is focused).
ACTUAL -
The new window opens and stays in the background. The window can't be activated/focused by clicking anywhere, focus is always transferred back to ViewA
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class ViewA extends JFrame {
public static void main(String[] args) {
new ViewA().open();
}
public void open() {
setLayout(new GridLayout(0, 2));
add(new JLabel( " test " ));
add(new JTextField());
JButton btn;
btn = new JButton( " Open " );
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new ViewB().open();
}
});
add(btn);
btn = new JButton( " Exit " );
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
add(btn);
pack();
setVisible(true);
}
}
public class ViewB extends JFrame {
private JTextField tf;
public void open() {
setLayout(new GridLayout(0, 2));
add(new JLabel( " test " ));
tf = new JTextField();
add(tf);
pack();
// disabling before requesting focus fails
tf.setEnabled(false);
tf.requestFocus();
// disabling after requesting focus works!
//tf.setEnabled(false);
setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
There's no public API to force focus transfer in this case. The public " transferFocus " fails because focus owner not cleared. Our workaround looks like
protected void hookFixFocus() {
Container window;
window = getParent();
while (window != null && !(window instanceof Window)) {
window = window.getParent();
}
if (window != null) {
Component c = ((Window) window).getMostRecentFocusOwner();
if (c != null && !c.isEnabled()) {
c.setFocusable(false);
c.setFocusable(true);
}
}
}
Maybe one should include the check for enablement in " requestFocusInWIndow " ?