/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
implements ComponentPeer, DropTargetPeer
{
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWComponentPeer");
// State lock is to be used for modifications to this
// peer's fields (e.g. bounds, background, font, etc.)
// It should be the last lock in the lock chain
new StringBuilder("LWComponentPeer.stateLock");
// The lock to operate with the peers hierarchy. AWT tree
// lock is not used as there are many peers related ops
// to be done on the toolkit thread, and we don't want to
// depend on a public lock on this thread
new StringBuilder("LWComponentPeer.peerTreeLock");
private final T target;
// Container peer. It may not be the peer of the target's direct
// let's skip this scenario for the time being. We also assume
// the container peer is not null, which might also be false if
// addNotify() is called for a component outside of the hierarchy.
// The exception is LWWindowPeers: their parents are always null
// Handy reference to the top-level window peer. Window peer is
// borrowed from the containerPeer in constructor, and should also
// be updated when the component is reparented to another container
// Bounds are relative to parent peer
// Component state. Should be accessed under the state lock
private boolean visible = false;
private boolean enabled = true;
/**
* Paint area to coalesce all the paint events and store the target dirty
* area.
*/
// private volatile boolean paintPending;
private volatile boolean isLayouting;
{
enableEvents(0xFFFFFFFF);
}
super();
}
public boolean isLightweight() {
return false;
}
return getLocationOnScreen();
}
return LWComponentPeer.this.getLocationOnScreen();
}
public int getX() {
return getLocation().x;
}
public int getY() {
return getLocation().y;
}
}
targetPaintArea = new LWRepaintArea();
this.platformComponent = platformComponent;
// Container peer is always null for LWWindowPeers, so
// windowPeer is always null for them as well. On the other
// hand, LWWindowPeer shouldn't use windowPeer at all
if (containerPeer != null) {
}
// don't bother about z-order here as updateZOrder()
// will be called from addNotify() later anyway
if (containerPeer != null) {
containerPeer.addChildPeer(this);
}
// the delegate must be created after the target is set
synchronized (Toolkit.getDefaultToolkit()) {
try {
synchronized (getDelegateLock()) {
delegate = createDelegate();
delegate.setVisible(false);
delegateContainer = new DelegateContainer();
} else {
return;
}
}
} finally {
}
// todo swing: later on we will probably have one global RM
public void addDirtyRegion(final JComponent c, final int x, final int y, final int w, final int h) {
c, new Rectangle(x, y, w, h), getDelegate()));
}
});
}
}
/**
* This method must be called under Toolkit.getDefaultToolkit() lock
* and followed by setToolkitAWTEventListener()
*/
public AWTEventListener run() {
try {
field.setAccessible(true);
} catch (Exception e) {
throw new InternalError(e.toString());
}
}
});
}
try {
field.setAccessible(true);
} catch (Exception e) {
throw new InternalError(e.toString());
}
return null;
}
});
}
/**
* This method is called under getDelegateLock().
* Overridden in subclasses.
*/
protected D createDelegate() {
return null;
}
protected final D getDelegate() {
synchronized (getStateLock()) {
return delegate;
}
}
return getDelegate();
}
/**
* Initializes this peer. The call to initialize() is not placed to
* LWComponentPeer ctor to let the subclass ctor to finish completely first.
* Instead, it's the LWToolkit object who is responsible for initialization.
* Note that we call setVisible() at the end of initialization.
*/
public final void initialize() {
}
/**
* Fetching general properties from the target. Should be overridden in
* subclasses to initialize specific peers properties.
*/
void initializeImpl() {
}
c.setBackground(null);
c.setForeground(null);
for (int i = 0; i < c.getComponentCount(); i++) {
}
}
return stateLock;
}
/**
* Synchronize all operations with the Swing delegates under AWT tree lock,
* using a new separate lock to synchronize access to delegates may lead
* deadlocks. Think of it as a 'virtual EDT'.
*
* @return DelegateLock
*/
return getTarget().getTreeLock();
}
return peerTreeLock;
}
final T getTarget() {
return target;
}
// Just a helper method
// Returns the window peer or null if this is a window peer
return windowPeer;
}
// Returns the window peer or 'this' if this is a window peer
return getWindowPeer();
}
// Just a helper method
return containerPeer;
}
// Just a helper method
// Overridden in LWWindowPeer to skip containerPeer initialization
protected void initializeContainerPeer() {
}
}
return windowPeer.getPlatformWindow();
}
}
// ---- PEER METHODS ---- //
return LWToolkit.getLWToolkit();
}
// Just a helper method
return LWToolkit.getLWToolkit();
}
public final void dispose() {
if (disposed.compareAndSet(false, true)) {
disposeImpl();
}
}
protected void disposeImpl() {
cp.removeChildPeer(this);
}
}
public final boolean isDisposed() {
}
/*
* GraphicsConfiguration is borrowed from the parent peer. The
* return value must not be null.
*
* Overridden in LWWindowPeer.
*/
// Don't check windowPeer for null as it can only happen
// for windows, but this method is overridden in
// LWWindowPeer and doesn't call super()
return getWindowPeer().getGraphicsConfiguration();
}
/*
* Overridden in LWWindowPeer to replace its surface
* data and back buffer.
*/
// TODO: not implemented
// throw new RuntimeException("Has not been implemented yet.");
return false;
}
final Graphics g = getOnscreenGraphics();
if (g != null) {
synchronized (getPeerTreeLock()){
applyConstrain(g);
}
}
return g;
}
/*
* Peer Graphics is borrowed from the parent peer, while
* foreground and background colors and font are specific to
* this peer.
*/
getFont());
}
}
return computeVisibleRect(this, getRegion());
}
final LWContainerPeer p = c.getContainerPeer();
if (p != null) {
}
return region;
}
// Is it a correct implementation?
return getGraphicsConfiguration().getColorModel();
}
throws AWTException {
throw new AWTException("Back buffers are only supported for " +
"Window or Canvas components.");
}
/*
* To be overridden in LWWindowPeer and LWCanvasPeer.
*/
// Return null or throw AWTException?
return null;
}
// Skip silently or throw AWTException?
}
public void destroyBuffers() {
// Do nothing
}
// Helper method
}
/**
* This method could be called on the toolkit thread.
*/
}
final boolean updateTarget) {
synchronized (getStateLock()) {
bounds.x = x;
bounds.y = y;
}
}
}
return;
}
final D delegate = getDelegate();
synchronized (getDelegateLock()) {
// TODO: the following means that the delegateContainer NEVER gets validated. That's WRONG!
}
}
h);
if (notify) {
if (resized) {
handleResize(w, h, updateTarget);
}
if (moved) {
handleMove(x, y, updateTarget);
}
}
}
synchronized (getStateLock()) {
// Return a copy to prevent subsequent modifications
}
}
synchronized (getStateLock()) {
// Return a copy to prevent subsequent modifications
}
}
windowLocation.y + locationInWindow.y);
}
/**
* Returns the cursor of the peer, which is cursor of the target by default,
* but peer can override this behavior.
*
* @param p Point relative to the peer.
* @return Cursor of the peer or null if default cursor should be used.
*/
}
return;
}
synchronized (getStateLock()) {
background = c;
}
final D delegate = getDelegate();
synchronized (getDelegateLock()) {
// delegate will repaint the target
}
} else {
repaintPeer();
}
}
synchronized (getStateLock()) {
return background;
}
}
return;
}
synchronized (getStateLock()) {
foreground = c;
}
final D delegate = getDelegate();
synchronized (getDelegateLock()) {
// delegate will repaint the target
}
} else {
repaintPeer();
}
}
synchronized (getStateLock()) {
return foreground;
}
}
return;
}
synchronized (getStateLock()) {
font = f;
}
final D delegate = getDelegate();
synchronized (getDelegateLock()) {
// delegate will repaint the target
}
} else {
repaintPeer();
}
}
synchronized (getStateLock()) {
return font;
}
}
// Borrow the metrics from the top-level window
// return getWindowPeer().getFontMetrics(f);
// Obtain the metrics from the offscreen window where this peer is
// mostly drawn to.
// TODO: check for "use platform metrics" settings
try {
if (g != null) {
return g.getFontMetrics(f);
} else {
synchronized (getDelegateLock()) {
return delegateContainer.getFontMetrics(f);
}
}
} finally {
if (g != null) {
g.dispose();
}
}
}
public void setEnabled(final boolean e) {
boolean status = e;
}
synchronized (getStateLock()) {
return;
}
}
final D delegate = getDelegate();
synchronized (getDelegateLock()) {
}
} else {
repaintPeer();
}
}
// Helper method
public final boolean isEnabled() {
synchronized (getStateLock()) {
return enabled;
}
}
public void setVisible(final boolean v) {
synchronized (getStateLock()) {
if (visible == v) {
return;
}
visible = v;
}
setVisibleImpl(v);
}
protected void setVisibleImpl(final boolean v) {
final D delegate = getDelegate();
synchronized (getDelegateLock()) {
delegate.setVisible(v);
}
}
if (visible) {
repaintPeer();
} else {
}
}
// Helper method
public final boolean isVisible() {
synchronized (getStateLock()) {
return visible;
}
}
}
}
// TODO: not implemented
throw new UnsupportedOperationException("ComponentPeer.reparent()");
}
public boolean isReparentSupported() {
// TODO: not implemented
return false;
}
// Don't check containerPeer for null as it can only happen
// for windows, but this method is overridden in
// LWWindowPeer and doesn't call super()
}
if (!(e instanceof IgnorePaintEvent)) {
Rectangle r = e.getUpdateRect();
}
}
}
/*
* Should be overridden in subclasses which use complex Swing components.
*/
public void layout() {
// TODO: not implemented
}
public boolean isObscured() {
// TODO: not implemented
return false;
}
public boolean canDetermineObscurity() {
// TODO: not implemented
return false;
}
/**
* Should be overridden in subclasses to forward the request
* to the Swing helper component, if required.
*/
// It looks like a default implementation for all toolkits
return getMinimumSize();
}
/*
* Should be overridden in subclasses to forward the request
* to the Swing helper component.
*/
D delegate = getDelegate();
// Is it a correct default value?
} else {
synchronized (getDelegateLock()) {
return delegate.getMinimumSize();
}
}
}
public void updateCursorImmediately() {
}
public boolean isFocusable() {
// Overridden in focusable subclasses like buttons
return false;
}
boolean focusedWindowChangeAllowed, long time,
{
", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
}
return true;
}
switch (result) {
return false;
if (parentWindow == null) {
return false;
}
if (parentPeer == null) {
return false;
}
// A fix for 7145768. Ensure the parent window is currently natively focused.
// The more evident place to perform this check is in KFM.shouldNativelyFocusHeavyweight,
// however that is the shared code and this particular problem's reproducibility has
// platform specifics. So, it was decided to narrow down the fix to lwawt (OSX) in
// current release. TODO: consider fixing it in the shared code.
if (!focusedWindowChangeAllowed) {
"decoratedPeer is inactive: " + decoratedPeer);
}
return false;
}
}
// If parent window can be made focused and has been made focused (synchronously)
// then we can proceed with children, otherwise we retreat
}
return false;
}
return true;
}
return false;
}
return new ToolkitImage(producer);
}
}
return new SunVolatileImage(getTarget(), w, h);
}
}
}
public boolean handlesWheelScrolling() {
// TODO: not implemented
return false;
}
synchronized (getStateLock()) {
return;
}
}
}
synchronized (getStateLock()) {
} else {
}
}
}
synchronized (getStateLock()) {
}
}
public boolean isShaped() {
synchronized (getStateLock()) {
}
}
// DropTargetPeer Method
// We need to register the DropTarget in the
// peer of the window ancestor of the component
} else {
synchronized (dropTargetLock) {
// 10-14-02 VL: Windows WComponentPeer would add (or remove) the drop target only
// if it's the first (or last) one for the component. Otherwise this call is a no-op.
if (++fNumDropTargets == 1) {
// Having a non-null drop target would be an error but let's check just in case:
if (fDropTarget != null)
// Create a new drop target:
}
}
}
}
// DropTargetPeer Method
// We need to unregister the DropTarget in the
// peer of the window ancestor of the component
} else {
synchronized (dropTargetLock){
// 10-14-02 VL: Windows WComponentPeer would add (or remove) the drop target only
// if it's the first (or last) one for the component. Otherwise this call is a no-op.
if (--fNumDropTargets == 0) {
// Having a null drop target would be an error but let's check just in case:
if (fDropTarget != null) {
// Dispose of the drop target:
fDropTarget = null;
} else
}
}
}
}
// ---- PEER NOTIFICATIONS ---- //
/**
* Called when this peer's location has been changed either as a result
* of target.setLocation() or as a result of user actions (window is
* dragged with mouse).
*
* To be overridden in LWWindowPeer to update its GraphicsConfig.
*
* This method could be called on the toolkit thread.
*/
protected final void handleMove(final int x, final int y,
final boolean updateTarget) {
if (updateTarget) {
}
}
/**
* Called when this peer's size has been changed either as a result of
* target.setSize() or as a result of user actions (window is resized).
*
* To be overridden in LWWindowPeer to update its SurfaceData and
* GraphicsConfig.
*
* This method could be called on the toolkit thread.
*/
protected final void handleResize(final int w, final int h,
final boolean updateTarget) {
if (updateTarget) {
}
}
repaintPeer(getSize());
}
// Repaint unobscured part of the parent
}
}
// ---- EVENTS ---- //
/**
* Post an event to the proper Java EDT.
*/
}
protected void postPaintEvent(int x, int y, int w, int h) {
// TODO: call getIgnoreRepaint() directly with the right ACC
return;
}
createPaintEvent(getTarget(), x, y, w, h);
}
}
/*
* Gives a chance for the peer to handle the event after it's been
* processed by the target.
*/
return;
}
switch (e.getID()) {
case FocusEvent.FOCUS_GAINED:
case FocusEvent.FOCUS_LOST:
break;
case PaintEvent.PAINT:
// Got a native paint event
// paintPending = false;
// fall through to the next statement
case PaintEvent.UPDATE:
break;
case MouseEvent.MOUSE_PRESSED:
}
}
return;
}
synchronized (getDelegateLock()) {
if (delegateEvent != null) {
if (delegateEvent instanceof KeyEvent) {
}
}
}
}
/**
* Changes the target of the AWTEvent from awt component to appropriate
* swing delegate.
*/
// TODO modifiers should be changed to getModifiers()|getModifiersEx()?
if (e instanceof MouseWheelEvent) {
delegateEvent = new MouseWheelEvent(
me.getModifiers(),
me.getClickCount(),
me.isPopupTrigger(),
me.getScrollType(),
me.getWheelRotation());
} else if (e instanceof MouseEvent) {
if (delegateDropTarget == null) {
} else {
}
}
}
if (eventTarget == null) {
}
} else if (e instanceof KeyEvent) {
} else if (e instanceof FocusEvent) {
}
return delegateEvent;
}
} else {
// Anyway request focus to the toplevel.
}
}
/**
* Handler for FocusEvents.
*/
// Note that the peer receives all the FocusEvents from
// its lightweight children as well
}
/**
* All peers should clear background before paint.
*
* @return false on components that DO NOT require a clearRect() before
* painting.
*/
protected final boolean shouldClearRectBeforePaint() {
// TODO: sun.awt.noerasebackground
return true;
}
/**
* Handler for PAINT and UPDATE PaintEvents.
*/
private void handleJavaPaintEvent() {
// Skip all painting while layouting and all UPDATEs
// while waiting for native paint
// if (!isLayouting && !paintPending) {
if (!isLayouting()) {
}
}
// ---- UTILITY METHODS ---- //
/**
* Finds a top-most visible component for the given point. The location is
* specified relative to the peer's parent.
*/
}
/*
* Translated the given point in Window coordinates to the point in
* coordinates local to this component. The given window peer must be
* the window where this component is in.
*/
}
LWComponentPeer cp = this;
p.x -= cpb.x;
p.y -= cpb.y;
}
// Return a copy to prevent subsequent modifications
return new Point(p);
}
}
return localToWindow(new Point(x, y));
}
p.x += r.x;
p.y += r.y;
}
// Return a copy to prevent subsequent modifications
return new Point(p);
}
}
public final void repaintPeer() {
repaintPeer(getSize());
}
return;
}
}
/**
* Determines whether this peer is showing on screen. This means that the
* peer must be visible, and it must be in a container that is visible and
* showing.
*
* @see #isVisible()
*/
protected final boolean isShowing() {
synchronized (getPeerTreeLock()) {
if (isVisible()) {
}
}
return false;
}
/**
* Paints the peer. Overridden in subclasses to delegate the actual painting
* to Swing components.
*/
final D delegate = getDelegate();
if (!SwingUtilities.isEventDispatchThread()) {
throw new InternalError("Painting must be done on EDT");
}
synchronized (getDelegateLock()) {
// JComponent.print() is guaranteed to not affect the double buffer
getDelegate().print(g);
}
}
}
protected static final void flushOnscreenGraphics(){
try {
} finally {
}
}
/**
* Used by ContainerPeer to skip all the paint events during layout.
*
* @param isLayouting layouting state.
*/
this.isLayouting = isLayouting;
}
/**
* Returns layouting state. Used by ComponentPeer to skip all the paint
* events during layout.
*
* @return true during layout, false otherwise.
*/
private final boolean isLayouting() {
return isLayouting;
}
}