-
Bug
-
Resolution: Fixed
-
P4
-
6
-
b64
-
x86
-
windows_2000
-
Verified
Name: sv35042 Date: 12/04/2002
FULL PRODUCT VERSION :
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
If the first component of a focus cycle root (I'll call it ancestor root) is a non-focusable focus cycle root
(I'll call this the descendent root ) there are two problems:
A. on initial showing the default of this descendant root is not focused
B. if there are other focusable components in the ancestor root then one of those is focused on initial
startup and the children of the descendent root are not reachable by back-tabbing.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
To reproduce A:
1. compile the attached code as is
2. run it
3. you have to tab to make the default component (the third button) focused
To reproduce B:
1. outcomment the line inserting the southPanel
2. compile
3. run it
4. the first button of the south panel is focused
5. back tab - the last button of the south panel is focused
To see that B is not the intended behaviour:
1. outcomment the line inserting the northPanel
2. compile
3. run it
4. the first of the north panel is focused
5. click the first button of the southpanel
6. back tab - the default button of the center panel is focused, as expected
EXPECTED VERSUS ACTUAL BEHAVIOR :
see above (negate A, B from the description to get the expected behavior)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import javax.swing.*;
import java.util.*;
/** example adapted from sun's core java tech tips, oct. 2002
*
* $RCSfile: AlphaPolicy.java,v $ $Revision: 1.1.2.1 $ $Date: 2002/11/27 11:35:12 $
*/
public class AlphaPolicy {
public AlphaPolicy() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = frame.getContentPane();
// to have a second panel all default settings
JComponent northDefaultPolicyPanel = buildDefaultPolicyPanel("north", 1);
// content.add(northDefaultPolicyPanel, BorderLayout.NORTH);
// have panel with custom traversal policy
JComponent customPolicyPanel = buildCustomPolicyPanel();
content.add(customPolicyPanel, BorderLayout.CENTER);
fiddleFocusSettings(customPolicyPanel);
// to have a second panel all default settings
JComponent defaultPolicyPanel = buildDefaultPolicyPanel("south", 3);
// content.add(defaultPolicyPanel, BorderLayout.SOUTH);
frame.pack();
frame.show();
}
private void fiddleFocusSettings(JComponent container) {
container.setFocusTraversalPolicy(new AlphaOrderFocusTraversalPolicy());
container.setFocusCycleRoot(true);
}
//---------------------------custom policy
public class AlphaOrderFocusTraversalPolicy
extends SortingFocusTraversalPolicy {
AlphaOrderFocusTraversalPolicy() {
super(new AlphaOrder());
}
protected boolean accept(Component aComp) {
if (aComp instanceof JButton) {
return super.accept(aComp);
}
return false;
}
}
//---------------------------Comparator
public class AlphaOrder implements Comparator {
public int compare(Object one, Object two) {
if (!(one instanceof JButton)) {
return 1;
}
if (!(two instanceof JButton)) {
return 1;
}
JButton button1 = (JButton) one;
JButton button2 = (JButton) two;
String text1 = button1.getText();
String text2 = button2.getText();
return text1.compareTo(text2);
}
}
//---------------------------init
private JComponent buildCustomPolicyPanel() {
String labels[] = { "HHH", "XXX", "AAA", "JJJ" };
JPanel panel = new JPanel();
for (int i = 0, n = labels.length; i < n; i++) {
JButton button = new JButton(labels[i]);
panel.add(button);
}
return panel;
}
private JComponent buildDefaultPolicyPanel(String pre, int count) {
JPanel panel = new JPanel();
for (int i = 0; i < count; i++) {
JButton button = new JButton(pre + i);
button.setName(button.getText());
panel.add(button);
}
return panel;
}
//---------------------------main
public static void main(String args[]) {
new AlphaPolicy();
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Evaluation:
Analisys and fix:
the common reason for both is that the getFirstComponent does not include the defaults when building
the cycle list. Instead of
enumerateAndSort(focusCycleRoot, list, null);
it should do a
enumerateAndSort(focusCycleRoot, list, defaults)
That's not the whole story, though: when creating the virtual insertion position of the defaultComponent
of a non-focusable root that virtual index is built as
virtualIndex = -(resultFromSearch) -2 where
resultFromSearch = -(insertPosition) - 1
in the case of insertPosition = 0 this leads to a virtualIndex of -1 which is not handled correctly in
getComponentBefore
workaround:
c&p complete code and fix it ...
Greetings
Jeanette
(Review ID: 178459)
======================================================================
- relates to
-
JDK-6240842 adding a focus traversal policy to a JPanel makes it unreachable in j2se 5.0
-
- Closed
-