提交 c11a6d11 编写于 作者: 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
上级 5c1cb50d
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -80,6 +80,14 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* This method is here so that a subclass could do Label specific
* 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
*/
protected String layoutCL(
......@@ -109,6 +117,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
/**
* 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 #paintDisabledText
*/
......@@ -125,6 +138,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* Paint clippedText at textX, textY with background.lighter() and then
* 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 #paintEnabledText
*/
......@@ -329,26 +347,46 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
public void uninstallUI(JComponent c) {
uninstallDefaults((JLabel)c);
uninstallComponents((JLabel)c);
uninstallListeners((JLabel)c);
uninstallKeyboardActions((JLabel)c);
uninstallDefaults((JLabel) c);
uninstallComponents((JLabel) c);
uninstallListeners((JLabel) c);
uninstallKeyboardActions((JLabel) c);
}
protected void installDefaults(JLabel c){
LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground", "Label.font");
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
}
/**
* Installs default properties.
*
* @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){
c.addPropertyChangeListener(this);
}
/**
* Registers components.
*
* @param c an instance of {@code JLabel}
*/
protected void installComponents(JLabel c){
BasicHTML.updateRenderer(c, c.getText());
c.setInheritsPopupMenu(true);
}
/**
* Registers keyboard actions.
*
* @param l an instance of {@code JLabel}
*/
protected void installKeyboardActions(JLabel l) {
int dka = l.getDisplayedMnemonic();
Component lf = l.getLabelFor();
......@@ -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){
}
/**
* Unregisters listeners.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallListeners(JLabel c){
c.removePropertyChangeListener(this);
}
/**
* Unregisters components.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallComponents(JLabel c){
BasicHTML.updateRenderer(c, "");
}
/**
* Unregisters keyboard actions.
*
* @param c an instance of {@code JLabel}
*/
protected void uninstallKeyboardActions(JLabel c) {
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null);
SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW,
......@@ -392,6 +450,12 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
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) {
if (System.getSecurityManager() != null) {
AppContext appContext = AppContext.getAppContext();
......@@ -440,7 +504,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
doPress(label);
}
else if (key == RELEASE) {
doRelease(label);
doRelease(label, e.getActionCommand() != null);
}
}
......@@ -453,33 +517,77 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
SwingUtilities.replaceUIInputMap(label, JComponent.WHEN_FOCUSED, inputMap);
}
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
inputMap.put(KeyStroke.getKeyStroke(dka, 0, true), RELEASE);
putOnRelease(inputMap, dka, 0);
// 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();
}
}
private void doRelease(JLabel label) {
private void doRelease(JLabel label, boolean isCommand) {
Component labelFor = label.getLabelFor();
if (labelFor != null && labelFor.isEnabled()) {
InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED);
if (inputMap != null) {
// inputMap should never be null.
if (label.hasFocus()) {
InputMap inputMap = SwingUtilities.getUIInputMap(label,
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();
inputMap.remove(KeyStroke.getKeyStroke(dka, BasicLookAndFeel.getFocusAcceleratorKeyMask(), true));
inputMap.remove(KeyStroke.getKeyStroke(dka, 0, true));
inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true));
}
if (labelFor instanceof Container &&
((Container) labelFor).isFocusCycleRoot()) {
labelFor.requestFocus();
if (isCommand) {
putOnRelease(inputMap, KeyEvent.VK_ALT, 0);
} else {
putOnRelease(inputMap, dka, BasicLookAndFeel
.getFocusAcceleratorKeyMask());
// Need this when the sticky keys are enabled
putOnRelease(inputMap, dka, 0);
}
if (labelFor instanceof Container &&
((Container) labelFor).isFocusCycleRoot()) {
labelFor.requestFocus();
} else {
SwingUtilities2.compositeRequestFocus(labelFor);
}
} 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.
先完成此消息的编辑!
想要评论请 注册