Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  KeyEvent.getKeyText() on mac  (Read 3442 times)
0 Members and 1 Guest are viewing this topic.
Offline oByhring

Senior Newbie


Medals: 1



« Posted 2012-08-23 19:42:17 »

Hi!

I'm using KeyEvent.getkeyText() to return a string representation of a keycode in a game I'm making. For example, the keycode for enter should be translated to the string "Enter". This applies to space, shift, cmd and similar keys as well.

This works on windows machines, but not in osx for some reason.

KeyEvent.getKeyText(32); returns "?" on macs and "Space" on windows machines.

Help?
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2012-08-23 21:53:02 »

What does Toolkit.getProperty("AWT.space", "Space"); return on your Mac?

Also, what OSX and Java version are you using?

Offline Best Username Ever

Junior Duke





« Reply #2 - Posted 2012-08-23 22:07:35 »

Don't use magic numbers. First, constants are usually defined for good reason. Their values could vary between different platforms to reflect the differences in those platforms and are there to enable better coding practices. Using constants instead of magic numbers ensures that your code is cross platform and forwards compatible with new Java versions. Second, key codes are not equivalent to characters. The return value of that function is also dependent on the user's platform, keyboard, and language. Try KeyEvent.getKeyText(KeyEvent.VK_SPACE).

Quote
"Key pressed" and "key released" events are lower-level and depend on the platform and keyboard layout. They are generated whenever a key is pressed or released, and are the only way to find out about keys that don't generate character input (e.g., action keys, modifier keys, etc.). The key being pressed or released is indicated by the getKeyCode method, which returns a virtual key code.

Virtual key codes are used to report which keyboard key has been pressed, rather than a character generated by the combination of one or more keystrokes (such as "A", which comes from shift and "a").

Quote
public static String getKeyText(int keyCode)

    Returns a String describing the keyCode, such as "HOME", "F1" or "A". These strings can be localized by changing the awt.properties file.

    Returns:
        a string containing a text description for a physical key, identified by its keyCode
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2012-08-23 22:15:54 »

VK_SPACE has always, is always, and will always be 32. OP might be from another language where 32 is commonly used so it's fine for this case.

Also, the KeyEvent keycodes for 0-9 and A-Z do correspond to their ASCII counterparts.

Offline davedes
« Reply #4 - Posted 2012-08-23 22:26:50 »

On Mac, KeyEvent.getKeyText should return the unicode character (e.g. "\u2318" for the command symbol) for proper use with menu items and accelerators. I can confirm that VK_META returns "\u2318" on my Mac, which is then printed to the console as '?'. VK_SPACE also turns into a '?'.

It's pretty useless for debugging and practical purposes, though... Especially games with limited character sets for their bitmap fonts.

Since there are so many keys that would be displayed as "?" on Mac (alt, control, shift, escape, tab, left, up, etc) I would suggest rolling your own KeyEvent-to-text, e.g.
http://www.java-gaming.org/?action=pastebin&id=247

(Ideally much of that would be put into a properties file for localization...)


Quote
VK_SPACE has always, is always, and will always be 32. OP might be from another language where 32 is commonly used so it's fine for this case.

Also, the KeyEvent keycodes for 0-9 and A-Z do correspond to their ASCII counterparts.
As stated in the KeyEvent javadocs:

WARNING: Aside from those keys that are defined by the Java language (VK_ENTER, VK_BACK_SPACE, and VK_TAB), do not rely on the values of the VK_ constants. Sun reserves the right to change these values as needed to accomodate a wider range of keyboards in the future.

Offline Best Username Ever

Junior Duke





« Reply #5 - Posted 2012-08-23 22:47:46 »

I was afraid someone would call me out on something I said because I was too lazy to hunt down the details, but I can't believe I missed the warning message. Now that I found it by using ?+F I am surprised I missed something in plain sight. Wink (Still, magic numbers in that type of context are evil.) I wonder what the justification behind single character key text Strings could have been. That and what program used an ASCII replacement character for unknown Unicode characters.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 816
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #6 - Posted 2012-08-24 11:26:46 »

As stated in the KeyEvent javadocs:

