Path: blob/master/src/java.desktop/macosx/classes/sun/lwawt/LWContainerPeer.java
41153 views
/*1* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.lwawt;2627import sun.awt.SunGraphicsCallback;28import sun.java2d.pipe.Region;2930import java.awt.Color;31import java.awt.Container;32import java.awt.Font;33import java.awt.Graphics;34import java.awt.Insets;35import java.awt.Rectangle;36import java.awt.peer.ContainerPeer;37import java.util.LinkedList;38import java.util.List;3940import javax.swing.JComponent;4142abstract class LWContainerPeer<T extends Container, D extends JComponent>43extends LWCanvasPeer<T, D> implements ContainerPeer {4445/**46* List of child peers sorted by z-order from bottom-most to top-most.47*/48private final List<LWComponentPeer<?, ?>> childPeers = new LinkedList<>();4950LWContainerPeer(final T target, final PlatformComponent platformComponent) {51super(target, platformComponent);52}5354final void addChildPeer(final LWComponentPeer<?, ?> child) {55synchronized (getPeerTreeLock()) {56childPeers.add(childPeers.size(), child);57// TODO: repaint58}59}6061final void removeChildPeer(final LWComponentPeer<?, ?> child) {62synchronized (getPeerTreeLock()) {63childPeers.remove(child);64}65// TODO: repaint66}6768// Used by LWComponentPeer.setZOrder()69final void setChildPeerZOrder(final LWComponentPeer<?, ?> peer,70final LWComponentPeer<?, ?> above) {71synchronized (getPeerTreeLock()) {72childPeers.remove(peer);73int index = (above != null) ? childPeers.indexOf(above) : childPeers.size();74if (index >= 0) {75childPeers.add(index, peer);76} else {77// TODO: log78}79}80// TODO: repaint81}8283// ---- PEER METHODS ---- //8485/*86* Overridden in LWWindowPeer.87*/88@Override89public Insets getInsets() {90return new Insets(0, 0, 0, 0);91}9293@Override94public final void beginValidate() {95// TODO: it seems that begin/endValidate() is only useful96// for heavyweight windows, when a batch movement for97// child windows occurs. That's why no-op98}99100@Override101public final void endValidate() {102// TODO: it seems that begin/endValidate() is only useful103// for heavyweight windows, when a batch movement for104// child windows occurs. That's why no-op105}106107@Override108public final void beginLayout() {109// Skip all painting till endLayout()110setLayouting(true);111}112113@Override114public final void endLayout() {115setLayouting(false);116117// Post an empty event to flush all the pending target paints118postPaintEvent(0, 0, 0, 0);119}120121// ---- PEER NOTIFICATIONS ---- //122123/**124* Returns a copy of the childPeer collection.125*/126@SuppressWarnings("unchecked")127final List<LWComponentPeer<?, ?>> getChildren() {128synchronized (getPeerTreeLock()) {129Object copy = ((LinkedList<?>) childPeers).clone();130return (List<LWComponentPeer<?, ?>>) copy;131}132}133134@Override135final Region getVisibleRegion() {136return cutChildren(super.getVisibleRegion(), null);137}138139/**140* Removes bounds of children above specific child from the region. If above141* is null removes all bounds of children.142*/143final Region cutChildren(Region r, final LWComponentPeer<?, ?> above) {144boolean aboveFound = above == null;145for (final LWComponentPeer<?, ?> child : getChildren()) {146if (!aboveFound && child == above) {147aboveFound = true;148continue;149}150if (aboveFound) {151if(child.isVisible()){152final Rectangle cb = child.getBounds();153final Region cr = child.getRegion();154final Region tr = cr.getTranslatedRegion(cb.x, cb.y);155r = r.getDifference(tr.getIntersection(getContentSize()));156}157}158}159return r;160}161162// ---- UTILITY METHODS ---- //163164/**165* Finds a top-most visible component for the given point. The location is166* specified relative to the peer's parent.167*/168@Override169final LWComponentPeer<?, ?> findPeerAt(int x, int y) {170LWComponentPeer<?, ?> peer = super.findPeerAt(x, y);171final Rectangle r = getBounds();172// Translate to this container's coordinates to pass to children173x -= r.x;174y -= r.y;175if (peer != null && getContentSize().contains(x, y)) {176synchronized (getPeerTreeLock()) {177for (int i = childPeers.size() - 1; i >= 0; --i) {178LWComponentPeer<?, ?> p = childPeers.get(i).findPeerAt(x, y);179if (p != null) {180peer = p;181break;182}183}184}185}186return peer;187}188189/*190* Called by the container when any part of this peer or child191* peers should be repainted192*/193@Override194final void repaintPeer(final Rectangle r) {195final Rectangle toPaint = getSize().intersection(r);196if (!isShowing() || toPaint.isEmpty()) {197return;198}199// First, post the PaintEvent for this peer200super.repaintPeer(toPaint);201// Second, handle all the children202// Use the straight order of children, so the bottom203// ones are painted first204repaintChildren(toPaint);205}206207/**208* Paints all the child peers in the straight z-order, so the209* bottom-most ones are painted first.210*/211private void repaintChildren(final Rectangle r) {212final Rectangle content = getContentSize();213for (final LWComponentPeer<?, ?> child : getChildren()) {214final Rectangle childBounds = child.getBounds();215Rectangle toPaint = r.intersection(childBounds);216toPaint = toPaint.intersection(content);217toPaint.translate(-childBounds.x, -childBounds.y);218child.repaintPeer(toPaint);219}220}221222Rectangle getContentSize() {223return getSize();224}225226@Override227public void setEnabled(final boolean e) {228super.setEnabled(e);229for (final LWComponentPeer<?, ?> child : getChildren()) {230child.setEnabled(e && child.getTarget().isEnabled());231}232}233234@Override235public void setBackground(final Color c) {236for (final LWComponentPeer<?, ?> child : getChildren()) {237if (!child.getTarget().isBackgroundSet()) {238child.setBackground(c);239}240}241super.setBackground(c);242}243244@Override245public void setForeground(final Color c) {246for (final LWComponentPeer<?, ?> child : getChildren()) {247if (!child.getTarget().isForegroundSet()) {248child.setForeground(c);249}250}251super.setForeground(c);252}253254@Override255public void setFont(final Font f) {256for (final LWComponentPeer<?, ?> child : getChildren()) {257if (!child.getTarget().isFontSet()) {258child.setFont(f);259}260}261super.setFont(f);262}263264@Override265public final void paint(final Graphics g) {266super.paint(g);267SunGraphicsCallback.PaintHeavyweightComponentsCallback.getInstance()268.runComponents(getTarget().getComponents(), g,269SunGraphicsCallback.LIGHTWEIGHTS270| SunGraphicsCallback.HEAVYWEIGHTS);271}272273@Override274public final void print(final Graphics g) {275super.print(g);276SunGraphicsCallback.PrintHeavyweightComponentsCallback.getInstance()277.runComponents(getTarget().getComponents(), g,278SunGraphicsCallback.LIGHTWEIGHTS279| SunGraphicsCallback.HEAVYWEIGHTS);280}281}282283284