All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.piccolo2d.extras.swt.PSWTCanvas Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
/*
 * Copyright (c) 2008-2011, Piccolo2D project, http://piccolo2d.org
 * Copyright (c) 1998-2008, University of Maryland
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of conditions
 * and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
 * and the following disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its
 * contributors may be used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.piccolo2d.extras.swt;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.InputEvent;
import java.awt.geom.Rectangle2D;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.piccolo2d.PCamera;
import org.piccolo2d.PComponent;
import org.piccolo2d.PLayer;
import org.piccolo2d.PRoot;
import org.piccolo2d.event.PInputEventListener;
import org.piccolo2d.event.PPanEventHandler;
import org.piccolo2d.event.PZoomEventHandler;
import org.piccolo2d.util.PBounds;
import org.piccolo2d.util.PDebug;
import org.piccolo2d.util.PPaintContext;
import org.piccolo2d.util.PStack;


/**
 * PSWTCanvas is an SWT Composite that can be used to embed
 * Piccolo into a SWT application. Canvases view the Piccolo scene graph
 * through a camera. The canvas manages screen updates coming from this camera,
 * and forwards swing mouse and keyboard events to the camera.
 * 
 * @version 1.0
 * @author Jesse Grosjean
 */
public class PSWTCanvas extends Composite implements PComponent {
    private static final int SWT_BUTTON1 = 1;
    private static final int SWT_BUTTON2 = 2;
    private static final int SWT_BUTTON3 = 3;
    
    /**
     * Terrible Singleton instance of the PSWTCanvas. Falsely assumes you will
     * only have one of these per application.
     */
    public static PSWTCanvas CURRENT_CANVAS = null;

    private Image backBuffer;
    private boolean doubleBuffered = true;
    private PCamera camera;
    private final PStack cursorStack;
    private Cursor curCursor;
    private int interacting;
    private int defaultRenderQuality;
    private int animatingRenderQuality;
    private int interactingRenderQuality;
    private final PPanEventHandler panEventHandler;
    private final PZoomEventHandler zoomEventHandler;
    private boolean paintingImmediately;
    private boolean animatingOnLastPaint;

    private boolean isButton1Pressed;
    private boolean isButton2Pressed;
    private boolean isButton3Pressed;

    /**
     * Construct a canvas with the basic scene graph consisting of a root,
     * camera, and layer. Event handlers for zooming and panning are
     * automatically installed.
     * 
     * @param parent component onto which the canvas is installed
     * @param style component style for the PSWTCanvas
     */
    public PSWTCanvas(final Composite parent, final int style) {
        super(parent, style | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE);

        CURRENT_CANVAS = this;
        cursorStack = new PStack();
        setCamera(createBasicSceneGraph());
        installInputSources();
        setDefaultRenderQuality(PPaintContext.HIGH_QUALITY_RENDERING);
        setAnimatingRenderQuality(PPaintContext.LOW_QUALITY_RENDERING);
        setInteractingRenderQuality(PPaintContext.LOW_QUALITY_RENDERING);
        panEventHandler = new PPanEventHandler();
        zoomEventHandler = new PZoomEventHandler();
        addInputEventListener(panEventHandler);
        addInputEventListener(zoomEventHandler);

        installPaintListener();
        installDisposeListener();
    }

    private void installPaintListener() {
        addPaintListener(new PaintListener() {
            public void paintControl(final PaintEvent pe) {
                paintComponent(pe.gc, pe.x, pe.y, pe.width, pe.height);
            }
        });
    }

    private void installDisposeListener() {
        SWTGraphics2D.incrementGCCount();
        addDisposeListener(new DisposeListener() {
            public void widgetDisposed(final DisposeEvent de) {
                getRoot().getActivityScheduler().removeAllActivities();
                SWTGraphics2D.decrementGCCount();
            }
        });
    }

    // ****************************************************************
    // Basic - Methods for accessing common Piccolo2D nodes.
    // ****************************************************************

    /**
     * Get the pan event handler associated with this canvas. This event handler
     * is set up to get events from the camera associated with this canvas by
     * default.
     * 
     * @return the current pan event handler, which may be null
     */
    public PPanEventHandler getPanEventHandler() {
        return panEventHandler;
    }

    /**
     * Get the zoom event handler associated with this canvas. This event
     * handler is set up to get events from the camera associated with this
     * canvas by default.
     * 
     * @return the event handler installed to handle zooming
     */
    public PZoomEventHandler getZoomEventHandler() {
        return zoomEventHandler;
    }

