Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Name: apR10229 Date: 02/04/2003 The problem is that javax.swing.plaf.basic.BasicComboBoxUI.FocusHandler listener does not hide popup menu when focus is lost and LightWeightPopupEnabled property is set to false. ----------------------- Java API Doc says: "public class BasicComboBoxUI.FocusHandler extends Object implements FocusListener This listener hides the popup when the focus is lost. It also repaints when focus is gained or lost." ------------------------ In other words we can not hide heavyweight popup menu by invoking focusLost() method. Reference implementation still use workaround to bug request 4168483, but it is not fixed. RI works OK only when LightWeightPopupEnabled property is set to true. See below for an example that reproduces this abnormal behavior and for a licensee request. -------------------- Test.java ---------------------- import javax.swing.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.*; import java.awt.*; import java.awt.event.*; import java.lang.reflect.*; class Test { public static void main(String[] args) { String title[] = { "test0", "test1", "test2", "test3", "test4" }; final StubComboUI ui = new StubComboUI(); final JComboBox comboBox = new JComboBox(title); final StubComboUI.StubFH c = ui.new StubFH(); final FocusEvent event = new FocusEvent(comboBox, FocusEvent.FOCUS_LOST); JFrame frame = new JFrame("Test"); comboBox.setUI(ui); comboBox.setLightWeightPopupEnabled(false); frame.getContentPane().add(comboBox, BorderLayout.CENTER); frame.pack(); frame.setLocation(100,100); frame.setSize(200,50); frame.setVisible(true); try { SwingUtilities.invokeAndWait(new Runnable() { public synchronized void run() { ui.setPopupVisible(comboBox, true); c.focusLost(event); } }); } catch (InterruptedException e){ System.out.println("InterruptedException: " + e); e.printStackTrace(); } catch (InvocationTargetException e){ System.out.println("InvocationTargetException: " + e); e.printStackTrace(); } ComboPopup popup = ((StubComboUI)comboBox.getUI()).stubGetPopup(); System.out.println("isLightWeightPopupEnabled(): "+ comboBox.isLightWeightPopupEnabled()); System.out.println("After invoking FocusHandler.focusLost():"); System.out.println("Popup has focus: "+ ((StubComboUI)comboBox.getUI()).stubHasFocus()); System.out.println("Popup is visible: "+popup.isVisible()); } } class StubComboUI extends BasicComboBoxUI { public StubComboUI() { super(); } public boolean stubHasFocus() { return super.hasFocus; } public class StubFH extends FocusHandler { public StubFH() { super(); } } public ComboPopup stubGetPopup() { return super.popup; } } ------------------- example output ------------------ <pav@libra(pts/5).260> java -cp . Test isLightWeightPopupEnabled(): false After invoking FocusHandler.focusLost(): Popup has focus: false Popup is visible: true ------------------ licensee request ----------------- licensee support engineer wrote: - - - - - - - - - - - - - - - - Dear plaf test writers, Apple fails the JCK 1.4a test javasoft.sqe.tests.api.javax.swing.plaf.basic.BasicComboBoxUI.FocusHandler.publicTests -TestCaseID FocusHandler2003 on their Aqua L&F. The reason for the failure is that Aqua ComboBox uses a heavyweight popup menu, but reference implementation is using a lightweight popup menu by default. This is up to the L&F to choose: JComboBox spec: "public void setLightWeightPopupEnabled(boolean aFlag)......The default value for the lightWeightPopupEnabled property is true, unless otherwise specified by the look and feel. Some look and feels always use heavyweight popups, no matter what the value of this property. " There's a hack in the swing code that prevents this test from behaving correctly with a heavyweight popup (please see Apple's message below). If the test is modified to set setLightWeightPopupEnabled(false), it will fail on reference implementation too. The reference implementation bug needs to be filed and the test excluded. Apple wrote: - - - - - - Environment: JCK14a, Mac OS X 10.2.3, jdk14a.jtx from 01/29/03, Default Look & Feel: apple.laf.AquaLookAndFeel Problem: The test javasoft.sqe.tests.api.javax.swing.plaf.basic.BasicComboBoxUI.FocusHandler.publicTests -TestCaseID FocusHandler2003 fails with the message: "Method focusLost works wrong" Analysis: For better fidelity with Apple's Aqua HI guidelines, we force JPopupMenus to be heavyweight in all cases. This gives us correct translucency and shadows on the menus. In the Sun shared file BasicComboBoxUI.java there are hacks in Swing that are incompatible with the forcing of heavyweight JPopupMenus. Here is the relevant code (note 'comboBox.isLightWeightPopupEnabled()'): public class FocusHandler implements FocusListener { public void focusGained( FocusEvent e ) { hasFocus = true; comboBox.repaint(); // Notify assistive technologies that the combo box // gained focus. if (comboBox instanceof Accessible) { AccessibleContext ac = ((Accessible)comboBox).getAccessibleContext(); if (ac != null) { ac.firePropertyChange( AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED); } } } public void focusLost( FocusEvent e ) { hasFocus = false; // GES, 980818: // Note that the second check here is a workaround to bug // 4168483. There is a bogus focusLost sent to the // ComboBox with isTemporary false when a mediumweight menu // is popped up. Until this is fixed in AWT, we make the // tradeoff of not popping down mediumweight popups when // the combobox loses focus. Although this means that the // combobox does not remove such menus when you tab out, // it is seen as more desirable than the alternative which // is that mediumweight combobox menus dissappear immediately // on popup, rendering them completely unusable. if ( !e.isTemporary() && comboBox.isLightWeightPopupEnabled()) { setPopupVisible(comboBox, false); } comboBox.repaint(); // Notify assistive technologies that the combo box // lost focus. if (comboBox instanceof Accessible) { AccessibleContext ac = ((Accessible)comboBox).getAccessibleContext(); if (ac != null) { ac.firePropertyChange( AccessibleContext.ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null); } } } } ------------------------------------------------------------------ ======================================================================
|