Package org.jnode.awt.swingpeers

Source Code of org.jnode.awt.swingpeers.SwingComponentPeer

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.awt.swingpeers;

import gnu.classpath.SystemProperties;
import java.awt.AWTEvent;
import java.awt.BufferCapabilities;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import java.awt.event.PaintEvent;
import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.image.VolatileImage;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.apache.log4j.Logger;
import org.jnode.awt.GraphicsFactory;
import org.jnode.awt.JNodeGenericPeer;
import org.jnode.awt.JNodeGraphics2D;
import org.jnode.awt.JNodeToolkit;
import sun.awt.CausedFocusEvent;
import sun.java2d.pipe.Region;

/**
* Base class for virtual component peers. Satisfies the requirements for AWT
* peers without actually displaying anything (hence, they are virtual) or by
* delegating to the parent component, under the assumption is that somewhere up
* in the hierarchy there is a parent who can produce a display.
*
* @author Levente S\u00e1ntha
*/

abstract class SwingComponentPeer<awtT extends Component, swingPeerT extends Component>
    extends JNodeGenericPeer<SwingToolkit, awtT> implements ComponentPeer {

    ///////////////////////////////////////////////////////////////////////////////////////
    // Private
    protected final Logger log = Logger.getLogger(getClass());
    protected final swingPeerT peerComponent;

    /**
     * Initialize this instance.
     *
     * @param toolkit
     * @param target
     */
    public SwingComponentPeer(SwingToolkit toolkit, awtT target, swingPeerT swingPeer) {
        super(toolkit, target);
        this.peerComponent = swingPeer;
        if (!(swingPeer instanceof ISwingPeer)) {
            throw new IllegalArgumentException("peer must implement ISwingPeer");
        }
        SwingToolkit.copyAwtProperties(target, swingPeer);
        setBounds(target.getX(), target.getY(), target.getWidth(),
            target.getHeight());
    }

    public boolean canDetermineObscurity() {
        return false;
    }

    public final int checkImage(Image img, int width, int height, ImageObserver o) {
        return toolkit.checkImage(img, width, height, o);
    }

    public final void coalescePaintEvent(PaintEvent e) {
        //System.err.println( "coalescePaintEvent: " + e );
    }

    // Buffer

    public final void createBuffers(int x, BufferCapabilities bufferCapabilities) {
    }

    public final void destroyBuffers() {
    }

    // Image

    public final Image createImage(ImageProducer producer) {
        return toolkit.createImage(producer);
    }

    public final Image createImage(int width, int height) {
        return toolkit.createCompatibleImage(width, height);
    }

    public final VolatileImage createVolatileImage(int width, int height) {
        return toolkit.createVolatileImage(width, height);
    }

    public final void disable() {
        setEnabled(false);
    }

    public final void enable() {
        setEnabled(true);
    }

    public final void flip(BufferCapabilities.FlipContents flipContents) {
    }

    public final Image getBackBuffer() {
        return null;
    }

    // Color

    public final ColorModel getColorModel() {
        return toolkit.getColorModel();
    }

    // Fonts

    public final FontMetrics getFontMetrics(Font font) {
        return toolkit.getFontMetrics(font);
    }

    public Graphics getGraphics() {
        /*
        final Component parent = targetComponent.getParent();
        if (parent != null) {
            final int x = peerComponent.getX();
            final int y = peerComponent.getY();
            final int width = peerComponent.getWidth();
            final int height = peerComponent.getHeight();
            return parent.getGraphics().create(x, y, width, height);
        } else {
            throw new Error();
        }
        */
        //TODO review this !!!
        final int x = peerComponent.getX();
        final int y = peerComponent.getY();
        final int width = peerComponent.getWidth();
        final int height = peerComponent.getHeight();
        Graphics g = SystemProperties.getProperty("gnu.javax.swing.noGraphics2D") == null ?
            new JNodeGraphics2D(this) : GraphicsFactory.getInstance().createGraphics(this);
        g.translate(x, y);
        g.clipRect(0, 0, width, height);

        /*
        Throwable t = new Throwable();
        StackTraceElement[] st = t.getStackTrace();
        for(StackTraceElement ste : st){
            if(ste.getClassName().contains("BoxWorld") && ste.getMethodName().equals("changeState")){
                System.out.println("SwingComponent.getGraphics");
                t.printStackTrace(System.out);
                System.out.println("target compoennt: " + targetComponent);
                System.out.println("peer compoennt: " + peerComponent);
            }
        }
        */

        return g;
    }

    public final GraphicsConfiguration getGraphicsConfiguration() {
        return toolkit.getGraphicsConfiguration();
    }

    /**
     * @return The location on screen
     * @see java.awt.peer.ComponentPeer#getLocationOnScreen()
     */
    public Point getLocationOnScreen() {
        Point p = targetComponent.getLocation();
        Container parent = targetComponent.getParent();
        while (parent != null) {
            p.translate(parent.getX(), parent.getY());
            parent = parent.getParent();
        }
        return p;
    }

    public final Dimension getMinimumSize() {
        return peerComponent.getMinimumSize();
    }

    public final Dimension getPreferredSize() {
        return peerComponent.getPreferredSize();
    }

    /**
     * Response on paint events.
     */
    private void processPaintEvent(PaintEvent event) {
        if (!targetComponent.isVisible() || !peerComponent.isVisible())
            return;

        final Graphics g = peerComponent.getGraphics();
        if (g != null) {
            if (event.getID() == PaintEvent.PAINT) {
                if (!(targetComponent instanceof java.awt.Window))
                    peerComponent.paint(g);
                //todo isolates related
                //if(targetComponent instanceof RootPaneContainer) {
                //      JRootPane jRootPane = ((RootPaneContainer) targetComponent).getRootPane();
                //jRootPane.paintImmediately(0,0, jRootPane.getWidth(), jRootPane.getHeight());
                //}
            } else {
                if (!(targetComponent instanceof java.awt.Window))
                    peerComponent.update(g);
                //todo isolates related
                //if(targetComponent instanceof RootPaneContainer)
                //  ((RootPaneContainer) targetComponent).getRootPane().update(g);
                //if(targetComponent instanceof RootPaneContainer) {
                //  JRootPane jRootPane = ((RootPaneContainer) targetComponent).getRootPane();
                //  jRootPane.paintImmediately(0,0, jRootPane.getWidth(), jRootPane.getHeight());
                //}
            }
            g.dispose();
        }
    }

    /**
     * Event handling.
     */
    public final void handleEvent(AWTEvent event) {
        final int id = event.getID();
        switch (id) {
            case PaintEvent.PAINT:
            case PaintEvent.UPDATE: {
                processPaintEvent((PaintEvent) event);
                break;
            }
            default: {
                if (event.getSource() == targetComponent) {
                    event.setSource(peerComponent);
                }
                if (event.getID() == MouseEvent.MOUSE_ENTERED) {
                    Object source = event.getSource();
                    if (source instanceof Component) {
                        Component comp = (Component) source;
                        Cursor cur = comp.getCursor();
                        if (cur != null) {
                            comp.setCursor(cur);
                        } else {
                            comp.setCursor(Cursor.getDefaultCursor());
                        }
                    }
                }
                ((ISwingPeer<?>) peerComponent).processAWTEvent(event);
                break;
            }
        }
    }

    /**
     * Post a paint event for the AWT component on the event queue.
     */
    protected final void postPaintEvent() {
        if (targetComponent != null) {
            final PaintEvent event = new PaintEvent(targetComponent, PaintEvent.PAINT, targetComponent.getBounds());
            JNodeToolkit.postToTarget(event, targetComponent);
        }
    }

    public boolean handlesWheelScrolling() {
        return false;
    }

    public final void hide() {
        setVisible(false);
    }

    // Focus

    public final boolean isFocusable() {
        return peerComponent.isFocusable();
    }

    // Obscurity

    public boolean isObscured() {
        return false;
    }

    public final Dimension minimumSize() {
        return peerComponent.getMinimumSize();
    }

    public final void paint(Graphics g) {
        if (!(targetComponent instanceof java.awt.Window)) {
            peerComponent.paint(g);
            targetComponent.paint(g);
        } else
            toolkit.postEvent(new PaintEvent(targetComponent, PaintEvent.PAINT, targetComponent.getBounds()));
    }

    // Deprecated

    public final Dimension preferredSize() {
        return peerComponent.getPreferredSize();
    }

    public final boolean prepareImage(Image img, int width, int height, ImageObserver o) {
        return toolkit.prepareImage(img, width, height, o);
    }

    public final void print(Graphics g) {
        peerComponent.print(g);
    }

    public final void repaint(long tm, int x, int y, int width, int height) {
        //peerComponent.repaint(tm, x, y, width, height);
        //postPaintEvent();
        toolkit.postEvent(new PaintEvent(targetComponent, PaintEvent.UPDATE, targetComponent.getBounds()));
    }

    /**
     * @see java.awt.peer.ComponentPeer#requestFocus()
     */
    public final void requestFocus() {


        peerComponent.requestFocus();
    }

    public final boolean requestFocus(final Component lightweightChild, final boolean temporary,
                                      final boolean focusedWindowChangeAllowed, final long time) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
            public Boolean run() {
                try {
                    Method processSynchronousLightweightTransferMethod =
                        KeyboardFocusManager.class.getDeclaredMethod("processSynchronousLightweightTransfer",
                            new Class[]{Component.class, Component.class, Boolean.TYPE, Boolean.TYPE, Long.TYPE});
                    processSynchronousLightweightTransferMethod.setAccessible(true);

                    Object[] params = new Object[]{targetComponent, peerComponent, Boolean.valueOf(temporary),
                        Boolean.valueOf(focusedWindowChangeAllowed), Long.valueOf(time)};
                    return ((Boolean) processSynchronousLightweightTransferMethod.invoke(null, params)).booleanValue();
                } catch (Exception x) {
                    x.printStackTrace();
                    org.jnode.vm.Unsafe.debug("SwingComponentPeer.requestFocus() exception\n");
                    org.jnode.vm.Unsafe.debugStackTrace();
                    return false;
                }
            }
        });
    }

    public boolean requestFocus(final Component lwChild, final boolean temporary,
                                final boolean focusedWindowChangeAllowed, final long time,
                                final CausedFocusEvent.Cause cause) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
            public Boolean run() {
                try {
                    Component lightweightChild = lwChild;
                    Method processSynchronousLightweightTransferMethod =
                        KeyboardFocusManager.class.getDeclaredMethod("processSynchronousLightweightTransfer",
                            new Class[]{Component.class, Component.class, Boolean.TYPE, Boolean.TYPE, Long.TYPE});
                    processSynchronousLightweightTransferMethod.setAccessible(true);

                    Object[] params = new Object[]{targetComponent, peerComponent,
                        Boolean.valueOf(temporary), Boolean.valueOf(focusedWindowChangeAllowed), Long.valueOf(time)};
                    @SuppressWarnings("unused")
                    boolean ret =
                        ((Boolean) processSynchronousLightweightTransferMethod.invoke(null, params)).booleanValue();
                    //if(ret)
                    //  return true;

                    if (lightweightChild == null) {
                        lightweightChild = targetComponent;
                    }
                    Component currentOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
                    if (currentOwner != null && currentOwner.getPeer() == null) {
                        currentOwner = null;
                    }

                    //if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Simulating transfer from " + currentOwner +
                    // " to " + lightweightChild);
                    FocusEvent fg =
                        new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED, false, currentOwner, cause);
                    FocusEvent fl = null;
                    if (currentOwner != null) {
                        fl = new CausedFocusEvent(currentOwner, FocusEvent.FOCUS_LOST, false, lightweightChild, cause);
                    }

                    if (fl != null) {
                        postPaintEvent();
                        JNodeToolkit.postToTarget(fl, currentOwner);
                    }
                    JNodeToolkit.postToTarget(fg, (Component) fg.getSource());
                    return true;


                } catch (Exception x) {
                    x.printStackTrace();
                    return false;
                }
            }
        });
    }

    boolean isReshapeInProgress = false;

    public final void reshape(int x, int y, int width, int height) {
        if (isReshapeInProgress) {
            return;
        }
        final int oldWidth = peerComponent.getWidth();
        final int oldHeight = peerComponent.getHeight();
        isReshapeInProgress = true;
        peerComponent.setBounds(x, y, width, height);
        isReshapeInProgress = false;
        fireComponentEvent(oldWidth, width, oldHeight, height);
    }

    public final void setBackground(Color c) {
        peerComponent.setBackground(c);
        postPaintEvent();
    }

    // Bounds

    public final void setBounds(int x, int y, int width, int height) {
        reshape(x, y, width, height);
    }

    final void fireComponentEvent(final int oldWidth, int width, final int oldHeight, int height) {
        if ((oldWidth != width) || (oldHeight != height)) {
            fireComponentEvent(ComponentEvent.COMPONENT_RESIZED);
        } else {
            fireComponentEvent(ComponentEvent.COMPONENT_MOVED);
        }
    }


    /**
     * @see java.awt.peer.ComponentPeer#setCursor(java.awt.Cursor)
     */
    public final void setCursor(Cursor cursor) {
        peerComponent.setCursor(cursor);

    }

    public final void setEnabled(boolean b) {
        peerComponent.setEnabled(b);
    }

    /**
     * @see java.awt.peer.ComponentPeer#setEventMask(long)
     */
    public final void setEventMask(long mask) {
    }

    public final void setFont(Font f) {
        peerComponent.setFont(f);
        postPaintEvent();
    }

    public final void setForeground(Color c) {
        peerComponent.setForeground(c);
        postPaintEvent();
    }

    public void setVisible(boolean b) {
        peerComponent.setVisible(b);
    }

    public final void show() {
        setVisible(true);
    }

    // Cursor

    public final void updateCursorImmediately() {

        Cursor cur = targetComponent.getCursor();
//        org.jnode.vm.Unsafe.debug("JNodeToolkit.updateCursor()-2 " + cur +  " for " + targetComponent + "\n");
//        org.jnode.vm.Unsafe.debugStackTrace(100);
        peerComponent.setCursor(cur);
        toolkit.updateCursor(cur);
    }

    /**
     * Posts a component event to the AWT event queue.
     *
     * @param what
     */
    protected final void fireComponentEvent(int what) {
        JNodeToolkit.postToTarget(new ComponentEvent(targetComponent, what), targetComponent);
    }

    public void layout() {
        peerComponent.doLayout();
        targetComponent.doLayout();
    }

    public Rectangle getBounds() {
        return peerComponent.getBounds();
    }

    public void setBounds(int x, int y, int width, int height, int z) {
        setBounds(x, y, width, height);
        //peerComponent.setBounds(x, y, width, height);
    }

    public boolean isReparentSupported() {
        //TODO implement it
        return false;
    }

    public void reparent(ContainerPeer parent) {
        //TODO implement it
    }

    public void applyShape(Region shape) {
        //TODO
    }
}
TOP

Related Classes of org.jnode.awt.swingpeers.SwingComponentPeer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.