    /**
     * Return the camera associated with this canvas. All input events from this
     * canvas go through this camera. And this is the camera that paints this
     * canvas.
     * 
     * @return the camera associated with this canvas
     */
    public PCamera getCamera() {
        return camera;
    }

    /**
     * Set the camera associated with this canvas. All input events from this
     * canvas go through this camera. And this is the camera that paints this
     * canvas.
     * 
     * @param newCamera camera to attach to this canvas
     */
    public void setCamera(final PCamera newCamera) {
        if (camera != null) {
            camera.setComponent(null);
        }

        camera = newCamera;

        if (camera != null) {
            camera.setComponent(this);

            final Rectangle swtRect = getBounds();

            camera.setBounds(new Rectangle2D.Double(swtRect.x, swtRect.y, swtRect.width, swtRect.height));
        }
    }

    /**
     * Return root for this canvas.
     * 
     * @return root of the scene this canvas is viewing through its camera
     */
    public PRoot getRoot() {
        return camera.getRoot();
    }

    /**
     * Helper method to return the first layer attached to the camera of this
     * canvas.
     * 
     * Short form of canvas.getCamera.getLayer(0)
     * 
     * @return the first layer attached to the camera of this canvas
     */
    public PLayer getLayer() {
        return camera.getLayer(0);
    }

    /**
     * Add an input listener to the camera associated with this canvas.
     * 
     * @param listener listener to add to to the camera
     */
    public void addInputEventListener(final PInputEventListener listener) {
        getCamera().addInputEventListener(listener);
    }

    /**
     * Remove an input listener to the camera associated with this canvas. Does
     * nothign is the listener is not found.
     * 
     * @param listener listener to remove from the set of event listeners
     *            attached to this canvas.
     */
    public void removeInputEventListener(final PInputEventListener listener) {
        getCamera().removeInputEventListener(listener);
    }

    /**
     * Builds the basic scene graph associated with this canvas. Developers may
     * override this method to install their own layers, and cameras.
     * 
     * @return PCamera viewing the freshly created scene
     */
    public PCamera createBasicSceneGraph() {
        final PRoot r = new PSWTRoot(this);
        final PLayer l = new PLayer();
        final PCamera c = new PCamera();

        r.addChild(c);
        r.addChild(l);
        c.addLayer(l);

        return c;
    }

    // ****************************************************************
    // Painting
    // ****************************************************************

    /**
     * Return true if this canvas has been marked as interacting. If so the
     * canvas will normally render at a lower quality that is faster.
     * 
     * @return true if canvas is flagged as interacting
     */
    public boolean getInteracting() {
        return interacting > 0;
    }

    /**
     * Return true if any activities that respond with true to the method
     * isAnimating were run in the last PRoot.processInputs() loop. This values
     * is used by this canvas to determine the render quality to use for the
     * next paint.
     * 
     * @return true if there is an animating activity that is currently active
     */
    public boolean getAnimating() {
        return getRoot().getActivityScheduler().getAnimating();
    }

    /**
     * Changes the number of callers that are interacting with the canvas. Will
     * allow the scene to be rendered in a lower quality if the number is not 0.
     * 
     * @param isInteracting state the client considers the PSWTCanvas to be in
     *            with regard to interacting
     */
    public void setInteracting(final boolean isInteracting) {
        if (isInteracting) {
            interacting++;
        }
        else {
            interacting--;
        }

        if (!getInteracting()) {
            repaint();
        }
    }

    /**
     * Get whether this canvas should use double buffering - the default is to
     * double buffer.
     * 
     * @return true if double buffering is enabled
     */
    public boolean getDoubleBuffered() {
        return doubleBuffered;
    }

    /**
     * Set whether this canvas should use double buffering - the default is yes.
     * 
     * @param doubleBuffered value of double buffering flas
     */
    public void setDoubleBuffered(final boolean doubleBuffered) {
        this.doubleBuffered = doubleBuffered;
        if (!doubleBuffered && backBuffer != null) {
            backBuffer.dispose();
            backBuffer = null;
        }
    }

    /**
     * Set the render quality that should be used when rendering this canvas.
     * The default value is PPaintContext.HIGH_QUALITY_RENDERING.
     * 
     * @param requestedQuality supports PPaintContext.HIGH_QUALITY_RENDERING or
     *            PPaintContext.LOW_QUALITY_RENDERING
     */
    public void setDefaultRenderQuality(final int requestedQuality) {
        defaultRenderQuality = requestedQuality;
        repaint();
    }

