Search code examples
javaswteclipse-rcpgui-testingui-testing

Automatically generate IDs on SWT-Widgets


Is there a way to automatically generate IDs on SWT-Widgets so UI-Tests can reference them? I know i can manually set an id using seData but I want to implement this feature for an existing application in a somewhat generic fashion.


Solution

  • You can recursively assign IDs for all your shells in your application using Display.getCurrent().getShells(); and Widget.setData();.

    Setting the IDs

    Shell []shells = Display.getCurrent().getShells();
    
    for(Shell obj : shells) {
        setIds(obj);
    }
    

    You have access to all the active (not disposed) Shells in your application with the method Display.getCurrent().getShells(); . You can loop through all children of each Shell and assign an ID to each Control with the method Widget.setData();.

    private Integer count = 0;
    
    private void setIds(Composite c) {
        Control[] children = c.getChildren();
        for(int j = 0 ; j < children.length; j++) {
            if(children[j] instanceof Composite) {
                setIds((Composite) children[j]);
            } else {
                children[j].setData(count);
                System.out.println(children[j].toString());
                System.out.println(" '-> ID: " + children[j].getData());
                ++count;
            }
        }
    }
    

    If the Control is a Composite it may have controls inside the composite, that's the reason I have used a recursive solution in my example.


    Finding Controls by ID

    Now, if you like to find a Control in one of your shells I would suggest a similar, recursive, approach:

    public Control findControlById(Integer id) {
        Shell[] shells = Display.getCurrent().getShells();
    
        for(Shell e : shells) {
            Control foundControl = findControl(e, id);
            if(foundControl != null) {
                return foundControl;
            }
        }
        return null;
    }
    
    private Control findControl(Composite c, Integer id) {
        Control[] children = c.getChildren();
        for(Control e : children) {
            if(e instanceof Composite) {
                Control found = findControl((Composite) e, id);
                if(found != null) {
                    return found;
                }
            } else {
                int value = id.intValue();
                int objValue = ((Integer)e.getData()).intValue();
    
                if(value == objValue)
                    return e;
            }
        }
        return null;
    }
    

    With the method findControlById() you can easily find a Control by it's ID.

        Control foundControl = findControlById(12);
        System.out.println(foundControl.toString());
    

    Links