4632N/A/*
4767N/A * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4639N/A
4632N/Apackage sun.lwawt;
4632N/A
4632N/Aimport java.awt.*;
4632N/A
4632N/Aimport java.awt.dnd.DropTarget;
4632N/Aimport java.awt.dnd.peer.DropTargetPeer;
4632N/Aimport java.awt.event.*;
4632N/A
4632N/Aimport java.awt.image.ColorModel;
4632N/Aimport java.awt.image.ImageObserver;
4632N/Aimport java.awt.image.ImageProducer;
4632N/Aimport java.awt.image.VolatileImage;
4632N/A
4632N/Aimport java.awt.peer.ComponentPeer;
4632N/Aimport java.awt.peer.ContainerPeer;
4632N/A
5336N/Aimport java.awt.peer.KeyboardFocusManagerPeer;
4632N/Aimport java.util.concurrent.atomic.AtomicBoolean;
4632N/Aimport java.lang.reflect.Field;
4632N/Aimport java.security.AccessController;
4632N/Aimport java.security.PrivilegedAction;
4632N/A
4632N/Aimport sun.awt.*;
4632N/A
4632N/Aimport sun.awt.event.IgnorePaintEvent;
4632N/A
4632N/Aimport sun.awt.image.SunVolatileImage;
4632N/Aimport sun.awt.image.ToolkitImage;
4632N/A
4632N/Aimport sun.java2d.SunGraphics2D;
4639N/Aimport sun.java2d.opengl.OGLRenderQueue;
4632N/Aimport sun.java2d.pipe.Region;
4632N/A
4886N/Aimport sun.util.logging.PlatformLogger;
4886N/A
4632N/Aimport javax.swing.JComponent;
4632N/Aimport javax.swing.SwingUtilities;
4632N/Aimport javax.swing.RepaintManager;
4632N/A
4632N/Aimport sun.lwawt.macosx.CDropTarget;
4632N/A
4632N/Aimport com.sun.java.swing.SwingUtilities3;
4632N/A
4632N/Apublic abstract class LWComponentPeer<T extends Component, D extends JComponent>
4886N/A implements ComponentPeer, DropTargetPeer
4886N/A{
4886N/A private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWComponentPeer");
4886N/A
4632N/A // State lock is to be used for modifications to this
4632N/A // peer's fields (e.g. bounds, background, font, etc.)
4632N/A // It should be the last lock in the lock chain
4632N/A private final Object stateLock =
4632N/A new StringBuilder("LWComponentPeer.stateLock");
4632N/A
4632N/A // The lock to operate with the peers hierarchy. AWT tree
4632N/A // lock is not used as there are many peers related ops
4632N/A // to be done on the toolkit thread, and we don't want to
4632N/A // depend on a public lock on this thread
5166N/A private static final Object peerTreeLock =
4632N/A new StringBuilder("LWComponentPeer.peerTreeLock");
4632N/A
5166N/A private final T target;
4632N/A
4632N/A // Container peer. It may not be the peer of the target's direct
4632N/A // parent, for example, in the case of hw/lw mixing. However,
4632N/A // let's skip this scenario for the time being. We also assume
4632N/A // the container peer is not null, which might also be false if
4632N/A // addNotify() is called for a component outside of the hierarchy.
4632N/A // The exception is LWWindowPeers: their parents are always null
4632N/A private LWContainerPeer containerPeer;
4632N/A
4632N/A // Handy reference to the top-level window peer. Window peer is
4632N/A // borrowed from the containerPeer in constructor, and should also
4632N/A // be updated when the component is reparented to another container
4632N/A private LWWindowPeer windowPeer;
4632N/A
5166N/A private final AtomicBoolean disposed = new AtomicBoolean(false);
4632N/A
4632N/A // Bounds are relative to parent peer
5166N/A private final Rectangle bounds = new Rectangle();
4639N/A private Region region;
4632N/A
4632N/A // Component state. Should be accessed under the state lock
4632N/A private boolean visible = false;
4632N/A private boolean enabled = true;
4632N/A
4691N/A private Color background;
4691N/A private Color foreground;
4691N/A private Font font;
4691N/A
5166N/A /**
5166N/A * Paint area to coalesce all the paint events and store the target dirty
5166N/A * area.
5166N/A */
5166N/A private final RepaintArea targetPaintArea;
4632N/A
4632N/A // private volatile boolean paintPending;
4632N/A private volatile boolean isLayouting;
4632N/A
4632N/A private D delegate = null;
4632N/A private Container delegateContainer;
4632N/A private Component delegateDropTarget;
4686N/A private final Object dropTargetLock = new Object();
4632N/A
4632N/A private int fNumDropTargets = 0;
4632N/A private CDropTarget fDropTarget = null;
4632N/A
5166N/A private final PlatformComponent platformComponent;
4632N/A
4639N/A private final class DelegateContainer extends Container {
4632N/A {
4632N/A enableEvents(0xFFFFFFFF);
4632N/A }
4632N/A
4639N/A DelegateContainer() {
4639N/A super();
4639N/A }
4639N/A
4632N/A @Override
4632N/A public boolean isLightweight() {
4632N/A return false;
4632N/A }
4632N/A
4639N/A @Override
4632N/A public Point getLocation() {
4632N/A return getLocationOnScreen();
4632N/A }
4632N/A
4639N/A @Override
4632N/A public Point getLocationOnScreen() {
4632N/A return LWComponentPeer.this.getLocationOnScreen();
4632N/A }
4632N/A
4639N/A @Override
4632N/A public int getX() {
4632N/A return getLocation().x;
4632N/A }
4632N/A
4639N/A @Override
4632N/A public int getY() {
4632N/A return getLocation().y;
4632N/A }
4632N/A }
4632N/A
4632N/A public LWComponentPeer(T target, PlatformComponent platformComponent) {
5166N/A targetPaintArea = new LWRepaintArea();
4632N/A this.target = target;
4632N/A this.platformComponent = platformComponent;
4632N/A
4632N/A initializeContainerPeer();
4632N/A // Container peer is always null for LWWindowPeers, so
4632N/A // windowPeer is always null for them as well. On the other
4632N/A // hand, LWWindowPeer shouldn't use windowPeer at all
4632N/A if (containerPeer != null) {
4632N/A windowPeer = containerPeer.getWindowPeerOrSelf();
4632N/A }
4632N/A // don't bother about z-order here as updateZOrder()
4632N/A // will be called from addNotify() later anyway
4632N/A if (containerPeer != null) {
4632N/A containerPeer.addChildPeer(this);
4632N/A }
4632N/A
4632N/A // the delegate must be created after the target is set
4632N/A AWTEventListener toolkitListener = null;
4632N/A synchronized (Toolkit.getDefaultToolkit()) {
4632N/A try {
4632N/A toolkitListener = getToolkitAWTEventListener();
4632N/A setToolkitAWTEventListener(null);
4632N/A
4632N/A synchronized (getDelegateLock()) {
4632N/A delegate = createDelegate();
4632N/A if (delegate != null) {
5166N/A delegate.setVisible(false);
4632N/A delegateContainer = new DelegateContainer();
4632N/A delegateContainer.add(delegate);
4632N/A delegateContainer.addNotify();
4632N/A delegate.addNotify();
5166N/A resetColorsAndFont(delegate);
5166N/A delegate.setOpaque(true);
4632N/A } else {
4632N/A return;
4632N/A }
4632N/A }
4632N/A
4632N/A } finally {
4632N/A setToolkitAWTEventListener(toolkitListener);
4632N/A }
4632N/A
4632N/A // todo swing: later on we will probably have one global RM
4632N/A SwingUtilities3.setDelegateRepaintManager(delegate, new RepaintManager() {
4632N/A @Override
4632N/A public void addDirtyRegion(final JComponent c, final int x, final int y, final int w, final int h) {
4874N/A repaintPeer(SwingUtilities.convertRectangle(
4874N/A c, new Rectangle(x, y, w, h), getDelegate()));
4632N/A }
4632N/A });
4632N/A }
4632N/A }
4632N/A
4632N/A /**
4632N/A * This method must be called under Toolkit.getDefaultToolkit() lock
4632N/A * and followed by setToolkitAWTEventListener()
4632N/A */
4632N/A protected final AWTEventListener getToolkitAWTEventListener() {
4632N/A return AccessController.doPrivileged(new PrivilegedAction<AWTEventListener>() {
4632N/A public AWTEventListener run() {
4632N/A Toolkit toolkit = Toolkit.getDefaultToolkit();
4632N/A try {
4632N/A Field field = Toolkit.class.getDeclaredField("eventListener");
4632N/A field.setAccessible(true);
4632N/A return (AWTEventListener) field.get(toolkit);
4632N/A } catch (Exception e) {
4632N/A throw new InternalError(e.toString());
4632N/A }
4632N/A }
4632N/A });
4632N/A }
4632N/A
4632N/A protected final void setToolkitAWTEventListener(final AWTEventListener listener) {
4632N/A AccessController.doPrivileged(new PrivilegedAction<Void>() {
4632N/A public Void run() {
4632N/A Toolkit toolkit = Toolkit.getDefaultToolkit();
4632N/A try {
4632N/A Field field = Toolkit.class.getDeclaredField("eventListener");
4632N/A field.setAccessible(true);
4632N/A field.set(toolkit, listener);
4632N/A } catch (Exception e) {
4632N/A throw new InternalError(e.toString());
4632N/A }
4632N/A return null;
4632N/A }
4632N/A });
4632N/A }
4632N/A
4632N/A /**
4632N/A * This method is called under getDelegateLock().
4632N/A * Overridden in subclasses.
4632N/A */
4632N/A protected D createDelegate() {
4632N/A return null;
4632N/A }
4632N/A
4632N/A protected final D getDelegate() {
4632N/A synchronized (getStateLock()) {
4632N/A return delegate;
4632N/A }
4632N/A }
4632N/A
4632N/A protected Component getDelegateFocusOwner() {
4632N/A return getDelegate();
4632N/A }
4632N/A
5166N/A /**
5166N/A * Initializes this peer. The call to initialize() is not placed to
5166N/A * LWComponentPeer ctor to let the subclass ctor to finish completely first.
5166N/A * Instead, it's the LWToolkit object who is responsible for initialization.
5166N/A * Note that we call setVisible() at the end of initialization.
4632N/A */
5166N/A public final void initialize() {
5333N/A platformComponent.initialize(getPlatformWindow());
5166N/A initializeImpl();
5166N/A setVisible(target.isVisible());
5166N/A }
5166N/A
5166N/A /**
5166N/A * Fetching general properties from the target. Should be overridden in
5166N/A * subclasses to initialize specific peers properties.
5166N/A */
5166N/A void initializeImpl() {
4691N/A setBackground(target.getBackground());
4691N/A setForeground(target.getForeground());
4691N/A setFont(target.getFont());
4632N/A setBounds(target.getBounds());
4632N/A setEnabled(target.isEnabled());
4632N/A }
4632N/A
4639N/A private static void resetColorsAndFont(final Container c) {
4632N/A c.setBackground(null);
4632N/A c.setForeground(null);
4632N/A c.setFont(null);
4632N/A for (int i = 0; i < c.getComponentCount(); i++) {
4632N/A resetColorsAndFont((Container) c.getComponent(i));
4632N/A }
4632N/A }
4632N/A
4632N/A final Object getStateLock() {
4632N/A return stateLock;
4632N/A }
4632N/A
5166N/A /**
5166N/A * Synchronize all operations with the Swing delegates under AWT tree lock,
5166N/A * using a new separate lock to synchronize access to delegates may lead
5166N/A * deadlocks. Think of it as a 'virtual EDT'.
5166N/A *
5166N/A * @return DelegateLock
5166N/A */
4632N/A final Object getDelegateLock() {
4632N/A return getTarget().getTreeLock();
4632N/A }
4632N/A
5166N/A protected static final Object getPeerTreeLock() {
4632N/A return peerTreeLock;
4632N/A }
4632N/A
4632N/A final T getTarget() {
4632N/A return target;
4632N/A }
4632N/A
4632N/A // Just a helper method
4632N/A // Returns the window peer or null if this is a window peer
4632N/A protected final LWWindowPeer getWindowPeer() {
4632N/A return windowPeer;
4632N/A }
4632N/A
4632N/A // Returns the window peer or 'this' if this is a window peer
4632N/A protected LWWindowPeer getWindowPeerOrSelf() {
4632N/A return getWindowPeer();
4632N/A }
4632N/A
4632N/A // Just a helper method
4632N/A protected final LWContainerPeer getContainerPeer() {
4632N/A return containerPeer;
4632N/A }
4632N/A
4632N/A // Just a helper method
4639N/A // Overridden in LWWindowPeer to skip containerPeer initialization
4632N/A protected void initializeContainerPeer() {
4632N/A Container parent = LWToolkit.getNativeContainer(target);
4632N/A if (parent != null) {
4632N/A containerPeer = (LWContainerPeer) LWToolkit.targetToPeer(parent);
4632N/A }
4632N/A }
4632N/A
4632N/A public PlatformWindow getPlatformWindow() {
4632N/A LWWindowPeer windowPeer = getWindowPeer();
4632N/A return windowPeer.getPlatformWindow();
4632N/A }
4632N/A
4639N/A protected AppContext getAppContext() {
4639N/A return SunToolkit.targetToAppContext(getTarget());
4639N/A }
4639N/A
4632N/A // ---- PEER METHODS ---- //
4632N/A
4632N/A @Override
4632N/A public Toolkit getToolkit() {
4632N/A return LWToolkit.getLWToolkit();
4632N/A }
4632N/A
4632N/A // Just a helper method
4632N/A public LWToolkit getLWToolkit() {
4632N/A return LWToolkit.getLWToolkit();
4632N/A }
4632N/A
4632N/A @Override
5032N/A public final void dispose() {
4632N/A if (disposed.compareAndSet(false, true)) {
4632N/A disposeImpl();
4632N/A }
4632N/A }
4632N/A
4632N/A protected void disposeImpl() {
4632N/A LWContainerPeer cp = getContainerPeer();
4632N/A if (cp != null) {
4632N/A cp.removeChildPeer(this);
4632N/A }
4632N/A platformComponent.dispose();
4632N/A LWToolkit.targetDisposedPeer(getTarget(), this);
4632N/A }
4632N/A
4632N/A public final boolean isDisposed() {
4632N/A return disposed.get();
4632N/A }
4632N/A
4632N/A /*
4632N/A * GraphicsConfiguration is borrowed from the parent peer. The
4632N/A * return value must not be null.
4632N/A *
4632N/A * Overridden in LWWindowPeer.
4632N/A */
4632N/A @Override
4632N/A public GraphicsConfiguration getGraphicsConfiguration() {
4632N/A // Don't check windowPeer for null as it can only happen
4632N/A // for windows, but this method is overridden in
4632N/A // LWWindowPeer and doesn't call super()
4632N/A return getWindowPeer().getGraphicsConfiguration();
4632N/A }
4632N/A
4632N/A /*
4632N/A * Overridden in LWWindowPeer to replace its surface
4632N/A * data and back buffer.
4632N/A */
4632N/A @Override
4632N/A public boolean updateGraphicsData(GraphicsConfiguration gc) {
4632N/A // TODO: not implemented
4632N/A// throw new RuntimeException("Has not been implemented yet.");
4632N/A return false;
4632N/A }
4632N/A
4639N/A @Override
4686N/A public final Graphics getGraphics() {
5232N/A final Graphics g = getOnscreenGraphics();
4639N/A if (g != null) {
4639N/A synchronized (getPeerTreeLock()){
4639N/A applyConstrain(g);
4639N/A }
4639N/A }
4639N/A return g;
4639N/A }
4639N/A
4632N/A /*
4632N/A * Peer Graphics is borrowed from the parent peer, while
4632N/A * foreground and background colors and font are specific to
4632N/A * this peer.
4632N/A */
4639N/A public final Graphics getOnscreenGraphics() {
4639N/A final LWWindowPeer wp = getWindowPeerOrSelf();
4639N/A return wp.getOnscreenGraphics(getForeground(), getBackground(),
4639N/A getFont());
4632N/A
4639N/A }
4639N/A
4639N/A private void applyConstrain(final Graphics g) {
4639N/A final SunGraphics2D sg2d = (SunGraphics2D) g;
6084N/A final Rectangle size = localToWindow(getSize());
6084N/A sg2d.constrain(size.x, size.y, size.width, size.height, getVisibleRegion());
4632N/A }
4632N/A
4639N/A public Region getVisibleRegion() {
4639N/A return computeVisibleRect(this, getRegion());
4639N/A }
4639N/A
4639N/A static final Region computeVisibleRect(LWComponentPeer c, Region region) {
4639N/A final LWContainerPeer p = c.getContainerPeer();
4639N/A if (p != null) {
4639N/A final Rectangle r = c.getBounds();
4639N/A region = region.getTranslatedRegion(r.x, r.y);
4639N/A region = region.getIntersection(p.getRegion());
4639N/A region = region.getIntersection(p.getContentSize());
4639N/A region = p.cutChildren(region, c);
4639N/A region = computeVisibleRect(p, region);
4639N/A region = region.getTranslatedRegion(-r.x, -r.y);
4632N/A }
4639N/A return region;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public ColorModel getColorModel() {
4632N/A // Is it a correct implementation?
4632N/A return getGraphicsConfiguration().getColorModel();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void createBuffers(int numBuffers, BufferCapabilities caps)
4632N/A throws AWTException {
4632N/A throw new AWTException("Back buffers are only supported for " +
4632N/A "Window or Canvas components.");
4632N/A }
4632N/A
4632N/A /*
4632N/A * To be overridden in LWWindowPeer and LWCanvasPeer.
4632N/A */
4632N/A @Override
4632N/A public Image getBackBuffer() {
4632N/A // Return null or throw AWTException?
4632N/A return null;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void flip(int x1, int y1, int x2, int y2,
4632N/A BufferCapabilities.FlipContents flipAction) {
4632N/A // Skip silently or throw AWTException?
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void destroyBuffers() {
4632N/A // Do nothing
4632N/A }
4632N/A
4632N/A // Helper method
4632N/A public void setBounds(Rectangle r) {
4632N/A setBounds(r.x, r.y, r.width, r.height, SET_BOUNDS);
4632N/A }
4632N/A
4639N/A /**
4639N/A * This method could be called on the toolkit thread.
4639N/A */
4632N/A @Override
4632N/A public void setBounds(int x, int y, int w, int h, int op) {
4639N/A setBounds(x, y, w, h, op, true, false);
4632N/A }
4632N/A
4639N/A protected void setBounds(int x, int y, int w, int h, int op, boolean notify,
4639N/A final boolean updateTarget) {
4632N/A Rectangle oldBounds;
4632N/A synchronized (getStateLock()) {
4632N/A oldBounds = new Rectangle(bounds);
4632N/A if ((op & (SET_LOCATION | SET_BOUNDS)) != 0) {
4632N/A bounds.x = x;
4632N/A bounds.y = y;
4632N/A }
4632N/A if ((op & (SET_SIZE | SET_BOUNDS)) != 0) {
4632N/A bounds.width = w;
4632N/A bounds.height = h;
4632N/A }
4632N/A }
4639N/A boolean moved = (oldBounds.x != x) || (oldBounds.y != y);
4639N/A boolean resized = (oldBounds.width != w) || (oldBounds.height != h);
4639N/A if (!moved && !resized) {
4639N/A return;
4639N/A }
4639N/A final D delegate = getDelegate();
4639N/A if (delegate != null) {
4639N/A synchronized (getDelegateLock()) {
4639N/A delegateContainer.setBounds(0, 0, w, h);
4639N/A delegate.setBounds(delegateContainer.getBounds());
4639N/A // TODO: the following means that the delegateContainer NEVER gets validated. That's WRONG!
4639N/A delegate.validate();
4632N/A }
4632N/A }
4639N/A
4639N/A final Point locationInWindow = localToWindow(0, 0);
4639N/A platformComponent.setBounds(locationInWindow.x, locationInWindow.y, w,
4639N/A h);
4639N/A if (notify) {
4639N/A repaintOldNewBounds(oldBounds);
4639N/A if (resized) {
4639N/A handleResize(w, h, updateTarget);
4639N/A }
4639N/A if (moved) {
4639N/A handleMove(x, y, updateTarget);
4639N/A }
4639N/A }
4632N/A }
4632N/A
4639N/A public final Rectangle getBounds() {
4632N/A synchronized (getStateLock()) {
4632N/A // Return a copy to prevent subsequent modifications
4639N/A return bounds.getBounds();
4639N/A }
4639N/A }
4639N/A
4639N/A public final Rectangle getSize() {
4639N/A synchronized (getStateLock()) {
4639N/A // Return a copy to prevent subsequent modifications
4639N/A return new Rectangle(bounds.width, bounds.height);
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4632N/A public Point getLocationOnScreen() {
4632N/A Point windowLocation = getWindowPeer().getLocationOnScreen();
4632N/A Point locationInWindow = localToWindow(0, 0);
4632N/A return new Point(windowLocation.x + locationInWindow.x,
4632N/A windowLocation.y + locationInWindow.y);
4632N/A }
4632N/A
5137N/A /**
5137N/A * Returns the cursor of the peer, which is cursor of the target by default,
5137N/A * but peer can override this behavior.
5137N/A *
5137N/A * @param p Point relative to the peer.
5137N/A * @return Cursor of the peer or null if default cursor should be used.
5137N/A */
5137N/A protected Cursor getCursor(final Point p) {
5137N/A return getTarget().getCursor();
5137N/A }
5137N/A
4632N/A @Override
4691N/A public void setBackground(final Color c) {
4691N/A final Color oldBg = getBackground();
4691N/A if (oldBg == c || (oldBg != null && oldBg.equals(c))) {
4691N/A return;
4691N/A }
4691N/A synchronized (getStateLock()) {
4691N/A background = c;
4691N/A }
4691N/A final D delegate = getDelegate();
4691N/A if (delegate != null) {
4691N/A synchronized (getDelegateLock()) {
4632N/A // delegate will repaint the target
4632N/A delegate.setBackground(c);
4632N/A }
4691N/A } else {
4691N/A repaintPeer();
4632N/A }
4632N/A }
4632N/A
4691N/A protected final Color getBackground() {
4691N/A synchronized (getStateLock()) {
4691N/A return background;
4632N/A }
4632N/A }
4632N/A
4691N/A @Override
4691N/A public void setForeground(final Color c) {
4691N/A final Color oldFg = getForeground();
4691N/A if (oldFg == c || (oldFg != null && oldFg.equals(c))) {
4691N/A return;
4691N/A }
4691N/A synchronized (getStateLock()) {
4691N/A foreground = c;
4691N/A }
4691N/A final D delegate = getDelegate();
4691N/A if (delegate != null) {
4691N/A synchronized (getDelegateLock()) {
4691N/A // delegate will repaint the target
4691N/A delegate.setForeground(c);
4632N/A }
4691N/A } else {
4691N/A repaintPeer();
4632N/A }
4691N/A }
4691N/A
4691N/A protected final Color getForeground() {
4691N/A synchronized (getStateLock()) {
4691N/A return foreground;
4691N/A }
4632N/A }
4632N/A
4632N/A @Override
4691N/A public void setFont(final Font f) {
4691N/A final Font oldF = getFont();
4691N/A if (oldF == f || (oldF != null && oldF.equals(f))) {
4691N/A return;
4691N/A }
4691N/A synchronized (getStateLock()) {
4691N/A font = f;
4691N/A }
4691N/A final D delegate = getDelegate();
4691N/A if (delegate != null) {
4691N/A synchronized (getDelegateLock()) {
4632N/A // delegate will repaint the target
4632N/A delegate.setFont(f);
4632N/A }
4691N/A } else {
4691N/A repaintPeer();
4632N/A }
4632N/A }
4632N/A
4691N/A protected final Font getFont() {
4691N/A synchronized (getStateLock()) {
4691N/A return font;
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4632N/A public FontMetrics getFontMetrics(Font f) {
4632N/A // Borrow the metrics from the top-level window
4632N/A// return getWindowPeer().getFontMetrics(f);
4632N/A // Obtain the metrics from the offscreen window where this peer is
4632N/A // mostly drawn to.
4632N/A // TODO: check for "use platform metrics" settings
5232N/A Graphics g = getWindowPeer().getGraphics();
4632N/A try {
4632N/A if (g != null) {
4632N/A return g.getFontMetrics(f);
4632N/A } else {
4632N/A synchronized (getDelegateLock()) {
4632N/A return delegateContainer.getFontMetrics(f);
4632N/A }
4632N/A }
4632N/A } finally {
4632N/A if (g != null) {
4632N/A g.dispose();
4632N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void setEnabled(final boolean e) {
4632N/A boolean status = e;
4632N/A final LWComponentPeer cp = getContainerPeer();
4632N/A if (cp != null) {
4632N/A status &= cp.isEnabled();
4632N/A }
4632N/A synchronized (getStateLock()) {
4632N/A if (enabled == status) {
4632N/A return;
4632N/A }
4632N/A enabled = status;
4632N/A }
4632N/A
4632N/A final D delegate = getDelegate();
4632N/A
4632N/A if (delegate != null) {
4632N/A synchronized (getDelegateLock()) {
4632N/A delegate.setEnabled(status);
4632N/A }
4632N/A } else {
4632N/A repaintPeer();
4632N/A }
4632N/A }
4632N/A
4632N/A // Helper method
4691N/A public final boolean isEnabled() {
4632N/A synchronized (getStateLock()) {
4632N/A return enabled;
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
5166N/A public void setVisible(final boolean v) {
4632N/A synchronized (getStateLock()) {
4632N/A if (visible == v) {
4632N/A return;
4632N/A }
4632N/A visible = v;
4632N/A }
5166N/A setVisibleImpl(v);
5166N/A }
4632N/A
5166N/A protected void setVisibleImpl(final boolean v) {
4632N/A final D delegate = getDelegate();
4632N/A
4632N/A if (delegate != null) {
4632N/A synchronized (getDelegateLock()) {
4632N/A delegate.setVisible(v);
4632N/A }
4632N/A }
4639N/A if (visible) {
4639N/A repaintPeer();
4639N/A } else {
4639N/A repaintParent(getBounds());
4632N/A }
4632N/A }
4632N/A
4632N/A // Helper method
4691N/A public final boolean isVisible() {
4632N/A synchronized (getStateLock()) {
4632N/A return visible;
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4639N/A public void paint(final Graphics g) {
4632N/A getTarget().paint(g);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void print(final Graphics g) {
4632N/A getTarget().print(g);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void reparent(ContainerPeer newContainer) {
4632N/A // TODO: not implemented
4632N/A throw new UnsupportedOperationException("ComponentPeer.reparent()");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean isReparentSupported() {
4632N/A // TODO: not implemented
4632N/A return false;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void setZOrder(ComponentPeer above) {
4632N/A LWContainerPeer cp = getContainerPeer();
4632N/A // Don't check containerPeer for null as it can only happen
4632N/A // for windows, but this method is overridden in
4632N/A // LWWindowPeer and doesn't call super()
4632N/A cp.setChildPeerZOrder(this, (LWComponentPeer) above);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void coalescePaintEvent(PaintEvent e) {
4632N/A if (!(e instanceof IgnorePaintEvent)) {
4632N/A Rectangle r = e.getUpdateRect();
4632N/A if ((r != null) && !r.isEmpty()) {
4632N/A targetPaintArea.add(r, e.getID());
4632N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A /*
4632N/A * Should be overridden in subclasses which use complex Swing components.
4632N/A */
4632N/A @Override
4632N/A public void layout() {
4632N/A // TODO: not implemented
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean isObscured() {
4632N/A // TODO: not implemented
4632N/A return false;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean canDetermineObscurity() {
4632N/A // TODO: not implemented
4632N/A return false;
4632N/A }
4632N/A
4639N/A /**
4639N/A * Should be overridden in subclasses to forward the request
4632N/A * to the Swing helper component, if required.
4632N/A */
4632N/A @Override
4632N/A public Dimension getPreferredSize() {
4632N/A // It looks like a default implementation for all toolkits
4632N/A return getMinimumSize();
4632N/A }
4632N/A
4632N/A /*
4632N/A * Should be overridden in subclasses to forward the request
4632N/A * to the Swing helper component.
4632N/A */
4632N/A @Override
4632N/A public Dimension getMinimumSize() {
4632N/A D delegate = getDelegate();
4632N/A
4632N/A if (delegate == null) {
4632N/A // Is it a correct default value?
4632N/A return getBounds().getSize();
4632N/A } else {
4632N/A synchronized (getDelegateLock()) {
4632N/A return delegate.getMinimumSize();
4632N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void updateCursorImmediately() {
4632N/A getLWToolkit().getCursorManager().updateCursor();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean isFocusable() {
4632N/A // Overridden in focusable subclasses like buttons
4632N/A return false;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean requestFocus(Component lightweightChild, boolean temporary,
4632N/A boolean focusedWindowChangeAllowed, long time,
4886N/A CausedFocusEvent.Cause cause)
4886N/A {
4886N/A if (focusLog.isLoggable(PlatformLogger.FINEST)) {
4886N/A focusLog.finest("lightweightChild=" + lightweightChild + ", temporary=" + temporary +
4886N/A ", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
4886N/A ", time= " + time + ", cause=" + cause);
4886N/A }
5336N/A if (LWKeyboardFocusManagerPeer.processSynchronousLightweightTransfer(
5336N/A getTarget(), lightweightChild, temporary,
5336N/A focusedWindowChangeAllowed, time)) {
4632N/A return true;
4632N/A }
4632N/A
5336N/A int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
5336N/A getTarget(), lightweightChild, temporary,
5336N/A focusedWindowChangeAllowed, time, cause);
4632N/A switch (result) {
4632N/A case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
4632N/A return false;
4632N/A case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:
4632N/A Window parentWindow = SunToolkit.getContainingWindow(getTarget());
4632N/A if (parentWindow == null) {
4886N/A focusLog.fine("request rejected, parentWindow is null");
4632N/A LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
4632N/A return false;
4632N/A }
4632N/A LWWindowPeer parentPeer = (LWWindowPeer) parentWindow.getPeer();
4632N/A if (parentPeer == null) {
4886N/A focusLog.fine("request rejected, parentPeer is null");
4632N/A LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
4632N/A return false;
4632N/A }
4632N/A
4886N/A // A fix for 7145768. Ensure the parent window is currently natively focused.
4886N/A // The more evident place to perform this check is in KFM.shouldNativelyFocusHeavyweight,
4886N/A // however that is the shared code and this particular problem's reproducibility has
4886N/A // platform specifics. So, it was decided to narrow down the fix to lwawt (OSX) in
4886N/A // current release. TODO: consider fixing it in the shared code.
4886N/A if (!focusedWindowChangeAllowed) {
4886N/A LWWindowPeer decoratedPeer = parentPeer.isSimpleWindow() ?
4886N/A LWWindowPeer.getOwnerFrameDialog(parentPeer) : parentPeer;
4886N/A
4886N/A if (decoratedPeer == null || !decoratedPeer.getPlatformWindow().isActive()) {
4886N/A if (focusLog.isLoggable(PlatformLogger.FINE)) {
4886N/A focusLog.fine("request rejected, focusedWindowChangeAllowed==false, " +
4886N/A "decoratedPeer is inactive: " + decoratedPeer);
4886N/A }
4886N/A LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
4886N/A return false;
4886N/A }
4886N/A }
4886N/A
4632N/A boolean res = parentPeer.requestWindowFocus(cause);
4632N/A // If parent window can be made focused and has been made focused (synchronously)
4632N/A // then we can proceed with children, otherwise we retreat
4632N/A if (!res || !parentWindow.isFocused()) {
4886N/A if (focusLog.isLoggable(PlatformLogger.FINE)) {
4886N/A focusLog.fine("request rejected, res= " + res + ", parentWindow.isFocused()=" +
4886N/A parentWindow.isFocused());
4886N/A }
4632N/A LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
4632N/A return false;
4632N/A }
4632N/A
5336N/A KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
5336N/A Component focusOwner = kfmPeer.getCurrentFocusOwner();
4632N/A return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
4632N/A getTarget(), temporary,
4632N/A focusedWindowChangeAllowed,
4632N/A time, cause, focusOwner);
5336N/A
4632N/A case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
4632N/A return true;
4632N/A }
4632N/A
4632N/A return false;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public Image createImage(ImageProducer producer) {
4632N/A return new ToolkitImage(producer);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public Image createImage(int w, int h) {
5039N/A CGraphicsConfig gc = (CGraphicsConfig)getGraphicsConfiguration();
5039N/A return gc.createAcceleratedImage(getTarget(), w, h);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public VolatileImage createVolatileImage(int w, int h) {
4632N/A // TODO: is it a right/complete implementation?
4632N/A return new SunVolatileImage(getTarget(), w, h);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
4632N/A // TODO: is it a right/complete implementation?
4632N/A return getToolkit().prepareImage(img, w, h, o);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public int checkImage(Image img, int w, int h, ImageObserver o) {
4632N/A // TODO: is it a right/complete implementation?
4632N/A return getToolkit().checkImage(img, w, h, o);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean handlesWheelScrolling() {
4632N/A // TODO: not implemented
4632N/A return false;
4632N/A }
4632N/A
4632N/A @Override
4639N/A public final void applyShape(final Region shape) {
4639N/A synchronized (getStateLock()) {
5232N/A if (region == shape || (region != null && region.equals(shape))) {
5232N/A return;
5232N/A }
5232N/A }
5232N/A applyShapeImpl(shape);
5232N/A }
5232N/A
5232N/A void applyShapeImpl(final Region shape) {
5232N/A synchronized (getStateLock()) {
5232N/A if (shape != null) {
5232N/A region = Region.WHOLE_REGION.getIntersection(shape);
5232N/A } else {
5232N/A region = null;
5232N/A }
4632N/A }
4639N/A repaintParent(getBounds());
4632N/A }
4632N/A
4639N/A protected final Region getRegion() {
4632N/A synchronized (getStateLock()) {
5232N/A return isShaped() ? region : Region.getInstance(getSize());
5232N/A }
5232N/A }
5232N/A
5232N/A public boolean isShaped() {
5232N/A synchronized (getStateLock()) {
5232N/A return region != null;
4632N/A }
4632N/A }
4632N/A
4632N/A // DropTargetPeer Method
4686N/A @Override
4686N/A public void addDropTarget(DropTarget dt) {
4830N/A LWWindowPeer winPeer = getWindowPeerOrSelf();
4830N/A if (winPeer != null && winPeer != this) {
4830N/A // We need to register the DropTarget in the
4830N/A // peer of the window ancestor of the component
4830N/A winPeer.addDropTarget(dt);
4830N/A } else {
4830N/A synchronized (dropTargetLock) {
4830N/A // 10-14-02 VL: Windows WComponentPeer would add (or remove) the drop target only
4830N/A // if it's the first (or last) one for the component. Otherwise this call is a no-op.
4830N/A if (++fNumDropTargets == 1) {
4830N/A // Having a non-null drop target would be an error but let's check just in case:
4830N/A if (fDropTarget != null)
4830N/A System.err.println("CComponent.addDropTarget(): current drop target is non-null.");
4632N/A
4830N/A // Create a new drop target:
4830N/A fDropTarget = CDropTarget.createDropTarget(dt, target, this);
4830N/A }
4686N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A // DropTargetPeer Method
4686N/A @Override
4686N/A public void removeDropTarget(DropTarget dt) {
4830N/A LWWindowPeer winPeer = getWindowPeerOrSelf();
4830N/A if (winPeer != null && winPeer != this) {
4830N/A // We need to unregister the DropTarget in the
4830N/A // peer of the window ancestor of the component
4830N/A winPeer.removeDropTarget(dt);
4830N/A } else {
4830N/A synchronized (dropTargetLock){
4830N/A // 10-14-02 VL: Windows WComponentPeer would add (or remove) the drop target only
4830N/A // if it's the first (or last) one for the component. Otherwise this call is a no-op.
4830N/A if (--fNumDropTargets == 0) {
4830N/A // Having a null drop target would be an error but let's check just in case:
4830N/A if (fDropTarget != null) {
4830N/A // Dispose of the drop target:
4830N/A fDropTarget.dispose();
4830N/A fDropTarget = null;
4830N/A } else
4830N/A System.err.println("CComponent.removeDropTarget(): current drop target is null.");
4830N/A }
4686N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A // ---- PEER NOTIFICATIONS ---- //
4632N/A
4639N/A /**
4632N/A * Called when this peer's location has been changed either as a result
4632N/A * of target.setLocation() or as a result of user actions (window is
4632N/A * dragged with mouse).
4632N/A *
4632N/A * To be overridden in LWWindowPeer to update its GraphicsConfig.
4632N/A *
4632N/A * This method could be called on the toolkit thread.
4632N/A */
4639N/A protected final void handleMove(final int x, final int y,
4639N/A final boolean updateTarget) {
4639N/A if (updateTarget) {
4639N/A AWTAccessor.getComponentAccessor().setLocation(getTarget(), x, y);
4632N/A }
4639N/A postEvent(new ComponentEvent(getTarget(),
4639N/A ComponentEvent.COMPONENT_MOVED));
4632N/A }
4632N/A
4639N/A /**
4632N/A * Called when this peer's size has been changed either as a result of
4632N/A * target.setSize() or as a result of user actions (window is resized).
4632N/A *
4632N/A * To be overridden in LWWindowPeer to update its SurfaceData and
4632N/A * GraphicsConfig.
4632N/A *
4632N/A * This method could be called on the toolkit thread.
4632N/A */
4639N/A protected final void handleResize(final int w, final int h,
4639N/A final boolean updateTarget) {
4639N/A if (updateTarget) {
4639N/A AWTAccessor.getComponentAccessor().setSize(getTarget(), w, h);
4639N/A }
4639N/A postEvent(new ComponentEvent(getTarget(),
4639N/A ComponentEvent.COMPONENT_RESIZED));
4639N/A }
4639N/A
4639N/A protected final void repaintOldNewBounds(final Rectangle oldB) {
4639N/A repaintParent(oldB);
4639N/A repaintPeer(getSize());
4639N/A }
4639N/A
4639N/A protected final void repaintParent(final Rectangle oldB) {
4639N/A final LWContainerPeer cp = getContainerPeer();
4632N/A if (cp != null) {
4632N/A // Repaint unobscured part of the parent
4639N/A cp.repaintPeer(cp.getContentSize().intersection(oldB));
4632N/A }
4632N/A }
4632N/A
4632N/A // ---- EVENTS ---- //
4632N/A
4639N/A /**
4632N/A * Post an event to the proper Java EDT.
4632N/A */
4632N/A public void postEvent(AWTEvent event) {
4639N/A SunToolkit.postEvent(getAppContext(), event);
4632N/A }
4632N/A
4632N/A protected void postPaintEvent(int x, int y, int w, int h) {
4632N/A // TODO: call getIgnoreRepaint() directly with the right ACC
4632N/A if (AWTAccessor.getComponentAccessor().getIgnoreRepaint(target)) {
4632N/A return;
4632N/A }
4632N/A PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher().
4632N/A createPaintEvent(getTarget(), x, y, w, h);
4632N/A if (event != null) {
4632N/A postEvent(event);
4632N/A }
4632N/A }
4632N/A
4632N/A /*
4632N/A * Gives a chance for the peer to handle the event after it's been
4632N/A * processed by the target.
4632N/A */
4632N/A @Override
4632N/A public void handleEvent(AWTEvent e) {
4632N/A if ((e instanceof InputEvent) && ((InputEvent) e).isConsumed()) {
4632N/A return;
4632N/A }
4632N/A switch (e.getID()) {
4632N/A case FocusEvent.FOCUS_GAINED:
4632N/A case FocusEvent.FOCUS_LOST:
4632N/A handleJavaFocusEvent((FocusEvent) e);
4632N/A break;
4632N/A case PaintEvent.PAINT:
4632N/A // Got a native paint event
4632N/A// paintPending = false;
4632N/A // fall through to the next statement
4632N/A case PaintEvent.UPDATE:
4639N/A handleJavaPaintEvent();
4632N/A break;
4632N/A case MouseEvent.MOUSE_PRESSED:
4717N/A handleJavaMouseEvent((MouseEvent)e);
4632N/A }
4632N/A
4632N/A sendEventToDelegate(e);
4632N/A }
4632N/A
4826N/A protected void sendEventToDelegate(final AWTEvent e) {
6069N/A if (getDelegate() == null || !isShowing() || !isEnabled()) {
6069N/A return;
6069N/A }
4632N/A synchronized (getDelegateLock()) {
4632N/A AWTEvent delegateEvent = createDelegateEvent(e);
4632N/A if (delegateEvent != null) {
4632N/A AWTAccessor.getComponentAccessor()
4632N/A .processEvent((Component) delegateEvent.getSource(),
4632N/A delegateEvent);
4632N/A if (delegateEvent instanceof KeyEvent) {
4632N/A KeyEvent ke = (KeyEvent) delegateEvent;
4632N/A SwingUtilities.processKeyBindings(ke);
4632N/A }
4632N/A }
4632N/A }
4632N/A }
4632N/A
6069N/A /**
6069N/A * Changes the target of the AWTEvent from awt component to appropriate
6069N/A * swing delegate.
6069N/A */
6069N/A private AWTEvent createDelegateEvent(final AWTEvent e) {
6069N/A // TODO modifiers should be changed to getModifiers()|getModifiersEx()?
4632N/A AWTEvent delegateEvent = null;
4632N/A if (e instanceof MouseWheelEvent) {
4632N/A MouseWheelEvent me = (MouseWheelEvent) e;
4632N/A delegateEvent = new MouseWheelEvent(
4632N/A delegate, me.getID(), me.getWhen(),
4632N/A me.getModifiers(),
4632N/A me.getX(), me.getY(),
4632N/A me.getClickCount(),
4781N/A me.isPopupTrigger(),
4781N/A me.getScrollType(),
4781N/A me.getScrollAmount(),
4632N/A me.getWheelRotation());
4632N/A } else if (e instanceof MouseEvent) {
4632N/A MouseEvent me = (MouseEvent) e;
4632N/A
4632N/A Component eventTarget = SwingUtilities.getDeepestComponentAt(delegate, me.getX(), me.getY());
4632N/A
4632N/A if (me.getID() == MouseEvent.MOUSE_DRAGGED) {
4632N/A if (delegateDropTarget == null) {
4632N/A delegateDropTarget = eventTarget;
4632N/A } else {
4632N/A eventTarget = delegateDropTarget;
4632N/A }
4632N/A }
4632N/A if (me.getID() == MouseEvent.MOUSE_RELEASED && delegateDropTarget != null) {
4632N/A eventTarget = delegateDropTarget;
4632N/A delegateDropTarget = null;
4632N/A }
4632N/A if (eventTarget == null) {
4632N/A eventTarget = delegate;
4632N/A }
4632N/A delegateEvent = SwingUtilities.convertMouseEvent(getTarget(), me, eventTarget);
4632N/A } else if (e instanceof KeyEvent) {
4632N/A KeyEvent ke = (KeyEvent) e;
4632N/A delegateEvent = new KeyEvent(getDelegateFocusOwner(), ke.getID(), ke.getWhen(),
4632N/A ke.getModifiers(), ke.getKeyCode(), ke.getKeyChar(), ke.getKeyLocation());
4632N/A } else if (e instanceof FocusEvent) {
4632N/A FocusEvent fe = (FocusEvent) e;
4632N/A delegateEvent = new FocusEvent(getDelegateFocusOwner(), fe.getID(), fe.isTemporary());
4632N/A }
4632N/A return delegateEvent;
4632N/A }
4632N/A
4717N/A protected void handleJavaMouseEvent(MouseEvent e) {
4717N/A Component target = getTarget();
4717N/A assert (e.getSource() == target);
4717N/A
4717N/A if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
4717N/A LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
4717N/A } else {
4717N/A // Anyway request focus to the toplevel.
4717N/A getWindowPeerOrSelf().requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
4717N/A }
4717N/A }
4717N/A
4639N/A /**
4639N/A * Handler for FocusEvents.
4639N/A */
4632N/A protected void handleJavaFocusEvent(FocusEvent e) {
4632N/A // Note that the peer receives all the FocusEvents from
4632N/A // its lightweight children as well
5336N/A KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
5336N/A kfmPeer.setCurrentFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? getTarget() : null);
4632N/A }
4632N/A
4639N/A /**
4767N/A * All peers should clear background before paint.
4639N/A *
4639N/A * @return false on components that DO NOT require a clearRect() before
4639N/A * painting.
4639N/A */
4639N/A protected final boolean shouldClearRectBeforePaint() {
4639N/A // TODO: sun.awt.noerasebackground
4767N/A return true;
4639N/A }
4639N/A
4639N/A /**
4632N/A * Handler for PAINT and UPDATE PaintEvents.
4632N/A */
4639N/A private void handleJavaPaintEvent() {
4632N/A // Skip all painting while layouting and all UPDATEs
4632N/A // while waiting for native paint
4632N/A// if (!isLayouting && !paintPending) {
4639N/A if (!isLayouting()) {
4639N/A targetPaintArea.paint(getTarget(), shouldClearRectBeforePaint());
4632N/A }
4632N/A }
4632N/A
4632N/A // ---- UTILITY METHODS ---- //
4632N/A
4632N/A /**
4632N/A * Finds a top-most visible component for the given point. The location is
4632N/A * specified relative to the peer's parent.
4632N/A */
4632N/A public LWComponentPeer findPeerAt(final int x, final int y) {
4632N/A final Rectangle r = getBounds();
4639N/A final Region sh = getRegion();
4639N/A final boolean found = isVisible() && sh.contains(x - r.x, y - r.y);
4632N/A return found ? this : null;
4632N/A }
4632N/A
4632N/A /*
4632N/A * Translated the given point in Window coordinates to the point in
4632N/A * coordinates local to this component. The given window peer must be
4632N/A * the window where this component is in.
4632N/A */
4632N/A public Point windowToLocal(int x, int y, LWWindowPeer wp) {
4632N/A return windowToLocal(new Point(x, y), wp);
4632N/A }
4632N/A
4632N/A public Point windowToLocal(Point p, LWWindowPeer wp) {
4632N/A LWComponentPeer cp = this;
4632N/A while (cp != wp) {
4632N/A Rectangle cpb = cp.getBounds();
4632N/A p.x -= cpb.x;
4632N/A p.y -= cpb.y;
4632N/A cp = cp.getContainerPeer();
4632N/A }
4632N/A // Return a copy to prevent subsequent modifications
4632N/A return new Point(p);
4632N/A }
4632N/A
4632N/A public Rectangle windowToLocal(Rectangle r, LWWindowPeer wp) {
4632N/A Point p = windowToLocal(r.getLocation(), wp);
4632N/A return new Rectangle(p, r.getSize());
4632N/A }
4632N/A
4632N/A public Point localToWindow(int x, int y) {
4632N/A return localToWindow(new Point(x, y));
4632N/A }
4632N/A
4632N/A public Point localToWindow(Point p) {
4632N/A LWComponentPeer cp = getContainerPeer();
4632N/A Rectangle r = getBounds();
4632N/A while (cp != null) {
4632N/A p.x += r.x;
4632N/A p.y += r.y;
4632N/A r = cp.getBounds();
4632N/A cp = cp.getContainerPeer();
4632N/A }
4632N/A // Return a copy to prevent subsequent modifications
4632N/A return new Point(p);
4632N/A }
4632N/A
4632N/A public Rectangle localToWindow(Rectangle r) {
4632N/A Point p = localToWindow(r.getLocation());
4632N/A return new Rectangle(p, r.getSize());
4632N/A }
4632N/A
4639N/A public final void repaintPeer() {
4639N/A repaintPeer(getSize());
4632N/A }
4632N/A
4639N/A public void repaintPeer(final Rectangle r) {
4639N/A final Rectangle toPaint = getSize().intersection(r);
4639N/A if (!isShowing() || toPaint.isEmpty()) {
4632N/A return;
4632N/A }
4632N/A
4639N/A postPaintEvent(toPaint.x, toPaint.y, toPaint.width, toPaint.height);
4632N/A }
4632N/A
4632N/A /**
4632N/A * Determines whether this peer is showing on screen. This means that the
4632N/A * peer must be visible, and it must be in a container that is visible and
4632N/A * showing.
4632N/A *
4632N/A * @see #isVisible()
4632N/A */
5166N/A protected final boolean isShowing() {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A if (isVisible()) {
4632N/A final LWContainerPeer container = getContainerPeer();
4632N/A return (container == null) || container.isShowing();
4632N/A }
4632N/A }
4632N/A return false;
4632N/A }
4632N/A
4639N/A /**
4639N/A * Paints the peer. Overridden in subclasses to delegate the actual painting
4639N/A * to Swing components.
4632N/A */
4691N/A protected final void paintPeer(final Graphics g) {
4639N/A final D delegate = getDelegate();
4639N/A if (delegate != null) {
4632N/A if (!SwingUtilities.isEventDispatchThread()) {
4632N/A throw new InternalError("Painting must be done on EDT");
4632N/A }
4632N/A synchronized (getDelegateLock()) {
4632N/A // JComponent.print() is guaranteed to not affect the double buffer
4639N/A getDelegate().print(g);
4632N/A }
4632N/A }
4632N/A }
4632N/A
4639N/A protected static final void flushOnscreenGraphics(){
4639N/A final OGLRenderQueue rq = OGLRenderQueue.getInstance();
4639N/A rq.lock();
4639N/A try {
4639N/A rq.flushNow();
4639N/A } finally {
4639N/A rq.unlock();
4639N/A }
4632N/A }
4632N/A
4639N/A /**
4639N/A * Used by ContainerPeer to skip all the paint events during layout.
4639N/A *
4639N/A * @param isLayouting layouting state.
4639N/A */
4639N/A protected final void setLayouting(final boolean isLayouting) {
4639N/A this.isLayouting = isLayouting;
4639N/A }
4632N/A
4639N/A /**
4639N/A * Returns layouting state. Used by ComponentPeer to skip all the paint
4639N/A * events during layout.
4639N/A *
4639N/A * @return true during layout, false otherwise.
4639N/A */
4639N/A private final boolean isLayouting() {
4639N/A return isLayouting;
4632N/A }
4632N/A}