How to simulate programmatically button click on background of Composite?

14,276

Solution 1

OK this is the main form :

package test.src;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class CompositeClicker
{
    private static Display      display;
    private static Shell        shell;
    private static PComposite   composite;

    public static void main ( String [ ] args )
    {
        display = new Display ( );
        shell = new Shell ( display );
        shell.setLayout ( new GridLayout ( 1 , false ) );
        shell.setLocation ( 100 , 50 );
        shell.setSize ( 100 , 500 );
        composite = new PComposite ( shell );
        composite.setLayoutData ( new GridData ( SWT.FILL , SWT.FILL , true , true ) );
        composite.setLayout ( new GridLayout ( 1 , false ) );

        shell.open ( );
        while ( !shell.isDisposed ( ) )
        {
            if ( !display.readAndDispatch ( ) )
                display.sleep ( );
        }
        display.dispose ( );

    }
}

And this is the PComposite class:

package test.src;

import java.awt.Panel;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;

import javax.swing.SwingUtilities;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Composite;

public class PComposite extends Composite
{
    int x;
    int y;

    public PComposite ( Composite parent )
    {
        super ( parent , SWT.BORDER | SWT.EMBEDDED );
        addPaintListener ( new PaintListener ( )
        {

            @Override
            public void paintControl ( PaintEvent e )
            {
                Point p = new Point ( PComposite.this.getClientArea ( ).x + 11 , PComposite.this.getClientArea ( ).y + 12 );
                Panel panel = new Panel ( );
                panel.setBounds ( getShell ( ).getBounds ( ).x , getShell ( ).getBounds ( ).y + 25 , getShell ( ).getBounds ( ).width , getShell ( ).getBounds ( ).height );
                SwingUtilities.convertPointToScreen ( p , panel );

                x = p.x;
                y = p.y;
                try
                {
                    trainer ( );
                }
                catch ( Exception exc )
                {

                    exc.printStackTrace ( );
                }
            }
        } );
        addMouseListener ( new MouseAdapter ( )
        {

            @Override
            public void mouseDown ( MouseEvent e )
            {
                System.out.println ( e.x + " " + e.y );
            }
        } );
    }

    private void trainer ( ) throws Exception
    {
        Robot trainer = new Robot ( );
        trainer.mouseMove ( x , y );
        int delay = 100;
        int clicks = 1;
        while ( clicks-- > 0 )
        {
            trainer.mouseMove ( x , y );
            trainer.mousePress ( InputEvent.BUTTON1_MASK );
            trainer.delay ( delay );
        }

    }

}

You have to use swing in your SWT application to success.

Solution 2

You can use Button.notifyListeners(int eventType, Event event) to simulate a SWT button click:

final Button setButton = new Button(composite, SWT.PUSH);
setButton.setText("Set");
setButton.addSelectionListener(new SelectionAdapter() {
    public void widgetSelected(final SelectionEvent e) {
        // some code here
    }
});

MenuItem clickMenuItem = new MenuItem(testMenu, SWT.PUSH);
clickMenuItem.setText("Click");
clickMenuItem.addListener(SWT.Selection, new Listener() {
    public void handleEvent(Event event) {
        setButton.notifyListeners(SWT.Selection, new Event());
    }
});

Solution 3

Another option is to use reflection to invoke the click method of the org.eclipse.swt.widgets.Button class

    org.eclipse.swt.widgets.Button button = (org.eclipse.swt.widgets.Button)Button.this;

    try 
    {                           
        Class<?>buttonClass = button.getClass().getSuperclass();

        Method method = buttonClass.getDeclaredMethod("click");
        method.setAccessible(true);
        method.invoke(button);          
    }
    catch (SecurityException         e) { e.printStackTrace(); }
    catch (NoSuchMethodException     e) { e.printStackTrace(); }
    catch (IllegalArgumentException  e) { e.printStackTrace(); }
    catch (IllegalAccessException    e) { e.printStackTrace(); }
    catch (InvocationTargetException e) { e.printStackTrace(); }    
Share:
14,276
alhcr
Author by

alhcr

Updated on June 14, 2022

Comments

  • alhcr
    alhcr almost 2 years

    I need to simulate programmatically button click on background of Composite. Specifically: on left-top corner of Composite.

  • alhcr
    alhcr over 12 years
    It's not what I wanted. I want to generate programmatically mouse click event without user interaction. What you have here is showing messagebox if user clicked 0,0 location...
  • Jordan Borisov
    Jordan Borisov over 12 years
    OK I found something. In swing there is a Robot class which implement what you want. Trey this code. The only thing is you have to set the x and the y fields of the class correctly.