[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [albireo-dev] size and border
|
Hi Gordon,
On 2008-02-28 you wrote:
> > /**
> > * Internal class.
> > * Please don't use this class; use {@link SwingControl} instead.
> > */
> >
> > Does this sound acceptable?
>
> I have no objection to an intermediate class, but I find it a little
> awkward that SwingControl would inherit from BorderlessSwingControl. If
> SwingControl can have a border, then it does not have a good
> object-oriented "kind of" relationship with BorderlessSwingControl. IMO
> (without seeing the code) it might be better to have an abstract
> AbstractSwingControl (or BaseSwingControl) containing the shared code,
> and have BorderlessSwingControl and SwingControl both inherit from it.
> You could then move BorderlessSwingControl to the .internal package to
> make it clear that normal users should not subclass it directly.
Your suggestions prompted me to look again at the proposed class hierarchy,
and I could actually get away without an intermediate superclass of
SwingControl. After this cleanup, the code looks quite reasonable.
Committed.
Bruno
Index: src/org/eclipse/albireo/core/SwingControl.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/SwingControl.java,v
retrieving revision 1.57
diff -c -3 -r1.57 SwingControl.java
*** src/org/eclipse/albireo/core/SwingControl.java 16 Apr 2008 16:30:32 -0000 1.57
--- src/org/eclipse/albireo/core/SwingControl.java 16 Apr 2008 20:25:56 -0000
***************
*** 69,77 ****
handleSettingsChange();
}
};
! private Display display;
private Composite layoutDeferredAncestor;
private Frame frame;
private RootPaneContainer rootPaneContainer;
private JComponent swingComponent;
--- 69,84 ----
handleSettingsChange();
}
};
! final /*private*/ Display display;
private Composite layoutDeferredAncestor;
+ // The width of the border to keep around the embedded AWT frame.
+ private int borderWidth;
+
+ // The immediate holder of the embedded AWT frame. It is == this if
+ // borderWidth == 0, or a different Composite if borderWidth != 0.
+ private Composite borderlessChild;
+
private Frame frame;
private RootPaneContainer rootPaneContainer;
private JComponent swingComponent;
***************
*** 111,117 ****
* @see Widget#getStyle
*/
public SwingControl(Composite parent, int style) {
! super(parent, style | SWT.EMBEDDED | SWT.NO_BACKGROUND);
setLayout(new FillLayout());
display = getDisplay();
--- 118,124 ----
* @see Widget#getStyle
*/
public SwingControl(Composite parent, int style) {
! super(parent, style | ((style & SWT.BORDER) == 0 ? SWT.EMBEDDED : 0) | SWT.NO_BACKGROUND);
setLayout(new FillLayout());
display = getDisplay();
***************
*** 133,138 ****
--- 140,177 ----
});
}
+ // Get the width of the border, i.e. the margins of this Composite.
+ // If style contains SWT.BORDER, it is platform dependent (2 pixels on
+ // Linux/gtk); otherwise it must be 0.
+ borderWidth = getBorderWidth();
+ if ((style & SWT.BORDER) != 0) {
+ // Fix for BR #91896
+ // <https://bugs.eclipse.org/bugs/show_bug.cgi?id=91896>:
+ // Since the SWT_AWT.new_Frame creates a low-level connection
+ // between the handle of its argument Composite and the Frame
+ // it creates, and this low-level connection propagates size
+ // from the Composite to the Frame automatically, it ignores
+ // the border. Work around it by creating an intermediate
+ // Composite.
+ borderlessChild =
+ new Composite(this, (style & ~SWT.BORDER) | SWT.EMBEDDED | SWT.NO_BACKGROUND) {
+ /**
+ * Overridden.
+ */
+ public Rectangle getClientArea() {
+ assert Display.getCurrent() != null; // On SWT event thread
+ Rectangle rect = super.getClientArea();
+ SwingControl.this.assignInitialClientArea(rect);
+ return rect;
+ }
+ };
+ } else {
+ // If no border is needed, there is no need to create another
+ // Composite.
+ assert borderWidth == 0;
+ borderlessChild = this;
+ }
+
// Clean up on dispose
addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
***************
*** 142,148 ****
// This listener clears garbage during resizing, making it look much cleaner. The garbage
// is due to use of the sun.awt.noerasebackground property, so this is done only under Windows.
if (Platform.isWin32()) {
! addControlListener(new CleanResizeListener());
}
}
--- 181,187 ----
// This listener clears garbage during resizing, making it look much cleaner. The garbage
// is due to use of the sun.awt.noerasebackground property, so this is done only under Windows.
if (Platform.isWin32()) {
! borderlessChild.addControlListener(new CleanResizeListener());
}
}
***************
*** 186,192 ****
// Make sure Awt environment is initialized.
AwtEnvironment.getInstance(display);
! frame = SWT_AWT.new_Frame(this);
if (verboseSizeLayout)
ComponentDebugging.addComponentSizeDebugListeners(frame);
--- 225,231 ----
// Make sure Awt environment is initialized.
AwtEnvironment.getInstance(display);
! frame = SWT_AWT.new_Frame(borderlessChild);
if (verboseSizeLayout)
ComponentDebugging.addComponentSizeDebugListeners(frame);
***************
*** 443,448 ****
--- 482,495 ----
public Rectangle getClientArea() {
assert Display.getCurrent() != null; // On SWT event thread
Rectangle rect = super.getClientArea();
+ if (borderlessChild == this)
+ assignInitialClientArea(rect);
+ return rect;
+ }
+ /**
+ * Invoked from borderlessChild's override of getClientArea().
+ */
+ void assignInitialClientArea(Rectangle rect) {
if (INITIAL_CLIENT_AREA_WORKAROUND && initialClientArea == null) {
synchronized (this) {
if (cachedSizesInitialized >= 1) {
***************
*** 460,466 ****
initialClientArea = rect;
}
}
- return rect;
}
// We have bidirectional size propagation, from AWT to SWT, and from
--- 507,512 ----
***************
*** 560,567 ****
Point minSize = new Point(min.width, min.height);
Point prefSize = new Point(pref.width, pref.height);
Point maxSize = new Point(max.width, max.height);
! preferredSizeChanged(minSize, prefSize, maxSize);
! firePreferredSizeChangedEvent(minSize, prefSize, maxSize);
} finally {
onBehalfAWTTimes.remove(Thread.currentThread());
}
--- 606,619 ----
Point minSize = new Point(min.width, min.height);
Point prefSize = new Point(pref.width, pref.height);
Point maxSize = new Point(max.width, max.height);
! // Augment the three sizes.
! minSize.x += 2*borderWidth;
! minSize.y += 2*borderWidth;
! prefSize.x += 2*borderWidth;
! prefSize.y += 2*borderWidth;
! maxSize.x += 2*borderWidth;
! maxSize.y += 2*borderWidth;
! notePreferredSizeChanged(minSize, prefSize, maxSize);
} finally {
onBehalfAWTTimes.remove(Thread.currentThread());
}
***************
*** 672,678 ****
if ((cachedSizesInitialized >= 2) ||
(Platform.isGtk() && Platform.JAVA_VERSION < Platform.javaVersion(1, 6, 0)) ||
Platform.isWin32()) {
! setAWTSize(width, height);
}
}
}
--- 724,731 ----
if ((cachedSizesInitialized >= 2) ||
(Platform.isGtk() && Platform.JAVA_VERSION < Platform.javaVersion(1, 6, 0)) ||
Platform.isWin32()) {
! setAWTSize(Math.max(width-2*borderWidth, 0),
! Math.max(height-2*borderWidth, 0));
}
}
}
***************
*** 699,718 ****
System.err.println("SWT thread: Uninitialized AWT sizes for " + swingComponent);
return super.computeSize(widthHint, heightHint, changed);
} else {
- assert cachedSizesInitialized >= 1;
synchronized (this) {
cachedSizesInitialized = 2;
}
int width =
(widthHint == SWT.DEFAULT ? pref.width :
widthHint < min.width ? min.width :
! widthHint > max.width ? max.width :
! widthHint);
int height =
(heightHint == SWT.DEFAULT ? pref.height :
heightHint < min.width ? min.height :
! heightHint > max.width ? max.height :
! heightHint);
if (verboseSizeLayout)
System.err.println("SWT thread: Computed size: " + width + " x " + height + " for " + swingComponent);
return new Point(width, height);
--- 752,773 ----
System.err.println("SWT thread: Uninitialized AWT sizes for " + swingComponent);
return super.computeSize(widthHint, heightHint, changed);
} else {
synchronized (this) {
+ assert cachedSizesInitialized >= 1;
cachedSizesInitialized = 2;
}
int width =
(widthHint == SWT.DEFAULT ? pref.width :
widthHint < min.width ? min.width :
! widthHint > max.width ? max.width :
! widthHint)
! + 2*borderWidth;
int height =
(heightHint == SWT.DEFAULT ? pref.height :
heightHint < min.width ? min.height :
! heightHint > max.width ? max.height :
! heightHint)
! + 2*borderWidth;
if (verboseSizeLayout)
System.err.println("SWT thread: Computed size: " + width + " x " + height + " for " + swingComponent);
return new Point(width, height);
***************
*** 731,736 ****
--- 786,800 ----
*/
public abstract Composite getLayoutAncestor();
+ /**
+ * Called when the preferred sizes of this control, as computed by
+ * AWT, have changed.
+ */
+ /*private*/ void notePreferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
+ preferredSizeChanged(minSize, prefSize, maxSize);
+ firePreferredSizeChangedEvent(minSize, prefSize, maxSize);
+ }
+
// TODO: remove this method and just leave the listener for advanced users?
/**
* Called when the preferred sizes of this control, as computed by
***************
*** 753,761 ****
* The parameters <var>minPoint</var>, <var>prefPoint</var>,
* <var>maxPoint</var> can usually be ignored: It is often enough to rely on the
* {@link #layout()} method.
! * @param minSize The new minimum size for this control, as reported by AWT.
! * @param prefSize The new preferred size for this control, as reported by AWT.
! * @param maxSize The new maximum size for this control, as reported by AWT.
*/
protected void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
Composite ancestor = getLayoutAncestor();
--- 817,828 ----
* The parameters <var>minPoint</var>, <var>prefPoint</var>,
* <var>maxPoint</var> can usually be ignored: It is often enough to rely on the
* {@link #layout()} method.
! * @param minSize The new minimum size for this control, as reported by
! * AWT, plus the border width on each side.
! * @param prefSize The new preferred size for this control, as reported by
! * AWT, plus the border width on each side.
! * @param maxSize The new maximum size for this control, as reported by
! * AWT, plus the border width on each side.
*/
protected void preferredSizeChanged(Point minSize, Point prefSize, Point maxSize) {
Composite ancestor = getLayoutAncestor();
***************
*** 765,771 ****
// changed. Objects such as org.eclipse.swt.layout.GridData (for
// GridLayout) cache the last width and height. We must flush this
// cached geometry.
! ancestor.layout(new Control[] { this });
}
}
--- 832,838 ----
// changed. Objects such as org.eclipse.swt.layout.GridData (for
// GridLayout) cache the last width and height. We must flush this
// cached geometry.
! ancestor.layout(new Control[] { borderlessChild });
}
}
***************
*** 869,874 ****
--- 936,943 ----
private void handleDispose() {
focusHandler.dispose();
+ if (borderlessChild != this)
+ borderlessChild.dispose();
display.removeListener(SWT.Settings, settingsListener);
}