WARNING: Aside from those keys that are defined by the Java language (VK_ENTER, VK_BACK_SPACE, and VK_TAB), do not rely on the values of the VK_ constants. Sun reserves the right to change these values as needed to accomodate a wider range of keyboards in the future.
Funny thing that those constants are 'burnt' into the classfiles, instead of looked up at runtime. So if you were to use the constant VK_SPACE years ago, the very same classfile/jar would contain a constant not equal to VK_SPACE.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline sproingie

JGO Kernel


Medals: 202



« Reply #7 - Posted 2012-08-24 16:27:46 »

The VK_* fields on KeyEvent are not final, so they could in fact be changed.  Still, the odds of that happening, especially now, are vanishingly small.
Offline Best Username Ever

Junior Duke





« Reply #8 - Posted 2012-08-24 21:59:40 »

Funny thing that those constants are 'burnt' into the classfiles, instead of looked up at runtime. So if you were to use the constant VK_SPACE years ago, the very same classfile/jar would contain a constant not equal to VK_SPACE.

I did not follow that. That seems self contradictory. Wouldn't "burnt into" mean something was made permanent?

Maybe you're confused. There are constants baked into the class at compile time, but all those VK_THINGS are static variables. When the class is loaded at run time, they get their default values, which are defined by an offset to a class file constant. By the time your code gets access to them, they all store the correct values. I guess they could get changed since they're not final, but assuming nothing loads, unloads, and reloads the class and no Java code, outside code, bugs, or solar flares change them, then they're going to stay the same at run time. And unless the class gets recompiled or otherwise updated, then their default values should stay the same between executions, too. Magic numbers, on the other hand, do have that exact problem because you're loading them from MyClass.class instead of KeyEvent.class.


@oByhring

Did you mean this character � ? As in "\uFFFD". I read "?" as a String literal instead of plain English. Roll Eyes
Online princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #9 - Posted 2012-08-24 22:18:26 »

The VK_* fields on KeyEvent are not final, so they could in fact be changed.
No they're not, they are final. All references to them by javac will be dereferenced at compile time and the constants baked in to the resulting classfiles. Being public static final, Oracle cannot change them now as they are part of the API contract and it would cause major breakage.

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline davedes
« Reply #10 - Posted 2012-08-24 22:25:16 »

@oByhring

Did you mean this character � ? As in "\uFFFD". I read "?" as a String literal instead of plain English. Roll Eyes
Like I said in my last post, it prints a question mark character: '?'. This is how Mac Terminal displays unicode strings and special characters; there is probably a switch somewhere to enable a wider range of unicode glyphs.

Since getKeyText is localized to the user's AWT properties (i.e. instead of "Shift" or "Enter" as on Windows, it returns a unicode symbol for Mac), it's pretty useless for debugging and other practical purposes. Which is why I'd suggest rolling your own if you're expecting plain text.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #11 - Posted 2012-08-24 23:20:17 »

The VK_* fields on KeyEvent are not final, so they could in fact be changed.
No they're not, they are final.

http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html#VK_1

I don't see 'final'.

Edit.  Oh f**k me.  Javadoc just left it out.  You have to click on a totally separate section to see that they're final.
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #12 - Posted 2012-08-24 23:22:49 »

Please tell me you're being sarcastic....I can clearly see them >.>

EDIT: LOL!

Offline sproingie

JGO Kernel


Medals: 202



« Reply #13 - Posted 2012-08-24 23:24:42 »

The 'final' doesn't show up in the Field Summary, only on the field itself.  Piece of crap javadoc.

Offline Best Username Ever

Junior Duke





« Reply #14 - Posted 2012-08-25 00:56:08 »

<rant>

Like I said in my last post, it prints a question mark character: '?'. This is how Mac Terminal displays unicode strings and special characters; there is probably a switch somewhere to enable a wider range of unicode glyphs.

That's ridiculous. Even if a symbol was a good idea for avoiding localization problems they should have at least supported it in their own programs and provide a fallback glyph for all their built in fonts. Angry

Since getKeyText is localized to the user's AWT properties (i.e. instead of "Shift" or "Enter" as on Windows, it returns a unicode symbol for Mac), it's pretty useless for debugging and other practical purposes. Which is why I'd suggest rolling your own if you're expecting plain text.

It's too bad they didn't provide useful localization. You should be able to use a function intended for localization support with other localization functions. For example displaying native and translated versions of the phrase "press the <key name> key to do <x>". Or, for example, telling the user the name of the keys currently configured in a key binding editor. Clueless

