Luke
Luke

Reputation: 1306

Windowlicker is not working on OS X

I have an issue with windowlicker on OS X ( everything works ok on Windows ). The issue is that when I try to simulate user input to any text field the data is not inserted properly ( some letters are cut out ).

For instance:

JTextFieldDriver txField = new JTextFieldDriver(this, 
                                                JTextField.class, 
                                                named(fieldName));
txField.focusWithMouse();
txField.typeText(input);

Preceding code will result in that I will observe windowlicker inserting input to a text field named fieldName and the input will be incomplete ( Peter will be Peer or Fred will be Fre and so on ). Everything works properly on windows.

I am not sure if all that has anything to do with a warning. I get similar on windows. The warning is: "WARNING: could not load keyboard layout Mac-, using fallback layout with reduced capabilities (JAR entry com/objogate/wl/keyboard/Mac- not found in /Users/odo/.m2/repository/com/googlecode/windowlicker/windowlicker-core/r268/windowlicker-core-r268.jar)"

Upvotes: 1

Views: 347

Answers (1)

Luke
Luke

Reputation: 1306

Windowlicker seems not to be very popular tool. Nevertheless I managed to figure out the root cause. The warning stating that keyboard layout can't be set is displayed because I am not using english locale. It looks like windowlicker supports only Mac-GB keyboard layout. The warning will go away if an appropriate system property is set. For instance:

System.setProperty("com.objogate.wl.keyboard", "Mac-GB");

However this will not solve the main problem. After couple trials I figured out that only 'a' and 'd' characters are trimmed. This is because windowlicker inserts them as if user would hold the 'a' or 'd' key for a bit. Holding those keys results in a helper menu invocation which allows to select special characters. In order to fix that I played with the JTextComponentDriver and found a workaround. The solution is not to use driver's typeText to insert text. JTextComponentDriver's component() method can be used to retrieve the actual guy component and then having an instance setText() can be invoked to set the text.

Below I present my helper class which is using described solution:

public class TextTyper {
    private final String inputText;

    privte TextTyper(String inputText) {
        this.inputText = inputText;
    }

    public static TextTyper typeText( final String inputText ){
        return new TextTyper( inputText );
    }

    public void into( JTextComponentDriver<?> driver ) throws Exception{
        driver.focusWithMouse();
        driver.clearText();

        Component cmp = driver.component().component();
        if(cmp instanceof JPasswordField ){
            JPasswordField pwField = (JPasswordField) cmp;
            pwField.setText(this.inputText);
        }
        else if( cmp instanceof JTextField){
            JTextField txField = (JTextField) cmp;
            txField.setText(this.inputText);
        }

        else
            throw new Exception("Component is not an instance of JTextField or JPasswordField");
    }
}

Upvotes: 2

Related Questions