4632N/A/*
4632N/A * Copyright (c) 2011, 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
4632N/Apackage sun.lwawt;
4632N/A
4632N/Aimport sun.awt.SunGraphicsCallback;
4639N/Aimport sun.java2d.pipe.Region;
4632N/A
4691N/Aimport java.awt.Color;
4632N/Aimport java.awt.Container;
4691N/Aimport java.awt.Font;
4632N/Aimport java.awt.Graphics;
4632N/Aimport java.awt.Insets;
4632N/Aimport java.awt.Rectangle;
4632N/Aimport java.awt.peer.ContainerPeer;
4632N/Aimport java.util.LinkedList;
4632N/Aimport java.util.List;
4632N/A
4632N/Aimport javax.swing.JComponent;
4632N/A
4632N/Aabstract class LWContainerPeer<T extends Container, D extends JComponent>
4632N/A extends LWComponentPeer<T, D>
4632N/A implements ContainerPeer
4632N/A{
4632N/A // List of child peers sorted by z-order from bottom-most
4632N/A // to top-most
4632N/A private List<LWComponentPeer> childPeers =
4632N/A new LinkedList<LWComponentPeer>();
4632N/A
4632N/A LWContainerPeer(T target, PlatformComponent platformComponent) {
4632N/A super(target, platformComponent);
4632N/A }
4632N/A
4632N/A void addChildPeer(LWComponentPeer child) {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A addChildPeer(child, childPeers.size());
4632N/A }
4632N/A }
4632N/A
4632N/A void addChildPeer(LWComponentPeer child, int index) {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A childPeers.add(index, child);
4632N/A }
4632N/A // TODO: repaint
4632N/A }
4632N/A
4632N/A void removeChildPeer(LWComponentPeer child) {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A childPeers.remove(child);
4632N/A }
4632N/A // TODO: repaint
4632N/A }
4632N/A
4632N/A // Used by LWComponentPeer.setZOrder()
4632N/A void setChildPeerZOrder(LWComponentPeer peer, LWComponentPeer above) {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A childPeers.remove(peer);
4632N/A int index = (above != null) ? childPeers.indexOf(above) : childPeers.size();
4632N/A if (index >= 0) {
4632N/A childPeers.add(index, peer);
4632N/A } else {
4632N/A // TODO: log
4632N/A }
4632N/A }
4632N/A // TODO: repaint
4632N/A }
4632N/A
4632N/A // ---- PEER METHODS ---- //
4632N/A
4632N/A /*
4632N/A * Overridden in LWWindowPeer.
4632N/A */
4632N/A @Override
4632N/A public Insets getInsets() {
4632N/A return new Insets(0, 0, 0, 0);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void beginValidate() {
4632N/A // TODO: it seems that begin/endValidate() is only useful
4632N/A // for heavyweight windows, when a batch movement for
4632N/A // child windows occurs. That's why no-op
4632N/A }
4632N/A @Override
4632N/A public void endValidate() {
4632N/A // TODO: it seems that begin/endValidate() is only useful
4632N/A // for heavyweight windows, when a batch movement for
4632N/A // child windows occurs. That's why no-op
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void beginLayout() {
4632N/A // Skip all painting till endLayout()
4632N/A setLayouting(true);
4632N/A }
4632N/A @Override
4632N/A public void endLayout() {
4632N/A setLayouting(false);
4632N/A
4632N/A // Post an empty event to flush all the pending target paints
4632N/A postPaintEvent(0, 0, 0, 0);
4632N/A }
4632N/A
4632N/A // ---- PEER NOTIFICATIONS ---- //
4632N/A
4632N/A /*
4632N/A * Returns a copy of the childPeer collection.
4632N/A */
4632N/A protected List<LWComponentPeer> getChildren() {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A Object copy = ((LinkedList)childPeers).clone();
4632N/A return (List<LWComponentPeer>)copy;
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4639N/A public final Region getVisibleRegion() {
4639N/A return cutChildren(super.getVisibleRegion(), null);
4632N/A }
4632N/A
4639N/A /**
4639N/A * Removes bounds of children above specific child from the region. If above
4639N/A * is null removes all bounds of children.
4632N/A */
4639N/A protected final Region cutChildren(Region r, final LWComponentPeer above) {
4639N/A boolean aboveFound = above == null;
4639N/A for (final LWComponentPeer child : getChildren()) {
4639N/A if (!aboveFound && child == above) {
4639N/A aboveFound = true;
4639N/A continue;
4639N/A }
4639N/A if (aboveFound) {
4639N/A if(child.isVisible()){
4639N/A final Rectangle cb = child.getBounds();
4639N/A final Region cr = child.getRegion();
4639N/A final Region tr = cr.getTranslatedRegion(cb.x, cb.y);
4639N/A r = r.getDifference(tr.getIntersection(getContentSize()));
4639N/A }
4639N/A }
4632N/A }
4639N/A return r;
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 @Override
4632N/A public final LWComponentPeer findPeerAt(int x, int y) {
4632N/A LWComponentPeer peer = super.findPeerAt(x, y);
4632N/A final Rectangle r = getBounds();
4632N/A // Translate to this container's coordinates to pass to children
4632N/A x -= r.x;
4632N/A y -= r.y;
4632N/A if (peer != null && getContentSize().contains(x, y)) {
4632N/A synchronized (getPeerTreeLock()) {
4632N/A for (int i = childPeers.size() - 1; i >= 0; --i) {
4632N/A LWComponentPeer p = childPeers.get(i).findPeerAt(x, y);
4632N/A if (p != null) {
4632N/A peer = p;
4632N/A break;
4632N/A }
4632N/A }
4632N/A }
4632N/A }
4632N/A return peer;
4632N/A }
4632N/A
4632N/A /*
4639N/A * Called by the container when any part of this peer or child
4639N/A * peers should be repainted
4639N/A */
4632N/A @Override
4639N/A public final void repaintPeer(final Rectangle r) {
4639N/A final Rectangle toPaint = getSize().intersection(r);
4639N/A if (!isShowing() || toPaint.isEmpty()) {
4632N/A return;
4632N/A }
4639N/A // First, post the PaintEvent for this peer
4639N/A super.repaintPeer(toPaint);
4639N/A // Second, handle all the children
4639N/A // Use the straight order of children, so the bottom
4639N/A // ones are painted first
4639N/A repaintChildren(toPaint);
4632N/A }
4632N/A
4632N/A /*
4639N/A * Paints all the child peers in the straight z-order, so the
4639N/A * bottom-most ones are painted first.
4639N/A */
4639N/A private void repaintChildren(final Rectangle r) {
4639N/A final Rectangle content = getContentSize();
4639N/A for (final LWComponentPeer child : getChildren()) {
4639N/A final Rectangle childBounds = child.getBounds();
4639N/A Rectangle toPaint = r.intersection(childBounds);
4639N/A toPaint = toPaint.intersection(content);
4639N/A toPaint.translate(-childBounds.x, -childBounds.y);
4639N/A child.repaintPeer(toPaint);
4632N/A }
4632N/A }
4632N/A
4632N/A protected Rectangle getContentSize() {
4639N/A return getSize();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public void setEnabled(final boolean e) {
4632N/A super.setEnabled(e);
4632N/A for (final LWComponentPeer child : getChildren()) {
4632N/A child.setEnabled(e && child.getTarget().isEnabled());
4632N/A }
4632N/A }
4632N/A
4632N/A @Override
4691N/A public void setBackground(final Color c) {
4691N/A for (final LWComponentPeer child : getChildren()) {
4691N/A if (!child.getTarget().isBackgroundSet()) {
4691N/A child.setBackground(c);
4691N/A }
4691N/A }
4691N/A super.setBackground(c);
4691N/A }
4691N/A
4691N/A @Override
4691N/A public void setForeground(final Color c) {
4691N/A for (final LWComponentPeer child : getChildren()) {
4691N/A if (!child.getTarget().isForegroundSet()) {
4691N/A child.setForeground(c);
4691N/A }
4691N/A }
4691N/A super.setForeground(c);
4691N/A }
4691N/A
4691N/A @Override
4691N/A public void setFont(final Font f) {
4691N/A for (final LWComponentPeer child : getChildren()) {
4691N/A if (!child.getTarget().isFontSet()) {
4691N/A child.setFont(f);
4691N/A }
4691N/A }
4691N/A super.setFont(f);
4691N/A }
4691N/A
4691N/A @Override
4639N/A public final void paint(final Graphics g) {
4632N/A super.paint(g);
4691N/A SunGraphicsCallback.PaintHeavyweightComponentsCallback.getInstance()
4691N/A .runComponents(getTarget().getComponents(), g,
4691N/A SunGraphicsCallback.LIGHTWEIGHTS
4691N/A | SunGraphicsCallback.HEAVYWEIGHTS);
4632N/A }
4632N/A
4632N/A @Override
4639N/A public final void print(final Graphics g) {
4632N/A super.print(g);
4691N/A SunGraphicsCallback.PrintHeavyweightComponentsCallback.getInstance()
4691N/A .runComponents(getTarget().getComponents(), g,
4691N/A SunGraphicsCallback.LIGHTWEIGHTS
4691N/A | SunGraphicsCallback.HEAVYWEIGHTS);
4632N/A }
4632N/A}