NiftyTextField: input of japanese letters

Hello,
I have some troubles for the localization of my game (Win/Mac/Linux). The output of japanse fonts works well, but the japanse testers tell me, that the japanse keyboard input in a nifty textfileld is ignored. They can use only english letters. A am a little bit lost now, and any help is very much appreciated.

Michael

you can change to use tonegodgui. it is available after you download the plugin from the plugins window
it support bitmap text for chinese so I think it can support japanese too.
just add: window/button/panel.setFont(“FontPath”);

Many thanks, but it is not a problem of the font. The bimap font is properly displayayd (including the japanese letters). The problem is that the key INPUT is ignored in the text field.

Michael

@harry1315 said: you can change to use tonegodgui. it is available after you download the plugin from the plugins window it support bitmap text for chinese so I think it can support japanese too. just add: window/button/panel.setFont("FontPath");
that gui library isn't supported anymore, nifty uses bitmapfonts too. @void256 any filtering going on in nifty that could cause this maybe? Or is it jMEs input stage dropping these? @Michael Does this happen with other jme input too? (e.g. when using the keyboard to control the game)

Thanks for your help. To make it more clear, here a complete description of what I found out:

TextInput with nifty:

  1. Works in principle for me (Win7) but I cannot input e.g. the @
  2. Some testers (europe) say, on Mac, the input of öäü does not work (for me it works)
  3. Japanese users say: The input of japanese letters does not work

Keyboard input in the game with jme3:
Works fine for me, but.e.g. the @ I cannot test, since i only observe the keys and not the letters (@ = AltGr 2 on my swiss keyboard)

I tried to look for keyboard events and there I got something for the @ which is somehow not trasferred to the NiftyTextInput.

Thanks for our help If I can do more debugging or so, let me know…

Michael

The “@” thing should be fixed in a more recent version of Nifty as I looked into that myself earlier this year.

Nifty does do some filtering on the input and maybe its losing the japanese characters, I’m honestly not sure though.

How are japanese characters entered? I seem to remember there is some complexities involved.

Hello,

sorry for the delay, I was not available a couple of days. I wanted to make sure that I have the latest version to try again the @-thing, but the nightly builds seem to be broken.

Thanks,

Michael

@zarch Japanese input goes through an “Input Method Handler” on Windows.
That’s normally not a problem since the AWT takes care of converting that to a stream of Unicode characters (and all Japanese characters are, at most, 16-bit, none of these supplementary character set, double-word complications needed).

Normally, I’d say that providing character input is the task of AWT’s keyboard handler. It’s not uncommon for game platforms to ignore the character stream and stick with the keycode stream, trying to build their own character stream from keycode events (and usually they all fail, one way or the other).
I haven’t checked whether JME and Nifty are going that route, too.

Hello,

I updated to the last version of jme3 from svn. The @ thing is solved, and the other problems can already be seen with western characters:

On Windows and Mac the @ works in the input.
On Windows: ö ä ü etc. works
On OS-X the charactrer input from the keyboard of ö ä ü does not work.

Ths display of the characters is not a problem.

Thanks again fpr the discussion.

Michael

Well, I don’t know where the problem might be. At a first glance the way an input event is being processed looks valid.

Here are the steps:

  1. The InputSystemJme.java receives a KeyInputEvent and forwards it to Nifty as a KeyboardInputEvent instance (which carries the original character as a Java char - so this should be ok, right?)

[java]private void onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic) {
int code = evt.getKeyCode();

    if (code == KeyInput.KEY_LSHIFT || code == KeyInput.KEY_RSHIFT) {
        shiftDown = evt.isPressed();
    } else if (code == KeyInput.KEY_LCONTROL || code == KeyInput.KEY_RCONTROL) {
        ctrlDown = evt.isPressed();
    }

    KeyboardInputEvent keyEvt = new KeyboardInputEvent(code,
            evt.getKeyChar(),
            evt.isPressed(),
            shiftDown,
            ctrlDown);

    if (nic.processKeyboardEvent(keyEvt)) {
        evt.setConsumed();
    }
}

[/java]

  1. The de.lessvoid.nifty.controls.textfield.TextFieldInputMapping class inside of Nifty will check the de.lessvoid.nifty.input.keyboard.KeyboardInputEvent instance for special keys like cursor up/down etc. since these are treated special inside of Nifty.

So the KeyboardInputEvent is translated inside of Nifty into a NiftyStandardInputEvent enum by the TextFieldInputMapping class. There is a special case enum NiftyStandardInputEvent.Character that is being used if the KeyboardInputEvent contained not one of the special characters but some other “real” character. In that case the character is stored, again as a Java char directly at the enum.

[java] private static NiftyStandardInputEvent handleKeyDownEvent(final KeyboardInputEvent inputEvent) {
switch (inputEvent.getKey()) {
case KeyboardInputEvent.KEY_UP:
return NiftyStandardInputEvent.MoveCursorUp;
case KeyboardInputEvent.KEY_DOWN:
return NiftyStandardInputEvent.MoveCursorDown;
… more code like the above removed for clearity …
default:
break;
}

if (!Character.isISOControl(inputEvent.getCharacter())) {
  final NiftyStandardInputEvent character = NiftyStandardInputEvent.Character;
  character.setCharacter(inputEvent.getCharacter());
  return character;
}
return null;

}
[/java]

  1. The NiftyInputEvent enum is send to the inputEvent() method of the de.lessvoid.nifty.controls.textfield.Textfield control which processes all of the cursor movements, etc. as well as insert the Character into the textfield String:

