You need to sign in or sign up before continuing.
提交 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>
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
setLabel(getTarget().getLabel());
synchronized (getDelegateLock()) {
getDelegate().addActionListener(this);
......
......@@ -61,8 +61,8 @@ final class LWCheckboxPeer
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
setLabel(getTarget().getLabel());
setState(getTarget().getState());
setCheckboxGroup(getTarget().getCheckboxGroup());
......
......@@ -55,8 +55,8 @@ final class LWChoicePeer extends LWComponentPeer<Choice, JComboBox<String>>
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
final Choice choice = getTarget();
final JComboBox<String> combo = getDelegate();
synchronized (getDelegateLock()) {
......
......@@ -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
// 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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
// 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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
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 abstract class LWComponentPeer<T extends Component, D extends JComponent>
}
public LWComponentPeer(T target, PlatformComponent platformComponent) {
targetPaintArea = new LWRepaintArea();
this.target = target;
this.platformComponent = platformComponent;
......@@ -201,10 +195,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
}
@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 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
*
* @see #isVisible()
*/
protected boolean isShowing() {
protected final boolean isShowing() {
synchronized (getPeerTreeLock()) {
if (isVisible()) {
final LWContainerPeer container = getContainerPeer();
......
......@@ -60,8 +60,8 @@ final class LWLabelPeer extends LWComponentPeer<Label, JLabel>
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
setText(getTarget().getText());
setAlignment(getTarget().getAlignment());
}
......
......@@ -49,8 +49,8 @@ final class LWListPeer
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
setMultipleMode(getTarget().isMultipleMode());
final int[] selectedIndices = getTarget().getSelectedIndexes();
synchronized (getDelegateLock()) {
......
......@@ -54,8 +54,8 @@ final class LWScrollBarPeer extends LWComponentPeer<Scrollbar, JScrollBar>
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
final Scrollbar target = getTarget();
setValues(target.getValue(), target.getVisibleAmount(),
target.getMinimum(), target.getMaximum());
......
......@@ -70,8 +70,8 @@ final class LWScrollPanePeer extends LWContainerPeer<ScrollPane, JScrollPane>
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
final int policy = getTarget().getScrollbarDisplayPolicy();
synchronized (getDelegateLock()) {
getDelegate().getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
......
......@@ -59,8 +59,8 @@ final class LWTextAreaPeer
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
final int visibility = getTarget().getScrollbarVisibility();
synchronized (getDelegateLock()) {
setScrollBarVisibility(visibility);
......
......@@ -63,8 +63,8 @@ abstract class LWTextComponentPeer<T extends TextComponent, D extends JComponent
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
synchronized (getDelegateLock()) {
// This listener should be added before setText().
getTextComponent().getDocument().addDocumentListener(this);
......
......@@ -58,8 +58,8 @@ final class LWTextFieldPeer
}
@Override
public void initialize() {
super.initialize();
void initializeImpl() {
super.initializeImpl();
setEchoChar(getTarget().getEchoChar());
synchronized (getDelegateLock()) {
getDelegate().addActionListener(this);
......
......@@ -145,8 +145,6 @@ public class LWWindowPeer
// 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 @@ public class LWWindowPeer
}
@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,50 +217,29 @@ public class LWWindowPeer
}
@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?
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);
}
}
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);
}
}
});
}
}
@Override
......@@ -983,6 +966,9 @@ public class LWWindowPeer
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
......
......@@ -56,7 +56,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
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 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// 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 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
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
......
......@@ -932,27 +932,6 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
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
* Method: nativeRevalidateNSWindowShadow
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册