Skip to content

Commit a012ce1

Browse files
committed
Add KeyCode.get(char) method
Previously, passing a char to KeyCode would call KeyCode.get(int), which does not do what one might expect. For example, calling KeyCode.get('a') would convert the 'a' character to integer/ASCII code 97, which corresponds to KeyCode.NUMPAD_0! This commit introduces a function that behaves as one would expect KeyCode.get(char) to behave: mapping the actual character value to the key code constant associated with it. So now, KeyCode.get('a') returns KeyCode.A as one might expect. Unfortunately, not all codes have clean character values, and not all characters map unambiguously to key codes; e.g.: * Both 'a' and 'A' map to KeyCode.A * '0' maps to KeyCode.NUM0, not KeyCode.NUMPAD_0 * '/' maps to KeyCode.SLASH, not KeyCode.NUMPAD_SLASH But it's still a big step forward in abiding by PoLA.
1 parent dbf2a7a commit a012ce1

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed

src/main/java/org/scijava/input/KeyCode.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,87 @@ public static KeyCode get(final int code) {
632632
return keyCode;
633633
}
634634

635+
/**
636+
* Gets the KeyCode corresponding to the given character,
637+
* or {@link #UNDEFINED} if no such code.
638+
*/
639+
public static KeyCode get(final char c) {
640+
switch (c) {
641+
case '\n': case '\r': return ENTER;
642+
case '\b': return BACK_SPACE;
643+
case '\t': return TAB;
644+
case 0x1b: return ESCAPE;
645+
case ' ': return SPACE;
646+
case ',': return COMMA;
647+
case '-': return MINUS;
648+
case '.': return PERIOD;
649+
case '/': return SLASH;
650+
case '0': return NUM0;
651+
case '1': return NUM1;
652+
case '2': return NUM2;
653+
case '3': return NUM3;
654+
case '4': return NUM4;
655+
case '5': return NUM5;
656+
case '6': return NUM6;
657+
case '7': return NUM7;
658+
case '8': return NUM8;
659+
case '9': return NUM9;
660+
case ';': return SEMICOLON;
661+
case '=': return EQUALS;
662+
case 'a': case 'A': return A;
663+
case 'b': case 'B': return B;
664+
case 'c': case 'C': return C;
665+
case 'd': case 'D': return D;
666+
case 'e': case 'E': return E;
667+
case 'f': case 'F': return F;
668+
case 'g': case 'G': return G;
669+
case 'h': case 'H': return H;
670+
case 'i': case 'I': return I;
671+
case 'j': case 'J': return J;
672+
case 'k': case 'K': return K;
673+
case 'l': case 'L': return L;
674+
case 'm': case 'M': return M;
675+
case 'n': case 'N': return N;
676+
case 'o': case 'O': return O;
677+
case 'p': case 'P': return P;
678+
case 'q': case 'Q': return Q;
679+
case 'r': case 'R': return R;
680+
case 's': case 'S': return S;
681+
case 't': case 'T': return T;
682+
case 'u': case 'U': return U;
683+
case 'v': case 'V': return V;
684+
case 'w': case 'W': return W;
685+
case 'x': case 'X': return X;
686+
case 'y': case 'Y': return Y;
687+
case 'z': case 'Z': return Z;
688+
case '[': return OPEN_BRACKET;
689+
case '\\': return BACK_SLASH;
690+
case ']': return CLOSE_BRACKET;
691+
case '`': return BACK_QUOTE;
692+
case '\'': return QUOTE;
693+
case '&': return AMPERSAND;
694+
case '*': return ASTERISK;
695+
case '"': return QUOTEDBL;
696+
case '<': return LESS;
697+
case '>': return GREATER;
698+
case '{': return BRACELEFT;
699+
case '}': return BRACERIGHT;
700+
case '@': return AT;
701+
case ':': return COLON;
702+
case '^': return CIRCUMFLEX;
703+
case '$': return DOLLAR;
704+
case '€': return EURO_SIGN;
705+
case '!': return EXCLAMATION_MARK;
706+
case 161: return INVERTED_EXCLAMATION_MARK;
707+
case '(': return LEFT_PARENTHESIS;
708+
case '#': return NUMBER_SIGN;
709+
case '+': return PLUS;
710+
case ')': return RIGHT_PARENTHESIS;
711+
case '_': return UNDERSCORE;
712+
}
713+
return UNDEFINED;
714+
}
715+
635716
/**
636717
* Gets the KeyCode with the given name, or {@link #UNDEFINED} if no such
637718
* code.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2025 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
package org.scijava.input;
31+
32+
import static org.junit.Assert.assertEquals;
33+
import static org.junit.Assert.assertNotNull;
34+
import static org.junit.Assert.assertSame;
35+
36+
import org.junit.Test;
37+
import org.scijava.plugin.PluginInfo;
38+
39+
/**
40+
* Tests {@link KeyCode}.
41+
*
42+
* @author Curtis Rueden
43+
*/
44+
public class KeyCodeTest {
45+
46+
@Test
47+
public void testGetInt() {
48+
assertEquals(KeyCode.ENTER, KeyCode.get(0x0a));
49+
assertEquals(KeyCode.PLUS, KeyCode.get(0x0209));
50+
assertEquals(KeyCode.NUM0, KeyCode.get(0x30));
51+
assertEquals(KeyCode.NUMPAD_0, KeyCode.get(0x60));
52+
assertEquals(KeyCode.A, KeyCode.get(0x41));
53+
assertEquals(KeyCode.Z, KeyCode.get(0x5a));
54+
55+
assertEquals(KeyCode.UNDEFINED, KeyCode.get(0xaaaa));
56+
assertEquals(KeyCode.UNDEFINED, KeyCode.get(0xffff));
57+
}
58+
59+
@Test
60+
public void testGetChar() {
61+
assertEquals(KeyCode.ENTER, KeyCode.get('\n'));
62+
assertEquals(KeyCode.ENTER, KeyCode.get('\r'));
63+
assertEquals(KeyCode.PLUS, KeyCode.get('+'));
64+
assertEquals(KeyCode.NUM0, KeyCode.get('0'));
65+
assertEquals(KeyCode.A, KeyCode.get('a'));
66+
assertEquals(KeyCode.A, KeyCode.get('A'));
67+
assertEquals(KeyCode.Z, KeyCode.get('z'));
68+
assertEquals(KeyCode.Z, KeyCode.get('Z'));
69+
70+
assertEquals(KeyCode.UNDEFINED, KeyCode.get('\0'));
71+
72+
// The following should maybe be considered a bug.
73+
assertEquals(KeyCode.UNDEFINED, KeyCode.get('|'));
74+
}
75+
76+
@Test
77+
public void testGetString() {
78+
assertEquals(KeyCode.PLUS, KeyCode.get("PLUS"));
79+
assertEquals(KeyCode.NUM0, KeyCode.get("NUM0"));
80+
assertEquals(KeyCode.NUMPAD_0, KeyCode.get("NUMPAD_0"));
81+
assertEquals(KeyCode.A, KeyCode.get("A"));
82+
assertEquals(KeyCode.Z, KeyCode.get("Z"));
83+
84+
assertEquals(KeyCode.UNDEFINED, KeyCode.get("UNDEFINED"));
85+
assertEquals(KeyCode.UNDEFINED, KeyCode.get(""));
86+
assertEquals(KeyCode.UNDEFINED, KeyCode.get("aa"));
87+
assertEquals(KeyCode.UNDEFINED, KeyCode.get("asdf"));
88+
}
89+
}

0 commit comments

Comments
 (0)