[java] public boolean inputEvent(final NiftyInputEvent inputEvent) {
if (inputEvent == null) {
return false;
}

final NiftyStandardInputEvent standardInputEvent = (NiftyStandardInputEvent) inputEvent;
switch (standardInputEvent) {
  case MoveCursorLeft:
    textField.cursorLeft();
    break;
  case MoveCursorRight:
    textField.cursorRight();
    break;

… more code like the above removed for clearity …
case Character:
textField.insert(standardInputEvent.getCharacter());
break;

[/java]

So again here the character is treated as a Java char data type. Should be ok.

  1. In newer versions of Nifty it’s possible to enable filtering of characters at the Textfield level by implementing a de.lessvoid.nifty.controls.textfield.filter.input.TextFieldInputFilter interface

However by default a de.lessvoid.nifty.controls.textfield.filter.input.FilterAcceptAll instance is used which does not filter any characters.

Well, it really would be interesting at which level we’ll lose the chinese characters. Can somebody check this with a debugger or something? I don’t know how to enter chinese characters o_O

Something to test is to cut and paste the chinese characters in and see if that works.

It may well be that these are actually entered as a sequence of keypresses in which case the code to actually turn that sequence into a single character would be needed.

<cite>@normen said:</cite> that gui library isn't supported anymore, nifty uses bitmapfonts too. @void256 any filtering going on in nifty that could cause this maybe? Or is it jMEs input stage dropping these? @Michael Does this happen with other jme input too? (e.g. when using the keyboard to control the game)

You’re not supporting this library anymore?? I’m crushed! I thought I had your full support :wink:

@t0neg0d said: You're not supporting this library anymore?? I'm crushed! I thought I had your full support ;)

Yeah, I thought you were crushed, thats what you said. You’re working on this library again?

@zarch said: Something to test is to cut and paste the chinese characters in and see if that works.

It may well be that these are actually entered as a sequence of keypresses in which case the code to actually turn that sequence into a single character would be needed.

I’ve tested cut and paste and although I can’t see the chinese character in the textfield (because I don’t have a chinese font) the character is inserted into the StringBuilder that stores the textfield data. I think that this worked.

It’s not the same as using a keyboard to enter the characters directly. Any idea @Michael?

Hello,

I think we can alayse this issue also without the japanese fonts (at least on a Mac). I tested:

MAC-OS-X:

Inputting ö ä ü does not work, The characters are not displayed in the text field.
Pasting ö ä ü from the clipboard into the textfield wrks perfect.

WIN7:
Inputting of € (AltGr+E on my Keyboard) does not work.
Pasting it into the textfield also does NOT work.

Maybe that helps.

Thanks for the active discussion!

Michael

Maybe that helps to isolate where the problem might be.

<cite>@normen said:</cite> Yeah, I thought you were crushed, thats what you said. You're working on this library again?

Yeah… kinda hard not to as it is what I use =) Most of the questions I get regarding it have been via PMs

@Michael said: MAC-OS-X:

Inputting ö ä ü does not work, The characters are not displayed in the text field.
Pasting ö ä ü from the clipboard into the textfield wrks perfect.

Ok, I’ve tested the ö character on Mac OSX 10.8.4 with Java 1.6.0_29 and 1.7.0_21 and it does indeed not work. I don’t get a ö character from jme in the com.jme3.input.event.KeyInputEvent class. The keyChar member is empty.

I’ve tried it with an old nightly build of jme (one I had checked out from svn a while ago) and there it worked! Then I’ve updated to latest svn, build it and it does not work anymore.

Has keyboard event processing changed inside of jme in the last months or is there something special to do to get the character?

<cite>@void256 said:</cite> Has keyboard event processing changed inside of jme in the last months or is there something special to do to get the character?
Maybe something changed in LWJGL. Supporting Mac is a real challenge :s I don't want to blame its maintainers.

If Nifty monitors only KEY_PRESSED and KEY_RELEASE KeyEvents, it’s certainly going to miss text input in the non-straighforward cases. It needs to monitor KEY_TYPED as well.

Here’s what http://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyEvent.html has to say about the issue:

But in some cases (e.g. auto-repeat or input method is activated) the order could be different (and platform dependent).

In other words, monitor KEY_TYPED KeyEvents as well, and you’ll get the system’s default keyboard repeat and IME semantics as well (which probably nobody can replicate well because you’d need to be with all the IME editors around, which includes some really weird stuff - there are two major IMEs for Simplified Chinese alone, one phonetic, one script-composition-based, and various minor variants).
Oh, and some IMEs will display a compositing window while a character is being built. I sure hope that these are general enough to work in fullscreen mode with OpenGL active. But that’s more of an JME rather than a Nifty issue (and I don’t know how IMEs behave in the presence of fullscreen mode anyway, maybe they just expect you to blind-type).

UPDATE: Okay, http://msdn.microsoft.com/en-us/library/windows/desktop/ee419002(v=vs.85).aspx#using_imes_with_dxut has more on this. Seems like the graphics engine would need to jump through some extra hoops. With luck, LWJGL/JOGL already cover this, otherwise JME would have to do something, or give up on IMEs.

<cite>@toolforger said:</cite> With luck, LWJGL/JOGL already cover this, otherwise JME would have to do something, or give up on IMEs.
JOGL NEWT has no typed events, we removed them because they weren't necessary and other events already contain the expected characters whereas it isn't the case in AWT. Accentuated characters work in NEWT but I have never tested with simplified Chinese.