提交 08e2dd6f 编写于 作者: S serb

7142091: [macosx] RFE: Refactoring of peer initialization/disposing

Reviewed-by: anthony, art
上级 c08437a7
...@@ -47,8 +47,8 @@ final class LWButtonPeer extends LWComponentPeer<Button, JButton> ...@@ -47,8 +47,8 @@ final class LWButtonPeer extends LWComponentPeer<Button, JButton>
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
setLabel(getTarget().getLabel()); setLabel(getTarget().getLabel());
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
getDelegate().addActionListener(this); getDelegate().addActionListener(this);
......
...@@ -61,8 +61,8 @@ final class LWCheckboxPeer ...@@ -61,8 +61,8 @@ final class LWCheckboxPeer
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
setLabel(getTarget().getLabel()); setLabel(getTarget().getLabel());
setState(getTarget().getState()); setState(getTarget().getState());
setCheckboxGroup(getTarget().getCheckboxGroup()); setCheckboxGroup(getTarget().getCheckboxGroup());
......
...@@ -55,8 +55,8 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>> ...@@ -55,8 +55,8 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
final Choice choice = getTarget(); final Choice choice = getTarget();
final JComboBox<String> combo = getDelegate(); final JComboBox<String> combo = getDelegate();
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
......
...@@ -81,19 +81,10 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -81,19 +81,10 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
// lock is not used as there are many peers related ops // lock is not used as there are many peers related ops
// to be done on the toolkit thread, and we don't want to // to be done on the toolkit thread, and we don't want to
// depend on a public lock on this thread // depend on a public lock on this thread
private final static Object peerTreeLock = private static final Object peerTreeLock =
new StringBuilder("LWComponentPeer.peerTreeLock"); new StringBuilder("LWComponentPeer.peerTreeLock");
/** private final T target;
* 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;
// Container peer. It may not be the peer of the target's direct // Container peer. It may not be the peer of the target's direct
// parent, for example, in the case of hw/lw mixing. However, // parent, for example, in the case of hw/lw mixing. However,
...@@ -108,10 +99,10 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -108,10 +99,10 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
// be updated when the component is reparented to another container // be updated when the component is reparented to another container
private LWWindowPeer windowPeer; private LWWindowPeer windowPeer;
private AtomicBoolean disposed = new AtomicBoolean(false); private final AtomicBoolean disposed = new AtomicBoolean(false);
// Bounds are relative to parent peer // Bounds are relative to parent peer
private Rectangle bounds = new Rectangle(); private final Rectangle bounds = new Rectangle();
private Region region; private Region region;
// Component state. Should be accessed under the state lock // Component state. Should be accessed under the state lock
...@@ -122,9 +113,11 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -122,9 +113,11 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
private Color foreground; private Color foreground;
private Font font; private Font font;
// Paint area to coalesce all the paint events and store /**
// the target dirty area * Paint area to coalesce all the paint events and store the target dirty
private RepaintArea targetPaintArea; * area.
*/
private final RepaintArea targetPaintArea;
// private volatile boolean paintPending; // private volatile boolean paintPending;
private volatile boolean isLayouting; private volatile boolean isLayouting;
...@@ -137,7 +130,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -137,7 +130,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
private int fNumDropTargets = 0; private int fNumDropTargets = 0;
private CDropTarget fDropTarget = null; private CDropTarget fDropTarget = null;
private PlatformComponent platformComponent; private final PlatformComponent platformComponent;
private final class DelegateContainer extends Container { private final class DelegateContainer extends Container {
{ {
...@@ -175,6 +168,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -175,6 +168,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
public LWComponentPeer(T target, PlatformComponent platformComponent) { public LWComponentPeer(T target, PlatformComponent platformComponent) {
targetPaintArea = new LWRepaintArea();
this.target = target; this.target = target;
this.platformComponent = platformComponent; this.platformComponent = platformComponent;
...@@ -201,10 +195,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -201,10 +195,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
delegate = createDelegate(); delegate = createDelegate();
if (delegate != null) { if (delegate != null) {
delegate.setVisible(false);
delegateContainer = new DelegateContainer(); delegateContainer = new DelegateContainer();
delegateContainer.add(delegate); delegateContainer.add(delegate);
delegateContainer.addNotify(); delegateContainer.addNotify();
delegate.addNotify(); delegate.addNotify();
resetColorsAndFont(delegate);
delegate.setOpaque(true);
} else { } else {
return; return;
} }
...@@ -278,27 +275,28 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -278,27 +275,28 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return getDelegate(); return getDelegate();
} }
/* /**
* Initializes this peer by fetching all the properties from the target. * Initializes this peer. The call to initialize() is not placed to
* The call to initialize() is not placed to LWComponentPeer ctor to * LWComponentPeer ctor to let the subclass ctor to finish completely first.
* let the subclass ctor to finish completely first. Instead, it's the * Instead, it's the LWToolkit object who is responsible for initialization.
* 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()); platformComponent.initialize(target, this, getPlatformWindow());
targetPaintArea = new LWRepaintArea(); initializeImpl();
if (getDelegate() != null) { setVisible(target.isVisible());
synchronized (getDelegateLock()) {
resetColorsAndFont(delegate);
getDelegate().setOpaque(true);
}
} }
/**
* Fetching general properties from the target. Should be overridden in
* subclasses to initialize specific peers properties.
*/
void initializeImpl() {
setBackground(target.getBackground()); setBackground(target.getBackground());
setForeground(target.getForeground()); setForeground(target.getForeground());
setFont(target.getFont()); setFont(target.getFont());
setBounds(target.getBounds()); setBounds(target.getBounds());
setEnabled(target.isEnabled()); setEnabled(target.isEnabled());
setVisible(target.isVisible());
} }
private static void resetColorsAndFont(final Container c) { private static void resetColorsAndFont(final Container c) {
...@@ -314,15 +312,18 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -314,15 +312,18 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return stateLock; return stateLock;
} }
// Synchronize all operations with the Swing delegates under /**
// AWT tree lock, using a new separate lock to synchronize * Synchronize all operations with the Swing delegates under AWT tree lock,
// access to delegates may lead deadlocks * 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() { final Object getDelegateLock() {
//return delegateTreeLock;
return getTarget().getTreeLock(); return getTarget().getTreeLock();
} }
protected final static Object getPeerTreeLock() { protected static final Object getPeerTreeLock() {
return peerTreeLock; return peerTreeLock;
} }
...@@ -758,14 +759,17 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -758,14 +759,17 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
@Override @Override
public void setVisible(boolean v) { public void setVisible(final boolean v) {
synchronized (getStateLock()) { synchronized (getStateLock()) {
if (visible == v) { if (visible == v) {
return; return;
} }
visible = v; visible = v;
} }
setVisibleImpl(v);
}
protected void setVisibleImpl(final boolean v) {
final D delegate = getDelegate(); final D delegate = getDelegate();
if (delegate != null) { if (delegate != null) {
...@@ -1355,7 +1359,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -1355,7 +1359,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
* *
* @see #isVisible() * @see #isVisible()
*/ */
protected boolean isShowing() { protected final boolean isShowing() {
synchronized (getPeerTreeLock()) { synchronized (getPeerTreeLock()) {
if (isVisible()) { if (isVisible()) {
final LWContainerPeer container = getContainerPeer(); final LWContainerPeer container = getContainerPeer();
......
...@@ -60,8 +60,8 @@ final class LWLabelPeer extends LWComponentPeer<Label, JLabel> ...@@ -60,8 +60,8 @@ final class LWLabelPeer extends LWComponentPeer<Label, JLabel>
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
setText(getTarget().getText()); setText(getTarget().getText());
setAlignment(getTarget().getAlignment()); setAlignment(getTarget().getAlignment());
} }
......
...@@ -49,8 +49,8 @@ final class LWListPeer ...@@ -49,8 +49,8 @@ final class LWListPeer
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
setMultipleMode(getTarget().isMultipleMode()); setMultipleMode(getTarget().isMultipleMode());
final int[] selectedIndices = getTarget().getSelectedIndexes(); final int[] selectedIndices = getTarget().getSelectedIndexes();
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
......
...@@ -54,8 +54,8 @@ final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar> ...@@ -54,8 +54,8 @@ final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar>
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
final Scrollbar target = getTarget(); final Scrollbar target = getTarget();
setValues(target.getValue(), target.getVisibleAmount(), setValues(target.getValue(), target.getVisibleAmount(),
target.getMinimum(), target.getMaximum()); target.getMinimum(), target.getMaximum());
......
...@@ -70,8 +70,8 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane> ...@@ -70,8 +70,8 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
final int policy = getTarget().getScrollbarDisplayPolicy(); final int policy = getTarget().getScrollbarDisplayPolicy();
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
getDelegate().getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); getDelegate().getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
......
...@@ -59,8 +59,8 @@ final class LWTextAreaPeer ...@@ -59,8 +59,8 @@ final class LWTextAreaPeer
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
final int visibility = getTarget().getScrollbarVisibility(); final int visibility = getTarget().getScrollbarVisibility();
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
setScrollBarVisibility(visibility); setScrollBarVisibility(visibility);
......
...@@ -63,8 +63,8 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent ...@@ -63,8 +63,8 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
// This listener should be added before setText(). // This listener should be added before setText().
getTextComponent().getDocument().addDocumentListener(this); getTextComponent().getDocument().addDocumentListener(this);
......
...@@ -58,8 +58,8 @@ final class LWTextFieldPeer ...@@ -58,8 +58,8 @@ final class LWTextFieldPeer
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initialize(); super.initializeImpl();
setEchoChar(getTarget().getEchoChar()); setEchoChar(getTarget().getEchoChar());
synchronized (getDelegateLock()) { synchronized (getDelegateLock()) {
getDelegate().addActionListener(this); getDelegate().addActionListener(this);
......
...@@ -145,8 +145,6 @@ public class LWWindowPeer ...@@ -145,8 +145,6 @@ public class LWWindowPeer
// similar to what Apple's Java do. // similar to what Apple's Java do.
// Since JDK7 we should rely on setOpacity() only. // Since JDK7 we should rely on setOpacity() only.
// this.opacity = c.getAlpha(); // this.opacity = c.getAlpha();
// System.out.println("Delegate assigns alpha (we ignore setOpacity()):"
// +this.opacity);
} }
if (!target.isForegroundSet()) { if (!target.isForegroundSet()) {
...@@ -159,23 +157,29 @@ public class LWWindowPeer ...@@ -159,23 +157,29 @@ public class LWWindowPeer
} }
@Override @Override
public void initialize() { void initializeImpl() {
super.initializeImpl();
if (getTarget() instanceof Frame) { if (getTarget() instanceof Frame) {
setTitle(((Frame)getTarget()).getTitle()); setTitle(((Frame) getTarget()).getTitle());
setState(((Frame)getTarget()).getExtendedState()); setState(((Frame) getTarget()).getExtendedState());
} else if (getTarget() instanceof Dialog) { } else if (getTarget() instanceof Dialog) {
setTitle(((Dialog)getTarget()).getTitle()); setTitle(((Dialog) getTarget()).getTitle());
} }
setAlwaysOnTop(getTarget().isAlwaysOnTop()); setAlwaysOnTop(getTarget().isAlwaysOnTop());
updateMinimumSize(); updateMinimumSize();
setOpacity(getTarget().getOpacity()); final float opacity = getTarget().getOpacity();
setOpaque(getTarget().isOpaque()); if (opacity < 1.0f) {
setOpacity(opacity);
}
super.initialize(); setOpaque(getTarget().isOpaque());
updateInsets(platformWindow.getInsets()); updateInsets(platformWindow.getInsets());
if (getSurfaceData() == null) {
replaceSurfaceData();
}
} }
// Just a helper method // Just a helper method
...@@ -213,28 +217,9 @@ public class LWWindowPeer ...@@ -213,28 +217,9 @@ public class LWWindowPeer
} }
@Override @Override
public void setVisible(final boolean visible) { protected void setVisibleImpl(final boolean visible) {
if (getSurfaceData() == null) { super.setVisibleImpl(visible);
replaceSurfaceData();
}
if (isVisible() == visible) {
return;
}
super.setVisible(visible);
// TODO: update graphicsConfig, see 4868278 // 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?
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
platformWindow.setVisible(visible); platformWindow.setVisible(visible);
if (isSimpleWindow()) { if (isSimpleWindow()) {
LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer. LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
...@@ -256,8 +241,6 @@ public class LWWindowPeer ...@@ -256,8 +241,6 @@ public class LWWindowPeer
} }
} }
} }
});
}
@Override @Override
public GraphicsConfiguration getGraphicsConfiguration() { public GraphicsConfiguration getGraphicsConfiguration() {
...@@ -983,6 +966,9 @@ public class LWWindowPeer ...@@ -983,6 +966,9 @@ public class LWWindowPeer
try { try {
Rectangle r = getBounds(); Rectangle r = getBounds();
g.setColor(getBackground()); g.setColor(getBackground());
if (g instanceof Graphics2D) {
((Graphics2D) g).setComposite(AlphaComposite.Src);
}
g.fillRect(0, 0, r.width, r.height); g.fillRect(0, 0, r.width, r.height);
if (oldBB != null) { if (oldBB != null) {
// Draw the old back buffer to the new one // Draw the old back buffer to the new one
......
...@@ -56,7 +56,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -56,7 +56,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native void nativePushNSWindowToBack(long nsWindowPtr); private static native void nativePushNSWindowToBack(long nsWindowPtr);
private static native void nativePushNSWindowToFront(long nsWindowPtr); private static native void nativePushNSWindowToFront(long nsWindowPtr);
private static native void nativeSetNSWindowTitle(long nsWindowPtr, String title); 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 nativeRevalidateNSWindowShadow(long nsWindowPtr);
private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage); private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename); private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
...@@ -244,17 +243,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -244,17 +243,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// TODO: implement on top of JObjC bridged class // TODO: implement on top of JObjC bridged class
// NSWindow window = JObjC.getInstance().AppKit().NSWindow().getInstance(nativeWindowPtr, JObjCRuntime.getInstance()); // 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) { if (target instanceof javax.swing.RootPaneContainer) {
final javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane(); final javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane();
if (rootpane != null) rootpane.addPropertyChangeListener("ancestor", new PropertyChangeListener() { if (rootpane != null) rootpane.addPropertyChangeListener("ancestor", new PropertyChangeListener() {
...@@ -419,16 +407,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -419,16 +407,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
if (owner != null) { if (owner != null) {
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr()); 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(); contentView.dispose();
nativeDispose(getNSWindowPtr()); nativeDispose(getNSWindowPtr());
CPlatformWindow.super.dispose(); CPlatformWindow.super.dispose();
} }
});
}
@Override // PlatformWindow @Override // PlatformWindow
public void flip(int x1, int y1, int x2, int y2, FlipContents flipAction) { public void flip(int x1, int y1, int x2, int y2, FlipContents flipAction) {
......
...@@ -932,27 +932,6 @@ AWT_ASSERT_NOT_APPKIT_THREAD; ...@@ -932,27 +932,6 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);
} }
/*
* 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 * Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeRevalidateNSWindowShadow * Method: nativeRevalidateNSWindowShadow
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册