This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
When tried to type extended character in JTextField, jemmy threw an exception. Code: JTextFieldOperator textField = new JTextFieldOperator (containeroperator, "text"); textField.changeCaretPosition(textField.getText().length()); textField.typeText("\u010d"); // č When I used setText method, it worked fine. But I need typeText because I try to simulate users input. I tried this in robot mode as well, but nothing was typed. Is it correct?
Exception: java.lang.NoSuchFieldException at java.lang.Class.getField0(Native Method) at java.lang.Class.getField(Class.java:826) at com.sun.jemmy.ClassReference.getField (ClassReference.java:128) at com.sun.jemmy.DefaultCharBindingMap.getCharKey (DefaultCharBindingMap.java:133) at com.sun.jemmy.operators.Operator.getCharKey (Operator.java:369) at com.sun.jemmy.operators.ComponentOperator.typeKey (ComponentOperator.java:716) at com.sun.jemmy.operators.JTextComponentOperator$1.launch (JTextComponentOperator.java:420) at com.sun.jemmy.ActionProducer.launchAction (ActionProducer.java:239) at com.sun.jemmy.ActionProducer.run(ActionProducer.java:211) Please see also Issue 18866
Chars are typed by modifiers and keys pushing. Mapping between chars and modifiers/key codes is performed by current CharBindingMap implementation which is defined by JemmyProperty.setDefaultCharBindingMap(CharBindingMap) method. Default CharBindingMap implementation (DefaultCharBindingMap) provides modifiers and keys only for regular chars: "!"#$%&'()*,-./0123456789:;\<\>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" Since you are going to reproduce user input, you, probably know both modifiers an key code. Depending of you need, you have two choices: 1. define you own or extend default CharBindingMap 2. Post necessary events by ComponentOperator.typeKey(int, char, int) method If it is a regular simbol, please specify what it is and I'll add it to default CharBindingMap.
Either new CharBindingMap implementation should be created or ComponentOperator.typeKey(int, char, int) method should be used to type any char which is not common. All those common chars are covered by default CharBindingMap implementation.
I have experimented with key events and Jemmy on Japanese locale and found a solution which could be accepted. All examples are done on Solaris in Japanese locale (EUC). If you bind a KeyListener to a JTextField and type a Japanese characted manually, following events are genereated: java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyChar='?',modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_LEFT] java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyChar='?',modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_LEFT] java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyChar='??',keyLocation=KEY_LOCATION_UNKNOWN] java.awt.event.KeyEvent[KEY_RELEASED,keyCode=32,keyChar=' ',modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_STANDARD] java.awt.event.KeyEvent[KEY_RELEASED,keyCode=17,keyChar='?',keyLocation=KEY_LOCATION_LEFT] Key sequence: CTRL+SPACE, A, CTRL+SPACE Another example: java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyChar='?',modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_LEFT] java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyChar='?',modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_LEFT] java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyChar='??',keyLocation=KEY_LOCATION_UNKNOWN] java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyChar='??',keyLocation=KEY_LOCATION_UNKNOWN] java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyChar='??',keyLocation=KEY_LOCATION_UNKNOWN] java.awt.event.KeyEvent[KEY_RELEASED,keyCode=17,keyChar='?',keyLocation=KEY_LOCATION_LEFT] Key sequence: CTRL+SPACE, N, I, H, O, N, G, O, SPACE, CTRL+SPACE If you want to simulate such input in current Jemmy, you must use robot: JemmyProperties.setCurrentDispatchingModel(JemmyProperties.QUEUE_MODEL_MASK | JemmyProperties.ROBOT_MODEL_MASK); oper.pushKey(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK); oper.pushKey(KeyEvent.VK_A); oper.pushKey(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK); To be honest, using Robot is only way how to simulate users input exactly. But to enable use Jemmy to input extended characters in non-robot mode, I suggest to fix DefaultCharBindingMap.getCharKey() to return VK_UNDEFINED key code for not known characters. Then you can write in Jemmy (without robot): oper.typeKey('\u3042'); // Japanese unicode char (CTRL+SPACE, A, CTRL+SPACE) oper.typeKey('\u010d'); // Czech unicode char oper.typeKey('??'); // ?? stands for native char oper.typeText("\u010d \u3042 ??"); Events fired on JTextField for \u3042 are following: java.awt.event.KeyEvent[KEY_PRESSED,keyCode=0,keyChar='',keyLocation=KEY_LOCATION_UNKNOWN] java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyChar='??',keyLocation=KEY_LOCATION_UNKNOWN] java.awt.event.KeyEvent[KEY_RELEASED,keyCode=0,keyChar='',keyLocation=KEY_LOCATION_UNKNOWN] Compare to event listings done "manually" it seems similar. I think that KEY_TYPED event is the most important. In "NIHONGO" example, no KEY_PRESSED and KEY_RELEASED events for N, I, H, ... were generated on JTextField. So such fix could satisfy users testing on non-English locales. See attachments for suggested fix and examples.
Created attachment 5303 [details] Proposed fix and examples.
DefaultCharBindingMap class should, definitely, be changed. However, I doubt it would make any sense to reduce control level there if a user would have a possibility to extend this class easily. I think it would be enough to allow users to extend this class and control everything there. So, what I would do is: 1. replace arrays with Hashtable (or Vector) 2. make those Hashtable protected, so they could be accessed from a subclass. 3. add a constructor to DefaultCharBindingMap: public DefaultCharBindingMap(<hashtable or vector>) 4. implement protected methods: protected getCharKeyPrimitive(char) throws NoSuchFieldException, IllegalAccessException; protected getCharModifiersPrimitive(char) throws NoSuchFieldException, IllegalAccessException; 5. make DefaultCharBindingMap Outputable, so those exceptions would be printed into correct output stream. After those changes, no metter if user wants to solve problem partially or completely, it would be quite easy to add new symbols support and exception handling simply by extending DefaultCharBindingMap and overriding some methods (changing some fields). Does it make sense?
Seems to me too complicated for users. Additionally, I am not sure if a mapping is possible for Japanese characters where one unicode char is mapped to several keystrokes. Please, give an example what user has to do to be able to use following code: oper.typeKey('\u3042'); // Japanese unicode char (CTRL+SPACE, A, CTRL+SPACE)
DefaultChaBindingMap class has been refactores in 2.1.0 Chars now stored in a hashtable, there are new methods allowing to "customize" char map by adding or removing chars. No exception is thrown even if no binding was found for a char: getCharKey(char) simply returns KeyEvent.VK_UNDEFINED in this case.