提交 916bcfda 编写于 作者: D ddehaven

7172652: With JDK 1.7 text field does not obtain focus when using mnemonic Alt/Key combin

Reviewed-by: alexsch, azvegint
Contributed-by: vivi.an@oracle.com
上级 6fed9bbb
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -80,6 +80,14 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -80,6 +80,14 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* This method is here so that a subclass could do Label specific * This method is here so that a subclass could do Label specific
* layout and to shorten the method name a little. * layout and to shorten the method name a little.
* *
* @param label an instance of {@code JLabel}
* @param fontMetrics a font metrics
* @param text a text
* @param icon an icon
* @param viewR a bounding rectangle to lay out label
* @param iconR a bounding rectangle to lay out icon
* @param textR a bounding rectangle to lay out text
* @return a possibly clipped version of the compound labels string
* @see SwingUtilities#layoutCompoundLabel * @see SwingUtilities#layoutCompoundLabel
*/ */
protected String layoutCL( protected String layoutCL(
...@@ -109,6 +117,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -109,6 +117,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
/** /**
* Paint clippedText at textX, textY with the labels foreground color. * Paint clippedText at textX, textY with the labels foreground color.
* *
* @param l an instance of {@code JLabel}
* @param g an instance of {@code Graphics}
* @param s a text
* @param textX an X coordinate
* @param textY an Y coordinate
* @see #paint * @see #paint
* @see #paintDisabledText * @see #paintDisabledText
*/ */
...@@ -125,6 +138,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -125,6 +138,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* Paint clippedText at textX, textY with background.lighter() and then * Paint clippedText at textX, textY with background.lighter() and then
* shifted down and to the right by one pixel with background.darker(). * shifted down and to the right by one pixel with background.darker().
* *
* @param l an instance of {@code JLabel}
* @param g an instance of {@code Graphics}
* @param s a text
* @param textX an X coordinate
* @param textY an Y coordinate
* @see #paint * @see #paint
* @see #paintEnabledText * @see #paintEnabledText
*/ */
...@@ -329,26 +347,46 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -329,26 +347,46 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
public void uninstallUI(JComponent c) { public void uninstallUI(JComponent c) {
uninstallDefaults((JLabel)c); uninstallDefaults((JLabel) c);
uninstallComponents((JLabel)c); uninstallComponents((JLabel) c);
uninstallListeners((JLabel)c); uninstallListeners((JLabel) c);
uninstallKeyboardActions((JLabel)c); uninstallKeyboardActions((JLabel) c);
} }
protected void installDefaults(JLabel c){ /**
LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground", "Label.font"); * Installs default properties.
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE); *
} * @param c an instance of {@code JLabel}
*/
protected void installDefaults(JLabel c){
LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground", "Label.font");
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
}
/**
* Registers listeners.
*
* @param c an instance of {@code JLabel}
*/
protected void installListeners(JLabel c){ protected void installListeners(JLabel c){
c.addPropertyChangeListener(this); c.addPropertyChangeListener(this);
} }
/**
* Registers components.
*
* @param c an instance of {@code JLabel}
*/
protected void installComponents(JLabel c){ protected void installComponents(JLabel c){
BasicHTML.updateRenderer(c, c.getText()); BasicHTML.updateRenderer(c, c.getText());
c.setInheritsPopupMenu(true); c.setInheritsPopupMenu(true);
} }
/**
* Registers keyboard actions.
*
* @param l an instance of {@code JLabel}
*/
protected void installKeyboardActions(JLabel l) { protected void installKeyboardActions(JLabel l) {
int dka = l.getDisplayedMnemonic(); int dka = l.getDisplayedMnemonic();
Component lf = l.getLabelFor(); Component lf = l.getLabelFor();
...@@ -374,17 +412,37 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -374,17 +412,37 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
} }
} }
/**
* Uninstalls default properties.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallDefaults(JLabel c){ protected void uninstallDefaults(JLabel c){
} }
/**
* Unregisters listeners.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallListeners(JLabel c){ protected void uninstallListeners(JLabel c){
c.removePropertyChangeListener(this); c.removePropertyChangeListener(this);
} }
/**
* Unregisters components.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallComponents(JLabel c){ protected void uninstallComponents(JLabel c){
BasicHTML.updateRenderer(c, ""); BasicHTML.updateRenderer(c, "");
} }
/**
* Unregisters keyboard actions.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallKeyboardActions(JLabel c) { protected void uninstallKeyboardActions(JLabel c) {
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null); SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null);
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW, SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW,
...@@ -392,6 +450,12 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -392,6 +450,12 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
SwingUtilities.replaceUIActionMap(c, null); SwingUtilities.replaceUIActionMap(c, null);
} }
/**
* Returns an instance of {@code BasicLabelUI}.
*
* @param c a component
* @return an instance of {@code BasicLabelUI}
*/
public static ComponentUI createUI(JComponent c) { public static ComponentUI createUI(JComponent c) {
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
AppContext appContext = AppContext.getAppContext(); AppContext appContext = AppContext.getAppContext();
...@@ -440,7 +504,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -440,7 +504,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
doPress(label); doPress(label);
} }
else if (key == RELEASE) { else if (key == RELEASE) {
doRelease(label); doRelease(label, e.getActionCommand() != null);
} }
} }
...@@ -453,33 +517,77 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -453,33 +517,77 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
SwingUtilities.replaceUIInputMap(label, JComponent.WHEN_FOCUSED, inputMap); SwingUtilities.replaceUIInputMap(label, JComponent.WHEN_FOCUSED, inputMap);
} }
int dka = label.getDisplayedMnemonic(); int dka = label.getDisplayedMnemonic();
inputMap.put(KeyStroke.getKeyStroke(dka, BasicLookAndFeel.getFocusAcceleratorKeyMask(), true), RELEASE); putOnRelease(inputMap, dka, BasicLookAndFeel
.getFocusAcceleratorKeyMask());
// Need this when the sticky keys are enabled // Need this when the sticky keys are enabled
inputMap.put(KeyStroke.getKeyStroke(dka, 0, true), RELEASE); putOnRelease(inputMap, dka, 0);
// Need this if ALT is released before the accelerator // Need this if ALT is released before the accelerator
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true), RELEASE); putOnRelease(inputMap, KeyEvent.VK_ALT, 0);
label.requestFocus(); label.requestFocus();
} }
} }
private void doRelease(JLabel label) { private void doRelease(JLabel label, boolean isCommand) {
Component labelFor = label.getLabelFor(); Component labelFor = label.getLabelFor();
if (labelFor != null && labelFor.isEnabled()) { if (labelFor != null && labelFor.isEnabled()) {
InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED); if (label.hasFocus()) {
if (inputMap != null) { InputMap inputMap = SwingUtilities.getUIInputMap(label,
// inputMap should never be null. JComponent.WHEN_FOCUSED);
if (inputMap != null) {
// inputMap should never be null.
int dka = label.getDisplayedMnemonic();
removeOnRelease(inputMap, dka, BasicLookAndFeel
.getFocusAcceleratorKeyMask());
removeOnRelease(inputMap, dka, 0);
removeOnRelease(inputMap, KeyEvent.VK_ALT, 0);
}
inputMap = SwingUtilities.getUIInputMap(label,
JComponent.WHEN_IN_FOCUSED_WINDOW);
if (inputMap == null) {
inputMap = new InputMapUIResource();
SwingUtilities.replaceUIInputMap(label,
JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
}
int dka = label.getDisplayedMnemonic(); int dka = label.getDisplayedMnemonic();
inputMap.remove(KeyStroke.getKeyStroke(dka, BasicLookAndFeel.getFocusAcceleratorKeyMask(), true)); if (isCommand) {
inputMap.remove(KeyStroke.getKeyStroke(dka, 0, true)); putOnRelease(inputMap, KeyEvent.VK_ALT, 0);
inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true)); } else {
} putOnRelease(inputMap, dka, BasicLookAndFeel
if (labelFor instanceof Container && .getFocusAcceleratorKeyMask());
((Container) labelFor).isFocusCycleRoot()) { // Need this when the sticky keys are enabled
labelFor.requestFocus(); putOnRelease(inputMap, dka, 0);
}
if (labelFor instanceof Container &&
((Container) labelFor).isFocusCycleRoot()) {
labelFor.requestFocus();
} else {
SwingUtilities2.compositeRequestFocus(labelFor);
}
} else { } else {
SwingUtilities2.compositeRequestFocus(labelFor); InputMap inputMap = SwingUtilities.getUIInputMap(label,
JComponent.WHEN_IN_FOCUSED_WINDOW);
int dka = label.getDisplayedMnemonic();
if (inputMap != null) {
if (isCommand) {
removeOnRelease(inputMap, dka, BasicLookAndFeel
.getFocusAcceleratorKeyMask());
removeOnRelease(inputMap, dka, 0);
} else {
removeOnRelease(inputMap, KeyEvent.VK_ALT, 0);
}
}
} }
} }
} }
private void putOnRelease(InputMap inputMap, int keyCode, int modifiers) {
inputMap.put(KeyStroke.getKeyStroke(keyCode, modifiers, true),
RELEASE);
}
private void removeOnRelease(InputMap inputMap, int keyCode, int modifiers) {
inputMap.remove(KeyStroke.getKeyStroke(keyCode, modifiers, true));
}
} }
} }
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 7172652
@summary With JDK 1.7 text field does not obtain focus when using mnemonic Alt/Key combin
@author Semyon Sadetsky
@library /lib/testlibrary
@build jdk.testlibrary.OSInfo
@run main bug7172652
*/
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.KeyEvent;
import jdk.testlibrary.OSInfo;
public class bug7172652 {
private static JMenu menu;
private static JFrame frame;
private static Boolean selected;
public static void main(String[] args) throws Exception {
if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
System.out.println("ok");
return;
}
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
setup();
}
});
test();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.dispose();
}
});
}
private static void test() throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
menu.getModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
selected = menu.isSelected();
}
});
}
});
Robot robot = new Robot();
robot.setAutoDelay(200);
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_ALT);
robot.waitForIdle();
if( selected != null ) {
throw new RuntimeException("Menu is notified selected= " + selected);
}
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_ALT);
if( selected != null ) {
throw new RuntimeException("Menu is notified selected= " + selected);
}
robot.waitForIdle();
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_ALT);
if( selected != null ) {
throw new RuntimeException("Menu is notified selected= " + selected);
}
robot.waitForIdle();
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_F);
robot.keyRelease(KeyEvent.VK_ALT);
if( selected != null ) {
throw new RuntimeException("Menu is notified selected= " + selected);
}
robot.waitForIdle();
System.out.printf("ok");
}
private static void setup() {
JLabel firstLbl = new JLabel("First name");
JLabel lastLbl = new JLabel("Last name");
JMenuBar menuBar = new JMenuBar();
JTextField firstTxtFld = new JTextField(20);
JTextField lastTxtFld = new JTextField(20);
JDesktopPane desktopPane = new JDesktopPane();
JInternalFrame iframe = new JInternalFrame("A frame", true, true, true, true);
// Set an initial size
iframe.setSize(200, 220);
// By default, internal frames are not visible; make it visible
iframe.setVisible(true);
JPanel pane = new JPanel();
pane.setLayout(new FlowLayout());
pane.add(firstLbl);
pane.add(firstTxtFld);
pane.add(lastLbl);
pane.add(lastTxtFld);
firstLbl.setLabelFor(firstTxtFld);
firstLbl.setDisplayedMnemonic('F');
lastLbl.setLabelFor(lastTxtFld);
lastLbl.setDisplayedMnemonic('L');
iframe.getContentPane().add(pane);
iframe.setJMenuBar(menuBar);
menu = new JMenu("FirstMenu");
//m.setMnemonic('i');
menuBar.add(menu);
desktopPane.add(iframe);
frame = new JFrame();
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(desktopPane);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册