    /**
     * Set the render quality that should be used when rendering this canvas
     * when it is animating. The default value is
     * PPaintContext.LOW_QUALITY_RENDERING.
     * 
     * @param requestedQuality supports PPaintContext.HIGH_QUALITY_RENDERING or
     *            PPaintContext.LOW_QUALITY_RENDERING
     */
    public void setAnimatingRenderQuality(final int requestedQuality) {
        animatingRenderQuality = requestedQuality;
        repaint();
    }

    /**
     * Set the render quality that should be used when rendering this canvas
     * when it is interacting. The default value is
     * PPaintContext.LOW_QUALITY_RENDERING.
     * 
     * @param requestedQuality supports PPaintContext.HIGH_QUALITY_RENDERING or
     *            PPaintContext.LOW_QUALITY_RENDERING
     */
    public void setInteractingRenderQuality(final int requestedQuality) {
        interactingRenderQuality = requestedQuality;
        repaint();
    }

    /**
     * Set the canvas cursor, and remember the previous cursor on the cursor
     * stack. Under the hood it is mapping the java.awt.Cursor to
     * org.eclipse.swt.graphics.Cursor objects.
     * 
     * @param newCursor new cursor to push onto the cursor stack
     */
    public void pushCursor(final java.awt.Cursor newCursor) {
        Cursor swtCursor = null;
        if (newCursor.getType() == java.awt.Cursor.N_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEN);
        }
        else if (newCursor.getType() == java.awt.Cursor.NE_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZENE);
        }
        else if (newCursor.getType() == java.awt.Cursor.NW_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZENW);
        }
        else if (newCursor.getType() == java.awt.Cursor.S_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZES);
        }
        else if (newCursor.getType() == java.awt.Cursor.SE_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZESE);
        }
        else if (newCursor.getType() == java.awt.Cursor.SW_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZESW);
        }
        else if (newCursor.getType() == java.awt.Cursor.E_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEE);
        }
        else if (newCursor.getType() == java.awt.Cursor.W_RESIZE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEW);
        }
        else if (newCursor.getType() == java.awt.Cursor.TEXT_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_IBEAM);
        }
        else if (newCursor.getType() == java.awt.Cursor.HAND_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_HAND);
        }
        else if (newCursor.getType() == java.awt.Cursor.MOVE_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEALL);
        }
        else if (newCursor.getType() == java.awt.Cursor.CROSSHAIR_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_CROSS);
        }
        else if (newCursor.getType() == java.awt.Cursor.WAIT_CURSOR) {
            swtCursor = new Cursor(getDisplay(), SWT.CURSOR_WAIT);
        }

        if (swtCursor != null) {
            if (curCursor != null) {
                cursorStack.push(curCursor);
            }
            curCursor = swtCursor;
            setCursor(swtCursor);
        }
    }

    /**
     * Pop the cursor on top of the cursorStack and set it as the canvas cursor.
     */
    public void popCursor() {
        if (curCursor != null) {
            // We must manually dispose of cursors under SWT
            curCursor.dispose();
        }

        if (cursorStack.isEmpty()) {
            curCursor = null;
        }
        else {
            curCursor = (Cursor) cursorStack.pop();
        }

        // This sets the cursor back to default
        setCursor(curCursor);
    }

    // ****************************************************************
    // Code to manage connection to Swing. There appears to be a bug in
    // swing where it will occasionally send to many mouse pressed or mouse
    // released events. Below we attempt to filter out those cases before
    // they get delivered to the Piccolo2D framework.
    // ****************************************************************

    /**
     * This method installs mouse and key listeners on the canvas that forward
     * those events to Piccolo2D.
     */
    protected void installInputSources() {
        MouseInputSource mouseInputSource = new MouseInputSource();
        addMouseListener(mouseInputSource);
        addMouseMoveListener(mouseInputSource);

        addKeyListener(new KeyboardInputSource());
    }

    /**
     * Dispatches the given event to the default input manager for the root of
     * this canvas.
     * 
     * @param awtEvent awt event needing dispatching
     * @param type type of the event
     */
    protected void sendInputEventToInputManager(final InputEvent awtEvent, final int type) {
        getRoot().getDefaultInputManager().processEventFromCamera(awtEvent, type, getCamera());
    }

    /**
     * Changes the bounds of this PSWTCanvas. Updating the camera and the double
     * buffered image appropriately.
     * 
     * @param x left of the new bounds
     * @param y top of the new bounds
     * @param newWidth new width of the bounds
     * @param newHeight new height of the bounds
     */
    public void setBounds(final int x, final int y, final int newWidth, final int newHeight) {
        camera.setBounds(camera.getX(), camera.getY(), newWidth, newHeight);

        if (backBufferNeedsResizing(newWidth, newHeight)) {
            resizeBackBuffer(newWidth, newHeight);
        }

        super.setBounds(x, y, newWidth, newHeight);
    }

    private void resizeBackBuffer(final int newWidth, final int newHeight) {
        if (backBuffer != null) {
            backBuffer.dispose();
        }
        backBuffer = new Image(getDisplay(), newWidth, newHeight);
    }

    private boolean backBufferNeedsResizing(final int newWidth, final int newHeight) {
        if (!doubleBuffered) {
            return false;
        }

        if (backBuffer == null) {
            return true;
        }

        return backBuffer.getBounds().width < newWidth || backBuffer.getBounds().height < newHeight;
    }

    /**
     * Exists to dispatch from the Swing's repaint method to SWT's redraw
     * method.
     */
    public void repaint() {
        super.redraw();
    }

    /**
     * Flags the bounds provided as needing to be redrawn.
     * 
     * @param bounds the bounds that should be repainted
     */
    public void repaint(final PBounds bounds) {
        bounds.expandNearestIntegerDimensions();
        bounds.inset(-1, -1);

        redraw((int) bounds.x, (int) bounds.y, (int) bounds.width, (int) bounds.height, true);
    }

    /**
     * Paints the region specified of the canvas onto the given Graphics
     * Context.
     * 
     * @param gc graphics onto within painting should occur
     * @param x left of the dirty region
     * @param y top of the dirty region
     * @param w width of the dirty region
     * @param h height of the dirty region
     */
    public void paintComponent(final GC gc, final int x, final int y, final int w, final int h) {
        PDebug.startProcessingOutput();

        GC imageGC = null;
        Graphics2D g2 = null;
        if (doubleBuffered) {
            imageGC = new GC(backBuffer);
            g2 = new SWTGraphics2D(imageGC, getDisplay());
        }
        else {
            g2 = new SWTGraphics2D(gc, getDisplay());
        }

        g2.setColor(Color.white);
        g2.setBackground(Color.white);

        final Rectangle rect = getBounds();
        g2.fillRect(0, 0, rect.width, rect.height);

        // This fixes a problem with standard debugging of region management in
        // SWT
        if (PDebug.debugRegionManagement) {
            final Rectangle r = gc.getClipping();
            final Rectangle2D r2 = new Rectangle2D.Double(r.x, r.y, r.width, r.height);
            g2.setBackground(PDebug.getDebugPaintColor());
            g2.fill(r2);
        }

        // create new paint context and set render quality
        final PPaintContext paintContext = new PPaintContext(g2);
        if (getInteracting() || getAnimating()) {
            if (interactingRenderQuality > animatingRenderQuality) {
                paintContext.setRenderQuality(interactingRenderQuality);
            }
            else {
                paintContext.setRenderQuality(animatingRenderQuality);
            }
        }
        else {
            paintContext.setRenderQuality(defaultRenderQuality);
        }

        // paint Piccolo2D
        camera.fullPaint(paintContext);

        // if switched state from animating to not animating invalidate
        // the entire screen so that it will be drawn with the default instead
        // of animating render quality.
        if (animatingOnLastPaint && !getAnimating()) {
            repaint();
        }
        animatingOnLastPaint = getAnimating();

        final boolean region = PDebug.debugRegionManagement;
        PDebug.debugRegionManagement = false;
        PDebug.endProcessingOutput(g2);
        PDebug.debugRegionManagement = region;

        if (doubleBuffered) {
            gc.drawImage(backBuffer, 0, 0);

            // Dispose of the allocated image gc
            imageGC.dispose();
        }
    }

    /**
     * Performs an immediate repaint if no other client is currently performing
     * one.
     */
    public void paintImmediately() {
        if (paintingImmediately) {
            return;
        }

        paintingImmediately = true;
        redraw();
        update();
        paintingImmediately = false;
    }

    private final class KeyboardInputSource implements KeyListener {
        public void keyPressed(final KeyEvent ke) {
            final java.awt.event.KeyEvent inputEvent = new PSWTKeyEvent(ke, java.awt.event.KeyEvent.KEY_PRESSED);
            sendInputEventToInputManager(inputEvent, java.awt.event.KeyEvent.KEY_PRESSED);
        }

        public void keyReleased(final KeyEvent ke) {
            final java.awt.event.KeyEvent inputEvent = new PSWTKeyEvent(ke, java.awt.event.KeyEvent.KEY_RELEASED);
            sendInputEventToInputManager(inputEvent, java.awt.event.KeyEvent.KEY_RELEASED);
        }
    }

    private final class MouseInputSource implements MouseListener, MouseMoveListener {
        public void mouseMove(final MouseEvent me) {
            if (isButton1Pressed || isButton2Pressed || isButton3Pressed) {
                final java.awt.event.MouseEvent inputEvent = new PSWTMouseEvent(me,
                        java.awt.event.MouseEvent.MOUSE_DRAGGED, 1);
                sendInputEventToInputManager(inputEvent, java.awt.event.MouseEvent.MOUSE_DRAGGED);
            }
            else {
                final java.awt.event.MouseEvent inputEvent = new PSWTMouseEvent(me,
                        java.awt.event.MouseEvent.MOUSE_MOVED, 1);
                sendInputEventToInputManager(inputEvent, java.awt.event.MouseEvent.MOUSE_MOVED);
            }
        }

        public void mouseDown(final MouseEvent mouseEvent) {
            boolean shouldBalanceEvent = false;

            switch (mouseEvent.button) {
                case SWT_BUTTON1:
                    if (isButton1Pressed) {
                        shouldBalanceEvent = true;
                    }
                    isButton1Pressed = true;
                    break;
                case SWT_BUTTON2:
                    if (isButton2Pressed) {
                        shouldBalanceEvent = true;
                    }
                    isButton2Pressed = true;
                    break;
                case SWT_BUTTON3:
                    if (isButton3Pressed) {
                        shouldBalanceEvent = true;
                    }
                    isButton3Pressed = true;
                    break;
                default:
            }

            if (shouldBalanceEvent) {
                final java.awt.event.MouseEvent balanceEvent = new PSWTMouseEvent(mouseEvent,
                        java.awt.event.MouseEvent.MOUSE_RELEASED, 1);
                sendInputEventToInputManager(balanceEvent, java.awt.event.MouseEvent.MOUSE_RELEASED);
            }

            final java.awt.event.MouseEvent balanceEvent = new PSWTMouseEvent(mouseEvent,
                    java.awt.event.MouseEvent.MOUSE_PRESSED, 1);
            sendInputEventToInputManager(balanceEvent, java.awt.event.MouseEvent.MOUSE_PRESSED);
        }

        public void mouseUp(final MouseEvent me) {
            boolean shouldBalanceEvent = false;

            switch (me.button) {
                case SWT_BUTTON1:
                    if (!isButton1Pressed) {
                        shouldBalanceEvent = true;
                    }
                    isButton1Pressed = false;
                    break;
                case SWT_BUTTON2:
                    if (!isButton2Pressed) {
                        shouldBalanceEvent = true;
                    }
                    isButton2Pressed = false;
                    break;
                case SWT_BUTTON3:
                    if (!isButton3Pressed) {
                        shouldBalanceEvent = true;
                    }
                    isButton3Pressed = false;
                    break;
                default:
            }

            if (shouldBalanceEvent) {
                final java.awt.event.MouseEvent balanceEvent = new PSWTMouseEvent(me,
                        java.awt.event.MouseEvent.MOUSE_PRESSED, 1);
                sendInputEventToInputManager(balanceEvent, java.awt.event.MouseEvent.MOUSE_PRESSED);
            }

            final java.awt.event.MouseEvent balanceEvent = new PSWTMouseEvent(me,
                    java.awt.event.MouseEvent.MOUSE_RELEASED, 1);
            sendInputEventToInputManager(balanceEvent, java.awt.event.MouseEvent.MOUSE_RELEASED);
        }

        public void mouseDoubleClick(final MouseEvent me) {
            // This doesn't work with click event types for some reason - it
            // has to do with how the click and release events are ordered,
            // I think
            java.awt.event.MouseEvent inputEvent = new PSWTMouseEvent(me, java.awt.event.MouseEvent.MOUSE_PRESSED, 2);
            sendInputEventToInputManager(inputEvent, java.awt.event.MouseEvent.MOUSE_PRESSED);
            inputEvent = new PSWTMouseEvent(me, java.awt.event.MouseEvent.MOUSE_RELEASED, 2);
            sendInputEventToInputManager(inputEvent, java.awt.event.MouseEvent.MOUSE_RELEASED);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy