7142091: [macosx] RFE: Refactoring of peer initialization/disposing
authorserb
Tue, 26 Jun 2012 13:46:09 +0400
changeset 13143 31c70a66a053
parent 13009 f409e6ef0185
child 13144 af0989bd5a41
7142091: [macosx] RFE: Refactoring of peer initialization/disposing Reviewed-by: anthony, art
jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java
jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java
jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java
jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java
jdk/src/macosx/classes/sun/lwawt/LWListPeer.java
jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java
jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java
jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java
jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java
jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/native/sun/awt/AWTWindow.m
--- a/jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWButtonPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -47,8 +47,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         setLabel(getTarget().getLabel());
         synchronized (getDelegateLock()) {
             getDelegate().addActionListener(this);
--- a/jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -61,8 +61,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         setLabel(getTarget().getLabel());
         setState(getTarget().getState());
         setCheckboxGroup(getTarget().getCheckboxGroup());
--- a/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWChoicePeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -55,8 +55,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         final Choice choice = getTarget();
         final JComboBox<String> combo = getDelegate();
         synchronized (getDelegateLock()) {
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -81,19 +81,10 @@
     // 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
-    private final static Object peerTreeLock =
+    private static final Object peerTreeLock =
             new StringBuilder("LWComponentPeer.peerTreeLock");
 
-    /**
-     * A custom tree-lock used for the hierarchy of the delegate Swing
-     * components.
-     * The lock synchronizes access to the delegate
-     * internal state. Think of it as a 'virtual EDT'.
-     */
-//    private final Object delegateTreeLock =
-//        new StringBuilder("LWComponentPeer.delegateTreeLock");
-
-    private T target;
+    private final T target;
 
     // Container peer. It may not be the peer of the target's direct
     // parent, for example, in the case of hw/lw mixing. However,
@@ -108,10 +99,10 @@
     // be updated when the component is reparented to another container
     private LWWindowPeer windowPeer;
 
-    private AtomicBoolean disposed = new AtomicBoolean(false);
+    private final AtomicBoolean disposed = new AtomicBoolean(false);
 
     // Bounds are relative to parent peer
-    private Rectangle bounds = new Rectangle();
+    private final Rectangle bounds = new Rectangle();
     private Region region;
 
     // Component state. Should be accessed under the state lock
@@ -122,9 +113,11 @@
     private Color foreground;
     private Font font;
 
-    // Paint area to coalesce all the paint events and store
-    // the target dirty area
-    private RepaintArea targetPaintArea;
+    /**
+     * Paint area to coalesce all the paint events and store the target dirty
+     * area.
+     */
+    private final RepaintArea targetPaintArea;
 
     //   private volatile boolean paintPending;
     private volatile boolean isLayouting;
@@ -137,7 +130,7 @@
     private int fNumDropTargets = 0;
     private CDropTarget fDropTarget = null;
 
-    private PlatformComponent platformComponent;
+    private final PlatformComponent platformComponent;
 
     private final class DelegateContainer extends Container {
         {
@@ -175,6 +168,7 @@
     }
 
     public LWComponentPeer(T target, PlatformComponent platformComponent) {
+        targetPaintArea = new LWRepaintArea();
         this.target = target;
         this.platformComponent = platformComponent;
 
@@ -201,10 +195,13 @@
                 synchronized (getDelegateLock()) {
                     delegate = createDelegate();
                     if (delegate != null) {
+                        delegate.setVisible(false);
                         delegateContainer = new DelegateContainer();
                         delegateContainer.add(delegate);
                         delegateContainer.addNotify();
                         delegate.addNotify();
+                        resetColorsAndFont(delegate);
+                        delegate.setOpaque(true);
                     } else {
                         return;
                     }
@@ -278,27 +275,28 @@
         return getDelegate();
     }
 
-    /*
-     * Initializes this peer by fetching all the properties from the target.
-     * 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.
+    /**
+     * 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 void initialize() {
+    public final void initialize() {
         platformComponent.initialize(target, this, getPlatformWindow());
-        targetPaintArea = new LWRepaintArea();
-        if (getDelegate() != null) {
-            synchronized (getDelegateLock()) {
-                resetColorsAndFont(delegate);
-                getDelegate().setOpaque(true);
-            }
-        }
+        initializeImpl();
+        setVisible(target.isVisible());
+    }
+
+    /**
+     * Fetching general properties from the target. Should be overridden in
+     * subclasses to initialize specific peers properties.
+     */
+    void initializeImpl() {
         setBackground(target.getBackground());
         setForeground(target.getForeground());
         setFont(target.getFont());
         setBounds(target.getBounds());
         setEnabled(target.isEnabled());
-        setVisible(target.isVisible());
     }
 
     private static void resetColorsAndFont(final Container c) {
@@ -314,15 +312,18 @@
         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
+    /**
+     * 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
+     */
     final Object getDelegateLock() {
-        //return delegateTreeLock;
         return getTarget().getTreeLock();
     }
 
-    protected final static Object getPeerTreeLock() {
+    protected static final Object getPeerTreeLock() {
         return peerTreeLock;
     }
 
@@ -758,14 +759,17 @@
     }
 
     @Override
-    public void setVisible(boolean v) {
+    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();
 
         if (delegate != null) {
@@ -1355,7 +1359,7 @@
      *
      * @see #isVisible()
      */
-    protected boolean isShowing() {
+    protected final boolean isShowing() {
         synchronized (getPeerTreeLock()) {
             if (isVisible()) {
                 final LWContainerPeer container = getContainerPeer();
--- a/jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWLabelPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -60,8 +60,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         setText(getTarget().getText());
         setAlignment(getTarget().getAlignment());
     }
--- a/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWListPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -49,8 +49,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         setMultipleMode(getTarget().isMultipleMode());
         final int[] selectedIndices = getTarget().getSelectedIndexes();
         synchronized (getDelegateLock()) {
--- a/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -54,8 +54,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         final Scrollbar target = getTarget();
         setValues(target.getValue(), target.getVisibleAmount(),
                   target.getMinimum(), target.getMaximum());
--- a/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -70,8 +70,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         final int policy = getTarget().getScrollbarDisplayPolicy();
         synchronized (getDelegateLock()) {
             getDelegate().getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -59,8 +59,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         final int visibility = getTarget().getScrollbarVisibility();
         synchronized (getDelegateLock()) {
             setScrollBarVisibility(visibility);
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -63,8 +63,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         synchronized (getDelegateLock()) {
             // This listener should be added before setText().
             getTextComponent().getDocument().addDocumentListener(this);
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -58,8 +58,8 @@
     }
 
     @Override
-    public void initialize() {
-        super.initialize();
+    void initializeImpl() {
+        super.initializeImpl();
         setEchoChar(getTarget().getEchoChar());
         synchronized (getDelegateLock()) {
             getDelegate().addActionListener(this);
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Tue Jun 26 13:46:09 2012 +0400
@@ -145,8 +145,6 @@
             // similar to what Apple's Java do.
             // Since JDK7 we should rely on setOpacity() only.
             // this.opacity = c.getAlpha();
-            // System.out.println("Delegate assigns alpha (we ignore setOpacity()):"
-            // +this.opacity);
         }
 
         if (!target.isForegroundSet()) {
@@ -159,23 +157,29 @@
     }
 
     @Override
-    public void initialize() {
+    void initializeImpl() {
+        super.initializeImpl();
         if (getTarget() instanceof Frame) {
-            setTitle(((Frame)getTarget()).getTitle());
-            setState(((Frame)getTarget()).getExtendedState());
+            setTitle(((Frame) getTarget()).getTitle());
+            setState(((Frame) getTarget()).getExtendedState());
         } else if (getTarget() instanceof Dialog) {
-            setTitle(((Dialog)getTarget()).getTitle());
+            setTitle(((Dialog) getTarget()).getTitle());
         }
 
         setAlwaysOnTop(getTarget().isAlwaysOnTop());
         updateMinimumSize();
 
-        setOpacity(getTarget().getOpacity());
+        final float opacity = getTarget().getOpacity();
+        if (opacity < 1.0f) {
+            setOpacity(opacity);
+        }
+
         setOpaque(getTarget().isOpaque());
 
-        super.initialize();
-
         updateInsets(platformWindow.getInsets());
+        if (getSurfaceData() == null) {
+            replaceSurfaceData();
+        }
     }
 
     // Just a helper method
@@ -213,50 +217,29 @@
     }
 
     @Override
-    public void setVisible(final boolean visible) {
-        if (getSurfaceData() == null) {
-            replaceSurfaceData();
-        }
-
-        if (isVisible() == visible) {
-            return;
-        }
-        super.setVisible(visible);
-
+    protected void setVisibleImpl(final boolean visible) {
+        super.setVisibleImpl(visible);
         // TODO: update graphicsConfig, see 4868278
-        // TODO: don't notify the delegate if our visibility is unchanged
+        platformWindow.setVisible(visible);
+        if (isSimpleWindow()) {
+            LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
+                getInstance(getAppContext());
 
-        // it is important to call this method on EDT
-        // to prevent the deadlocks during the painting of the lightweight delegates
-        //TODO: WHY? This is a native-system related call. Perhaps NOT calling
-        // the painting procedure right from the setVisible(), but rather relying
-        // on the native Expose event (or, scheduling the repainting asynchronously)
-        // is better?
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                platformWindow.setVisible(visible);
-                if (isSimpleWindow()) {
-                    LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
-                        getInstance(getAppContext());
-
-                    if (visible) {
-                        if (!getTarget().isAutoRequestFocus()) {
-                            return;
-                        } else {
-                            requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
-                        }
-                    // Focus the owner in case this window is focused.
-                    } else if (manager.getCurrentFocusedWindow() == getTarget()) {
-                        // Transfer focus to the owner.
-                        LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
-                        if (owner != null) {
-                            owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
-                        }
-                    }
+            if (visible) {
+                if (!getTarget().isAutoRequestFocus()) {
+                    return;
+                } else {
+                    requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
+                }
+            // Focus the owner in case this window is focused.
+            } else if (manager.getCurrentFocusedWindow() == getTarget()) {
+                // Transfer focus to the owner.
+                LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
+                if (owner != null) {
+                    owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
                 }
             }
-        });
+        }
     }
 
     @Override
@@ -983,6 +966,9 @@
                 try {
                     Rectangle r = getBounds();
                     g.setColor(getBackground());
+                    if (g instanceof Graphics2D) {
+                        ((Graphics2D) g).setComposite(AlphaComposite.Src);
+                    }
                     g.fillRect(0, 0, r.width, r.height);
                     if (oldBB != null) {
                         // Draw the old back buffer to the new one
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Jun 26 13:46:09 2012 +0400
@@ -56,7 +56,6 @@
     private static native void nativePushNSWindowToBack(long nsWindowPtr);
     private static native void nativePushNSWindowToFront(long nsWindowPtr);
     private static native void nativeSetNSWindowTitle(long nsWindowPtr, String title);
-    private static native void nativeSetNSWindowAlpha(long nsWindowPtr, float alpha);
     private static native void nativeRevalidateNSWindowShadow(long nsWindowPtr);
     private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
     private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
@@ -244,17 +243,6 @@
         // TODO: implement on top of JObjC bridged class
     //    NSWindow window = JObjC.getInstance().AppKit().NSWindow().getInstance(nativeWindowPtr, JObjCRuntime.getInstance());
 
-        // Since JDK7 we have standard way to set opacity, so we should not pick
-        // background's alpha.
-        // TODO: set appropriate opacity value
-        //        this.opacity = target.getOpacity();
-        //        this.setOpacity(this.opacity);
-
-        final float windowAlpha = target.getOpacity();
-        if (windowAlpha != 1.0f) {
-            nativeSetNSWindowAlpha(nativeWindowPtr, windowAlpha);
-        }
-
         if (target instanceof javax.swing.RootPaneContainer) {
             final javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane();
             if (rootpane != null) rootpane.addPropertyChangeListener("ancestor", new PropertyChangeListener() {
@@ -419,15 +407,9 @@
         if (owner != null) {
             CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr());
         }
-        // Make sure window is ordered out before it is disposed, we could order it out right here or
-        // we could postpone the disposal, I think postponing is probably better.
-        EventQueue.invokeLater(new Runnable() {
-            public void run() {
-                contentView.dispose();
-                nativeDispose(getNSWindowPtr());
-                CPlatformWindow.super.dispose();
-            }
-        });
+        contentView.dispose();
+        nativeDispose(getNSWindowPtr());
+        CPlatformWindow.super.dispose();
     }
 
     @Override // PlatformWindow
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m	Mon Jun 25 17:27:04 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m	Tue Jun 26 13:46:09 2012 +0400
@@ -934,27 +934,6 @@
 
 /*
  * Class:     sun_lwawt_macosx_CPlatformWindow
- * Method:    nativeSetNSWindowAlpha
- * Signature: (JF)V
- */
-JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowAlpha
-(JNIEnv *env, jclass clazz, jlong windowPtr, jfloat alpha)
-{
-JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
-
-    NSWindow *nsWindow = OBJC(windowPtr);
-    [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
-        AWT_ASSERT_APPKIT_THREAD;
-
-        [nsWindow setAlphaValue:alpha];
-    }];
-
-JNF_COCOA_EXIT(env);
-}
-
-/*
- * Class:     sun_lwawt_macosx_CPlatformWindow
  * Method:    nativeRevalidateNSWindowShadow
  * Signature: (J)V
  */