</rant>
Offline oByhring

Senior Newbie


Medals: 1



« Reply #15 - Posted 2012-08-25 09:12:45 »


Thanks for all the replies everyone Smiley

Or, for example, telling the user the name of the keys currently configured in a key binding editor. Clueless

This is exactly what I am doing.

I've been developing this game for the windows platform the entire time, and I'm just doing the finishing touches on the mac export now.

If I understood you all correctly, what I need to do is make my own method for translating keycodes to text?

Something like this:

if(keycode == KeyEvent.VK_SPACE){
    return "Space";
}
else {...

for the most relevant keys (Space, Enter, Shift, CMD, Alt++?
Offline Best Username Ever

Junior Duke





« Reply #16 - Posted 2012-08-25 16:22:12 »

You could write a function like isBadKeyText(s) that takes a String and returns true if it contains only private use characters or non-printable glyph. Then you can either write your own translations, use reflection to get the English/Java name, or hardcode a default name in one language. You could also use the isBadKeyText(s) method to decide how to display a key as a fallback on platforms like that. For example you could try writing "� (Space)", "� 32" (key number), or "Special Key #32".
Offline davedes
« Reply #17 - Posted 2012-08-25 19:30:15 »

Just use the code I posted earlier. It will give you printable text based on the VK_XX field name (e.g. VK_SHIFT => "Shift"). It also has a few exceptional cases, like VK_META => "Command" (Mac) or "Windows Key" (other platforms), and control characters less than 32 (e.g. Control + D) will return the expected key (e.g. "D").

Just another Mac note... If a user holds Alt (aka "Option") and enters a letter key, it will show up as a symbol like 'ƒ' instead of F or '√' instead of V. If you want the returned text to be the key itself (rather than the inserted symbol), use the text from the VK_ field (code) rather than the result of keyEvent.getKeyChar.

Offline Best Username Ever

Junior Duke





« Reply #18 - Posted 2012-08-25 20:24:43 »

Just use the code I posted earlier. It will give you printable text based on the VK_XX field name (e.g. VK_SHIFT => "Shift"). It also has a few exceptional cases, like VK_META => "Command" (Mac) or "Windows Key" (other platforms), and control characters less than 32 (e.g. Control + D) will return the expected key (e.g. "D").

A few comments. First, why not call put the result of fixName into the map? Second, you assume that if you're not using a Mac then you're using a Windows computer. Finally, you override the default key text look up no matter what. This will cause problems if the user speaks a different language, uses a different type of keyboard, does not understand what key the Java constant name refers to, or if platform's key naming conventions change.

Instead, all you really need to replace are those single glyph names. Someone might fix that problem on Apple's Java platform in the near future so that getKeyText actually returns text. That way you can work around the problem and only the problematic part without maintaining separate properties files or diverging from the expected key naming conventions.

Just another Mac note... If a user holds Alt (aka "Option") and enters a letter key, it will show up as a symbol like 'ƒ' instead of F or '√' instead of V. If you want the returned text to be the key itself (rather than the inserted symbol), use the text from the VK_ field (code) rather than the result of keyEvent.getKeyChar.

That's true for all platforms.
Offline davedes
« Reply #19 - Posted 2012-08-25 21:16:43 »

A few comments. First, why not call put the result of fixName into the map?
The idea is that you may want to localize words like "Up" and "Print Screen", at which point the string "PRINT_SCREEN" would be a better key (i.e. for a properties file) than "Print Screen". In either case, the performance difference is negligible, so its ultimately up to preference...

Quote
Second, you assume that if you're not using a Mac then you're using a Windows computer.
Ultimately it has to do with keyboard manufacturer. An Apple computer uses the terms "Command" and "Option". Microsoft, Logitech, HP, etc. keyboards use the "Windows Key" and "Alt" buttons (even if it's on a Linux OS). Linux users call it the "Windows Key" unless I'm mistaken...

Quote
Finally, you override the default key text look up no matter what. This will cause problems if the user speaks a different language, uses a different type of keyboard, does not understand what key the Java constant name refers to, or if platform's key naming conventions change.
Hence my comment in code: "this should really be localized in a properties file!"

Yes, it would probably be best to use the AWT localizations as much as possible. My code was just a brief example of an alternative; instead of trying to nitpick it line by line, why don't you write up your own solution and post it? Roll Eyes

Quote
Just another Mac note... If a user holds Alt (aka "Option") and enters a letter key, it will show up as a symbol like 'ƒ' instead of F or '√' instead of V. If you want the returned text to be the key itself (rather than the inserted symbol), use the text from the VK_ field (code) rather than the result of keyEvent.getKeyChar.

That's true for all platforms.
Uhh.. Nope.

Offline Best Username Ever

Junior Duke





« Reply #20 - Posted 2012-08-26 01:23:07 »

The Windows/Apple logo thing is a little like the market for Coke/Pepsi products. There have been exceptions in the past and still may be in the future. Even if today's keyboard manufacturers are in that type of market, there is no guarantee that future devices will be "backwards compatible" or cross compatible with rare keyboard-like peripherals. I've heard Linux users refer to the same key as the "Super" or "Meta" key and perhaps one other name I can't recall at the moment. Imagine a user accustomed to the term Super key running a Linux operating system on a Macbook laptop being told to press the Windows key.

I was actually going to make some wiki-like edits to your example, but decided on something more general because there are so many standards to choose from when it comes to localization. A list of simple caveats shouldn't be unwelcome.

Quote
Just another Mac note... If a user holds Alt (aka "Option") and enters a letter key, it will show up as a symbol like 'ƒ' instead of F or '√' instead of V. If you want the returned text to be the key itself (rather than the inserted symbol), use the text from the VK_ field (code) rather than the result of keyEvent.getKeyChar.

That's true for all platforms.
Uhh.. Nope.

What did you mean then? The JavaDoc makes a distinction between key codes (which are relevant to KEY_PRESSED or KEY_RELEASED events) and key chars (which are relevant only to KEY_TYPED events.) Part of the class descriptions even mentions such a scenario for Windows platforms.

Quote
"Key typed" events are higher-level and generally do not depend on the platform or keyboard layout. They are generated when a Unicode character is entered, and are the preferred way to find out about character input. In the simplest case, a key typed event is produced by a single key press (e.g., 'a'). Often, however, characters are produced by series of key presses (e.g., 'shift' + 'a'), and the mapping from key pressed events to key typed events may be many-to-one or many-to-many. Key releases are not usually necessary to generate a key typed event, but there are some cases where the key typed event is not generated until a key is released (e.g., entering ASCII sequences via the Alt-Numpad method in Windows). No key typed events are generated for keys that don't generate Unicode characters (e.g., action keys, modifier keys, etc.).
Offline davedes
« Reply #21 - Posted 2012-08-27 04:37:06 »

I've heard Linux users refer to the same key as the "Super" or "Meta" key and perhaps one other name I can't recall at the moment. Imagine a user accustomed to the term Super key running a Linux operating system on a Macbook laptop being told to press the Windows key.
Likewise... Imagine a user accustomed to "Windows Key" is faced with the words "Super" or "Meta". Generally speaking, since the Windows icon appears on almost every non-Apple keyboard, most Linux users will be more accustomed to "Windows Key" than "Super/Meta".

The point is; Apple consistently uses terms like "Command" and "Option", whereas the vast majority of other keyboard manufacturers (and operating systems) tend to use the terms "Alt", "Control" and "Windows Key". In any case, the code I posted is just a sample; if you want more flexibility and localization, write it in yourself or use AWT properties.

Quote
What did you mean then? The JavaDoc makes a distinction between key codes (which are relevant to KEY_PRESSED or KEY_RELEASED events) and key chars (which are relevant only to KEY_TYPED events.) Part of the class descriptions even mentions such a scenario for Windows platforms.
My point was that the "Alt + [Key]" combination (e.g. Alt + F => ƒ) is an Apple feature that isn't mirrored on all platforms/keyboards.

I have nothing wrong with criticism, but you seem intent on nitpicking a simple code sample I offered to the OP. If you want to be useful, post some alternative/better code using your "isBadKeyText" idea. (I am genuinely curious as to how you would implement that...)

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (49 views)
2014-10-17 03:59:02

Norakomi (39 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (35 views)
2014-10-15 16:18:58

TehJavaDev (65 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!