--- old/src/macosx/classes/sun/lwawt/LWButtonPeer.java 2012-05-31 17:13:19.149300300 +0400 +++ new/src/macosx/classes/sun/lwawt/LWButtonPeer.java 2012-05-31 17:13:18.962100000 +0400 @@ -47,8 +47,8 @@ } @Override - public void initialize() { - super.initialize(); + void initializeImpl() { + super.initializeImpl(); setLabel(getTarget().getLabel()); synchronized (getDelegateLock()) { getDelegate().addActionListener(this); --- old/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java 2012-05-31 17:13:21.114903800 +0400 +++ new/src/macosx/classes/sun/lwawt/LWCheckboxPeer.java 2012-05-31 17:13:20.927703500 +0400 @@ -61,8 +61,8 @@ } @Override - public void initialize() { - super.initialize(); + void initializeImpl() { + super.initializeImpl(); setLabel(getTarget().getLabel()); setState(getTarget().getState()); setCheckboxGroup(getTarget().getCheckboxGroup()); --- old/src/macosx/classes/sun/lwawt/LWChoicePeer.java 2012-05-31 17:13:22.986907100 +0400 +++ new/src/macosx/classes/sun/lwawt/LWChoicePeer.java 2012-05-31 17:13:22.784106700 +0400 @@ -55,8 +55,8 @@ } @Override - public void initialize() { - super.initialize(); + void initializeImpl() { + super.initializeImpl(); final Choice choice = getTarget(); final JComboBox combo = getDelegate(); synchronized (getDelegateLock()) { --- old/src/macosx/classes/sun/lwawt/LWComponentPeer.java 2012-05-31 17:13:24.890110400 +0400 +++ new/src/macosx/classes/sun/lwawt/LWComponentPeer.java 2012-05-31 17:13:24.656110000 +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(); --- old/src/macosx/classes/sun/lwawt/LWLabelPeer.java 2012-05-31 17:13:26.980514100 +0400 +++ new/src/macosx/classes/sun/lwawt/LWLabelPeer.java 2012-05-31 17:13:26.730913600 +0400 @@ -56,8 +56,8 @@ } @Override - public void initialize() { - super.initialize(); + void initializeImpl() { + super.initializeImpl(); setText(getTarget().getText()); setAlignment(getTarget().getAlignment()); } --- old/src/macosx/classes/sun/lwawt/LWListPeer.java 2012-05-31 17:13:28.961717600 +0400 +++ new/src/macosx/classes/sun/lwawt/LWListPeer.java 2012-05-31 17:13:28.743317200 +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()) { --- old/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java 2012-05-31 17:13:30.833720800 +0400 +++ new/src/macosx/classes/sun/lwawt/LWScrollBarPeer.java 2012-05-31 17:13:30.615320500 +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()); --- old/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java 2012-05-31 17:13:32.799324300 +0400 +++ new/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java 2012-05-31 17:13:32.612124000 +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); --- old/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java 2012-05-31 17:13:35.061328300 +0400 +++ new/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java 2012-05-31 17:13:34.780527800 +0400 @@ -59,8 +59,8 @@ } @Override - public void initialize() { - super.initialize(); + void initializeImpl() { + super.initializeImpl(); final int visibility = getTarget().getScrollbarVisibility(); synchronized (getDelegateLock()) { setScrollBarVisibility(visibility); --- old/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java 2012-05-31 17:13:37.089331800 +0400 +++ new/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java 2012-05-31 17:13:36.870931500 +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); --- old/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java 2012-05-31 17:13:39.023735200 +0400 +++ new/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java 2012-05-31 17:13:38.805334900 +0400 @@ -54,8 +54,8 @@ } @Override - public void initialize() { - super.initialize(); + void initializeImpl() { + super.initializeImpl(); setEchoChar(getTarget().getEchoChar()); synchronized (getDelegateLock()) { getDelegate().addActionListener(this); --- old/src/macosx/classes/sun/lwawt/LWWindowPeer.java 2012-05-31 17:13:40.958138600 +0400 +++ new/src/macosx/classes/sun/lwawt/LWWindowPeer.java 2012-05-31 17:13:40.770938300 +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()); - setOpaque(getTarget().isOpaque()); + final float opacity = getTarget().getOpacity(); + if (opacity < 1.0f) { + setOpacity(opacity); + } - super.initialize(); + setOpaque(getTarget().isOpaque()); updateInsets(platformWindow.getInsets()); + if (getSurfaceData() == null) { + replaceSurfaceData(); + } } // Just a helper method @@ -213,25 +217,18 @@ } @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 - - // 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? + // In the super.setVisibleImpl() we post PaintEvent to EDT. + // Then we schedule this method on EDT too. So we'll have correct + // texture at the time when the window will appear on the screen and + // we'll simply make the blit in the native callback. + // invokeLater() can be deleted, but in this case we get a lag between + // windows showing and content painting. + // Note: don't forget to delete invokeLater from CPlatformWindow.dispose + // if this one will be deleted. + // TODO if EDT is blocked we cannot show the window. SwingUtilities.invokeLater(new Runnable() { @Override public void run() { @@ -982,8 +979,9 @@ Graphics g = backBuffer.getGraphics(); try { Rectangle r = getBounds(); - g.setColor(getBackground()); - g.fillRect(0, 0, r.width, r.height); + g.setColor(getForeground()); + ((Graphics2D) g).setBackground(getBackground()); + g.clearRect(0, 0, r.width, r.height); if (oldBB != null) { // Draw the old back buffer to the new one g.drawImage(oldBB, 0, 0, null); --- old/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2012-05-31 17:13:43.032942300 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2012-05-31 17:13:42.845741900 +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); @@ -243,17 +242,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() { --- old/src/macosx/native/sun/awt/AWTWindow.m 2012-05-31 17:13:45.092145900 +0400 +++ new/src/macosx/native/sun/awt/AWTWindow.m 2012-05-31 17:13:44.904945600 +0400 @@ -933,27 +933,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 */