-
Bug
-
Resolution: Cannot Reproduce
-
P4
-
None
-
7
-
x86
-
linux
FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.7.0_04-b20)
Same behavior under OpenJDK (6b24-1.11.1-4ubuntu2)
ADDITIONAL OS VERSION INFORMATION :
Ubuntu 10.04/12.04
EXTRA RELEVANT SYSTEM CONFIGURATION :
Nothing special
A DESCRIPTION OF THE PROBLEM :
An InputVerifier should prevent a control from losing the focus, if the contents do not pass validation. Focus-loss is prevented when clicking with the mouse, or when pressing "tab". However, pressing "shift-tab" to go to the previous control results in loss-of-focus. After pressing "shift-tab", no control has the focus (getFocusOwner returns null).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the sample application below. Delete the text in the second text field, and press "tab" or click the mouse on the first text field. Focus is properly retained by the second text field, since it may not be empty.
However, if you attempt to leave the text field by pressing "shift-tab", focus *is* lost. Not shown by this simple demo: the FocusLost event is fired, even though it should not be.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Focus should be retained by the JTextField until the contents validate. The FocusLost event should not be triggered.
ACTUAL -
The control loses the focus. The FocusLost event is triggered.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
No errors reported
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Component;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class FocusBugDemo extends JFrame {
static JTextField txtOne = new JTextField("Ignore this control");
static JTextField txtTwo = new JTextField("Delete this text, then press shift-tab");
static JLabel lblFocus = new JLabel("");
static KeyboardFocusManager kfm = new DefaultKeyboardFocusManager();
public static void main(String[] args) {
new FocusBugDemo();
Thread t = new Thread() {
@Override
public void run() {
while (true) {
Component c = kfm.getFocusOwner();
String focusInfo = "elsewhere";
if (c == null) {
focusInfo = "null";
} else if (c == txtOne) {
focusInfo = "txtOne";
} else if (c == txtTwo) {
focusInfo = "txtTwo";
}
lblFocus.setText(System.currentTimeMillis() + " - Focus owner " + focusInfo);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
};
t.start();
}
private FocusBugDemo() {
super("Focus bug demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 100));
setLayout(new GridLayout(3, 1));
NotEmpty validator = new NotEmpty();
txtOne.setInputVerifier(validator);
txtTwo.setInputVerifier(validator);
add(txtOne);
add(txtTwo);
add(lblFocus);
pack();
setVisible(true);
}
private class NotEmpty extends InputVerifier {
@Override
public boolean verify(JComponent input) {
JTextField txtField = (JTextField) input;
return (txtField.getText().length() > 0);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One must add code to the FocusLost event to check whether the event should actually have occurred, and to return focus to the correct control if not.
Java(TM) SE Runtime Environment (build 1.7.0_04-b20)
Same behavior under OpenJDK (6b24-1.11.1-4ubuntu2)
ADDITIONAL OS VERSION INFORMATION :
Ubuntu 10.04/12.04
EXTRA RELEVANT SYSTEM CONFIGURATION :
Nothing special
A DESCRIPTION OF THE PROBLEM :
An InputVerifier should prevent a control from losing the focus, if the contents do not pass validation. Focus-loss is prevented when clicking with the mouse, or when pressing "tab". However, pressing "shift-tab" to go to the previous control results in loss-of-focus. After pressing "shift-tab", no control has the focus (getFocusOwner returns null).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the sample application below. Delete the text in the second text field, and press "tab" or click the mouse on the first text field. Focus is properly retained by the second text field, since it may not be empty.
However, if you attempt to leave the text field by pressing "shift-tab", focus *is* lost. Not shown by this simple demo: the FocusLost event is fired, even though it should not be.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Focus should be retained by the JTextField until the contents validate. The FocusLost event should not be triggered.
ACTUAL -
The control loses the focus. The FocusLost event is triggered.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
No errors reported
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Component;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class FocusBugDemo extends JFrame {
static JTextField txtOne = new JTextField("Ignore this control");
static JTextField txtTwo = new JTextField("Delete this text, then press shift-tab");
static JLabel lblFocus = new JLabel("");
static KeyboardFocusManager kfm = new DefaultKeyboardFocusManager();
public static void main(String[] args) {
new FocusBugDemo();
Thread t = new Thread() {
@Override
public void run() {
while (true) {
Component c = kfm.getFocusOwner();
String focusInfo = "elsewhere";
if (c == null) {
focusInfo = "null";
} else if (c == txtOne) {
focusInfo = "txtOne";
} else if (c == txtTwo) {
focusInfo = "txtTwo";
}
lblFocus.setText(System.currentTimeMillis() + " - Focus owner " + focusInfo);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
};
t.start();
}
private FocusBugDemo() {
super("Focus bug demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 100));
setLayout(new GridLayout(3, 1));
NotEmpty validator = new NotEmpty();
txtOne.setInputVerifier(validator);
txtTwo.setInputVerifier(validator);
add(txtOne);
add(txtTwo);
add(lblFocus);
pack();
setVisible(true);
}
private class NotEmpty extends InputVerifier {
@Override
public boolean verify(JComponent input) {
JTextField txtField = (JTextField) input;
return (txtField.getText().length() > 0);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One must add code to the FocusLost event to check whether the event should actually have occurred, and to return focus to the correct control if not.