# HG changeset patch # User jgiles # Date 1396988565 -43200 # Wed Apr 09 08:22:45 2014 +1200 # Node ID 9dd539c10334224d62303fe76f895cbd4778adce # Parent f690b32d89d1e40174f7203c01704f6166df57c1 [mq]: rt36583.patch diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ContextMenuContent.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ContextMenuContent.java --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ContextMenuContent.java +++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/ContextMenuContent.java @@ -1275,7 +1275,7 @@ getChildren().remove(right); } - String text = KeystrokeUtils.toString(item.getAccelerator()); + String text = item.getAccelerator().getDisplayText(); right = new Label(text); right.setStyle(item.getStyle()); right.getStyleClass().add("accelerator-text"); diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/KeyCodeUtils.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/KeyCodeUtils.java deleted file mode 100644 --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/KeyCodeUtils.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2011, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package com.sun.javafx.scene.control.skin; - -import javafx.scene.input.KeyCode; - -/** - * Utility functions related to KeyCodes - */ -public class KeyCodeUtils { - /** - * Return the accelerator string associated with a KeyCode. - * (This doesn't include the modifier keys you would find in a - * Keystroke - for those, you would call {@link KeystrokeUtils#toString} - * which incidentally uses this method to compute the key portion - * of the accelerator string. - * - * @param code The keycode to compute a menu accelerator string for - * @return The accelerator string, typically a single character (quite possibly - * * a unicode character). - */ - public static String getAccelerator(KeyCode code) { - char c = getSingleChar(code); - if (c != 0) { - return String.valueOf(c); - } - - // Compute a name based on the enum name, e.g. F13 becomes F13 and - // NUM_LOCK becomes Num Lock - - String name = code.toString(); - - // We only want the first letter to be upper-case, so we convert 'ENTER' - // to 'Enter' -- and we also convert multiple words separated by _ - // such that each individual word is capitalized and the underline replaced - // by spaces. - StringBuilder sb = new StringBuilder(); - String[] words = com.sun.javafx.Utils.split(name, "_"); - for (String word : words) { - if (sb.length() > 0) { - sb.append(' '); - } - sb.append(word.charAt(0)); - sb.append(word.substring(1).toLowerCase()); - } - return sb.toString(); - } - - /** Compute a single suitable char summarizing the code, if any, and 0 otherwise. */ - private static char getSingleChar(KeyCode code) { - switch (code) { - case ENTER: return '\u21B5'; - case LEFT: return '\u2190'; - case UP: return '\u2191'; - case RIGHT: return '\u2192'; - case DOWN: return '\u2193'; - case COMMA: return ','; - case MINUS: return '-'; - case PERIOD: return '.'; - case SLASH: return '/'; - case SEMICOLON: return ';'; - case EQUALS: return '='; - case OPEN_BRACKET: return '['; - case BACK_SLASH: return '\\'; - case CLOSE_BRACKET: return ']'; - case MULTIPLY: return '*'; - case ADD: return '+'; - case SUBTRACT: return '-'; - case DECIMAL: return '.'; - case DIVIDE: return '/'; - case BACK_QUOTE: return '`'; - case QUOTE: return '"'; - case AMPERSAND: return '&'; - case ASTERISK: return '*'; - case LESS: return '<'; - case GREATER: return '>'; - case BRACELEFT: return '{'; - case BRACERIGHT: return '}'; - case AT: return '@'; - case COLON: return ':'; - case CIRCUMFLEX: return '^'; - case DOLLAR: return '$'; - case EURO_SIGN: return '\u20AC'; - case EXCLAMATION_MARK: return '!'; - case LEFT_PARENTHESIS: return '('; - case NUMBER_SIGN: return '#'; - case PLUS: return '+'; - case RIGHT_PARENTHESIS: return ')'; - case UNDERSCORE: return '_'; - case DIGIT0: return '0'; - case DIGIT1: return '1'; - case DIGIT2: return '2'; - case DIGIT3: return '3'; - case DIGIT4: return '4'; - case DIGIT5: return '5'; - case DIGIT6: return '6'; - case DIGIT7: return '7'; - case DIGIT8: return '8'; - case DIGIT9: return '9'; - default: - break; - } - - /* - ** On Mac we display these unicode symbols, - ** otherwise we default to the Text version of the char. - */ - if (com.sun.javafx.PlatformUtil.isMac()) { - switch (code) { - case BACK_SPACE: return '\u232B'; - case ESCAPE: return '\u238B'; - case DELETE: return '\u2326'; - default: - break; - } - } - return 0; - } -} diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/KeystrokeUtils.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/KeystrokeUtils.java deleted file mode 100644 --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/KeystrokeUtils.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2011, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package com.sun.javafx.scene.control.skin; - -import javafx.scene.input.KeyCharacterCombination; -import javafx.scene.input.KeyCodeCombination; -import javafx.scene.input.KeyCombination; - -public class KeystrokeUtils { - - public static String toString(final KeyCombination kc) { - if (kc == null) { - return ""; - } - - StringBuilder stringBuilder = new StringBuilder(); - if (com.sun.javafx.PlatformUtil.isMac()) { - // Macs have a different convention for keyboard accelerators - - // no pluses to separate modifiers, and special symbols for - // each modifier (in a particular order), etc - if (kc.getControl() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("\u2303"); - } - if (kc.getAlt() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("\u2325"); - } - if (kc.getShift() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("\u21e7"); - } - if (kc.getMeta() == KeyCombination.ModifierValue.DOWN || kc.getShortcut() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("\u2318"); - } - // TODO refer to RT-14486 for remaining glyphs - } - else { - if (kc.getControl() == KeyCombination.ModifierValue.DOWN || kc.getShortcut() == KeyCombination.ModifierValue.DOWN ) { - stringBuilder.append("Ctrl+"); - } - if (kc.getAlt() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("Alt+"); - } - if (kc.getShift() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("Shift+"); - } - if (kc.getMeta() == KeyCombination.ModifierValue.DOWN) { - stringBuilder.append("Meta+"); - } - } - - if (kc instanceof KeyCodeCombination) { - stringBuilder.append(KeyCodeUtils.getAccelerator(((KeyCodeCombination)kc).getCode())); - } else if (kc instanceof KeyCharacterCombination) { - stringBuilder.append(((KeyCharacterCombination)kc).getCharacter()); - } - - return stringBuilder.toString(); - } -} diff --git a/modules/controls/src/test/java/com/sun/javafx/scene/control/skin/KeystrokeUtilsTest.java b/modules/controls/src/test/java/com/sun/javafx/scene/control/skin/KeystrokeUtilsTest.java deleted file mode 100644 --- a/modules/controls/src/test/java/com/sun/javafx/scene/control/skin/KeystrokeUtilsTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2011, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package com.sun.javafx.scene.control.skin; - -import static org.junit.Assert.assertTrue; - -import javafx.scene.input.KeyCharacterCombination; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyCodeCombination; -import javafx.scene.input.KeyCombination; - -import org.junit.Test; -import static org.junit.Assert.*; - - -/** - * @author mickf - */ -public class KeystrokeUtilsTest { - - /* - ** check that a KeyCombination constructed with a KeyCodeCombination - ** and one constucted with a KeyCharacterCombination will have - ** the same text if they are for the same key. - */ - @Test public void SameDisplayStringKeyCombinationForCharOrCode() { - - KeyCodeCombination acceleratorKeyComboACode = - new KeyCodeCombination(KeyCode.A, KeyCombination.CONTROL_DOWN); - - KeyCharacterCombination acceleratorKeyComboAChar = - new KeyCharacterCombination("A", KeyCombination.CONTROL_DOWN); - - - KeyCombination kcACode = acceleratorKeyComboACode; - KeyCombination kcAChar = acceleratorKeyComboAChar; - - String codeAString = KeystrokeUtils.toString(kcACode); - String charAString = KeystrokeUtils.toString(kcAChar); - - assertTrue(codeAString.equals(charAString)); - } - - - /* - ** check that an accelerator constructed with a Shortcut - ** displays appropriate platform text. - */ - @Test public void checkShortcutModifierChangesDisplayString() { - KeyCombination acceleratorShortcutA = KeyCodeCombination.keyCombination("Shortcut+A"); - String shortcutAString = KeystrokeUtils.toString(acceleratorShortcutA); - - if (com.sun.javafx.PlatformUtil.isMac()) { - KeyCodeCombination acceleratorMetaA = - new KeyCodeCombination(KeyCode.A, KeyCombination.META_DOWN); - String metaAString = KeystrokeUtils.toString(acceleratorMetaA); - - assertTrue(shortcutAString.equals(metaAString)); - } - else { - KeyCodeCombination acceleratorControlA = - new KeyCodeCombination(KeyCode.A, KeyCombination.CONTROL_DOWN); - String controlAString = KeystrokeUtils.toString(acceleratorControlA); - - assertTrue(shortcutAString.equals(controlAString)); - } - } - - - /* - ** check - */ - @Test public void validStringForNonKeyCode() { - - KeyCharacterCombination acceleratorKeyCombo = - new KeyCharacterCombination("["); - - String comboString = KeystrokeUtils.toString(acceleratorKeyCombo); - - assertTrue(comboString.equals("[")); - } - - - /* - ** check that the KeyCodeCombination for KeyCode.DELETE produces something printable. - ** We only display the unicode DELETE char on mac, otherwise we use "Delete". - */ - @Test public void validStringForDELETE() { - - KeyCodeCombination keyComboDELETE = new KeyCodeCombination(KeyCode.DELETE); - - String shortcutString = KeyCodeUtils.getAccelerator(keyComboDELETE.getCode()); - - if (com.sun.javafx.PlatformUtil.isMac()) { - assertTrue(shortcutString.equals("\u2326")); - } - else { - assertTrue(shortcutString.equals("Delete")); - } - } - - -} diff --git a/modules/graphics/src/main/java/javafx/scene/input/KeyCharacterCombination.java b/modules/graphics/src/main/java/javafx/scene/input/KeyCharacterCombination.java --- a/modules/graphics/src/main/java/javafx/scene/input/KeyCharacterCombination.java +++ b/modules/graphics/src/main/java/javafx/scene/input/KeyCharacterCombination.java @@ -145,6 +145,15 @@ .append('\'').toString(); } + /** {@inheritDoc} */ + @Override + public String getDisplayText() { + StringBuilder sb = new StringBuilder(); + sb.append(super.getDisplayText()); + sb.append(getCharacter()); + return sb.toString(); + } + /** * Tests whether this {@code KeyCharacterCombination} equals to the * specified object. diff --git a/modules/graphics/src/main/java/javafx/scene/input/KeyCodeCombination.java b/modules/graphics/src/main/java/javafx/scene/input/KeyCodeCombination.java --- a/modules/graphics/src/main/java/javafx/scene/input/KeyCodeCombination.java +++ b/modules/graphics/src/main/java/javafx/scene/input/KeyCodeCombination.java @@ -138,6 +138,39 @@ return sb.append(code.getName()).toString(); } + /** {@inheritDoc} */ + @Override + public String getDisplayText() { + StringBuilder sb = new StringBuilder(); + sb.append(super.getDisplayText()); + final int initialLength = sb.length(); + + char c = getSingleChar(code); + if (c != 0) { + sb.append(c); + return sb.toString(); + } + + // Compute a name based on the enum name, e.g. F13 becomes F13 and + // NUM_LOCK becomes Num Lock + String name = code.toString(); + + // We only want the first letter to be upper-case, so we convert 'ENTER' + // to 'Enter' -- and we also convert multiple words separated by _ + // such that each individual word is capitalized and the underline replaced + // by spaces. + + String[] words = com.sun.javafx.Utils.split(name, "_"); + for (String word : words) { + if (sb.length() > initialLength) { + sb.append(' '); + } + sb.append(word.charAt(0)); + sb.append(word.substring(1).toLowerCase()); + } + return sb.toString(); + } + /** * Tests whether this {@code KeyCodeCombination} equals to the specified * object. @@ -184,4 +217,75 @@ "Key code must differ from undefined value!"); } } + + /** Compute a single suitable char summarizing the code, if any, and 0 otherwise. */ + private static char getSingleChar(KeyCode code) { + switch (code) { + case ENTER: return '\u21B5'; + case LEFT: return '\u2190'; + case UP: return '\u2191'; + case RIGHT: return '\u2192'; + case DOWN: return '\u2193'; + case COMMA: return ','; + case MINUS: return '-'; + case PERIOD: return '.'; + case SLASH: return '/'; + case SEMICOLON: return ';'; + case EQUALS: return '='; + case OPEN_BRACKET: return '['; + case BACK_SLASH: return '\\'; + case CLOSE_BRACKET: return ']'; + case MULTIPLY: return '*'; + case ADD: return '+'; + case SUBTRACT: return '-'; + case DECIMAL: return '.'; + case DIVIDE: return '/'; + case BACK_QUOTE: return '`'; + case QUOTE: return '"'; + case AMPERSAND: return '&'; + case ASTERISK: return '*'; + case LESS: return '<'; + case GREATER: return '>'; + case BRACELEFT: return '{'; + case BRACERIGHT: return '}'; + case AT: return '@'; + case COLON: return ':'; + case CIRCUMFLEX: return '^'; + case DOLLAR: return '$'; + case EURO_SIGN: return '\u20AC'; + case EXCLAMATION_MARK: return '!'; + case LEFT_PARENTHESIS: return '('; + case NUMBER_SIGN: return '#'; + case PLUS: return '+'; + case RIGHT_PARENTHESIS: return ')'; + case UNDERSCORE: return '_'; + case DIGIT0: return '0'; + case DIGIT1: return '1'; + case DIGIT2: return '2'; + case DIGIT3: return '3'; + case DIGIT4: return '4'; + case DIGIT5: return '5'; + case DIGIT6: return '6'; + case DIGIT7: return '7'; + case DIGIT8: return '8'; + case DIGIT9: return '9'; + default: + break; + } + + /* + ** On Mac we display these unicode symbols, + ** otherwise we default to the Text version of the char. + */ + if (com.sun.javafx.PlatformUtil.isMac()) { + switch (code) { + case BACK_SPACE: return '\u232B'; + case ESCAPE: return '\u238B'; + case DELETE: return '\u2326'; + default: + break; + } + } + return 0; + } } diff --git a/modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java b/modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java --- a/modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java +++ b/modules/graphics/src/main/java/javafx/scene/input/KeyCombination.java @@ -275,6 +275,51 @@ } /** + * Returns a string representation of this {@code KeyCombination} that is + * suitable for display in a user interface (for example, beside a menu item). + * + * @return A string representation of this {@code KeyCombination}, suitable + * for display in a user interface. + */ + public String getDisplayText() { + StringBuilder stringBuilder = new StringBuilder(); + if (com.sun.javafx.PlatformUtil.isMac()) { + // Macs have a different convention for keyboard accelerators - + // no pluses to separate modifiers, and special symbols for + // each modifier (in a particular order), etc + if (getControl() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("\u2303"); + } + if (getAlt() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("\u2325"); + } + if (getShift() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("\u21e7"); + } + if (getMeta() == KeyCombination.ModifierValue.DOWN || getShortcut() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("\u2318"); + } + // TODO refer to RT-14486 for remaining glyphs + } + else { + if (getControl() == KeyCombination.ModifierValue.DOWN || getShortcut() == KeyCombination.ModifierValue.DOWN ) { + stringBuilder.append("Ctrl+"); + } + if (getAlt() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("Alt+"); + } + if (getShift() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("Shift+"); + } + if (getMeta() == KeyCombination.ModifierValue.DOWN) { + stringBuilder.append("Meta+"); + } + } + + return stringBuilder.toString(); + } + + /** * Tests whether this {@code KeyCombination} equals to the specified object. * * @param obj the object to compare to diff --git a/modules/graphics/src/test/java/javafx/scene/input/KeyCombinationTest.java b/modules/graphics/src/test/java/javafx/scene/input/KeyCombinationTest.java --- a/modules/graphics/src/test/java/javafx/scene/input/KeyCombinationTest.java +++ b/modules/graphics/src/test/java/javafx/scene/input/KeyCombinationTest.java @@ -501,4 +501,64 @@ assertEquals("Alt'Q'\\'", ((KeyCharacterCombination) multiChar).getCharacter()); } + + + + + // ------ Tests for getDisplayText() method + + /* + * check that a KeyCombination constructed with a KeyCodeCombination + * and one constucted with a KeyCharacterCombination will have + * the same text if they are for the same key. + */ + @Test public void SameDisplayStringKeyCombinationForCharOrCode() { + + KeyCodeCombination acceleratorKeyComboACode = + new KeyCodeCombination(KeyCode.A, KeyCombination.CONTROL_DOWN); + + KeyCharacterCombination acceleratorKeyComboAChar = + new KeyCharacterCombination("A", KeyCombination.CONTROL_DOWN); + + assertEquals(acceleratorKeyComboACode.getDisplayText(), acceleratorKeyComboAChar.getDisplayText()); + } + + /* + * check that an accelerator constructed with a Shortcut + * displays appropriate platform text. + */ + @Test public void checkShortcutModifierChangesDisplayString() { + KeyCombination acceleratorShortcutA = KeyCodeCombination.keyCombination("Shortcut+A"); + + if (com.sun.javafx.PlatformUtil.isMac()) { + KeyCodeCombination acceleratorMetaA = + new KeyCodeCombination(KeyCode.A, KeyCombination.META_DOWN); + + assertEquals(acceleratorShortcutA.getDisplayText(), acceleratorMetaA.getDisplayText()); + } else { + KeyCodeCombination acceleratorControlA = + new KeyCodeCombination(KeyCode.A, KeyCombination.CONTROL_DOWN); + + assertEquals(acceleratorShortcutA.getDisplayText(), acceleratorControlA.getDisplayText()); + } + } + + @Test public void validStringForNonKeyCode() { + KeyCharacterCombination acceleratorKeyCombo = new KeyCharacterCombination("["); + assertEquals("[", acceleratorKeyCombo.getDisplayText()); + } + + /* + * check that the KeyCodeCombination for KeyCode.DELETE produces something printable. + * We only display the unicode DELETE char on mac, otherwise we use "Delete". + */ + @Test public void validStringForDELETE() { + KeyCodeCombination keyComboDELETE = new KeyCodeCombination(KeyCode.DELETE); + + if (com.sun.javafx.PlatformUtil.isMac()) { + assertEquals("\u2326", keyComboDELETE.getDisplayText()); + } else { + assertEquals("Delete", keyComboDELETE.getDisplayText()); + } + } }