diff options
Diffstat (limited to 'common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlAligner.java')
-rw-r--r-- | common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlAligner.java | 913 |
1 files changed, 0 insertions, 913 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlAligner.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlAligner.java deleted file mode 100644 index ebbd1eed4c..0000000000 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlAligner.java +++ /dev/null @@ -1,913 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.common.ui.internal.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import org.eclipse.core.runtime.Assert; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; - -/** - * This class is responsible to set a preferred width on the registered widgets - * (either <code>Control</code> or <code>ControlAligner</code>) based on the - * widest widget. - * <p> - * Important: The layout data has to be a <code>GridData</code>. If none is set, - * then a new <code>GridData</code> is automatically created. - * <p> - * Here an example of the result if this aligner is used to align controls - * within either one or two group boxes, the controls added are the labels in - * this case. It is also possible to align controls on the right side of the - * main component, a spacer can be used for extra space. - * <p> - * Here's an example: - * <pre> - * - Group Box 1 -------------------------------------------------------------- - * | -------------------------------------- ------------- | - * | Name: | I | | Browse... | | - * | -------------------------------------- ------------- | - * | --------- | - * | Preallocation Size: | |I| | - * | --------- | - * | -------------------------------------- | - * | Descriptor: | |v| | - * | -------------------------------------- | - * ---------------------------------------------------------------------------- - * - * - Group Box 2 -------------------------------------------------------------- - * | -------------------------------------- | - * | Mapping Type: | |V| | - * | -------------------------------------- | - * | -------------------------------------- | - * | Check in Script: | I | | - * | -------------------------------------- | - * ----------------------------------------------------------------------------</pre> - * - * @version 2.0 - * @since 2.0 - */ -@SuppressWarnings("nls") -public final class ControlAligner -{ - /** - * Flag used to prevent a validation so it can be done after an operation - * completed. - */ - private boolean autoValidate; - - /** - * The utility class used to support bound properties. - */ - private Collection<Listener> changeSupport; - - /** - * The listener added to each of the controls that listens only to a text - * change. - */ - private Listener listener; - - /** - * Prevents infinite recursion when recalculating the preferred width. - * This happens in an hierarchy of <code>ControlAligner</code>s. The lock - * has to be placed here and not in the {@link ControlAlignerWrapper}. - */ - private boolean locked; - - /** - * The length of the widest control. If the length was not calculated, then - * this value is 0. - */ - private int maximumWidth; - - /** - * The collection of {@link Wrapper}s encapsulating either <code>Control</code>s - * or {@link ControlAligner}s. - */ - private Collection<Wrapper> wrappers; - - /** - * A null-<code>Point</code> object used to clear the preferred size. - */ - private static final Point DEFAULT_SIZE = new Point(SWT.DEFAULT, SWT.DEFAULT); - - /** - * The types of events to listen in order to properly adjust the size of all - * the widgets. - */ - private static final int[] EVENT_TYPES = { - SWT.Dispose, - SWT.Hide, - SWT.Resize, - SWT.Show - }; - - /** - * Creates a new <code>ControlAligner</code>. - */ - public ControlAligner() { - super(); - initialize(); - } - - /** - * Creates a new <code>ControlAligner</code>. - * - * @param controls The collection of <code>Control</code>s - */ - public ControlAligner(Collection<? extends Control> controls) { - this(); - addAllControls(controls); - } - - /** - * Adds the given control. Its width will be used along with the width of all - * the other registered controls in order to get the greater witdh and use - * it as the width for all the controls. - * - * @param control The <code>Control</code> to be added - */ - public void add(Control control) { - - Assert.isNotNull(control, "Can't add null to this ControlAligner"); - - Wrapper wrapper = buildWrapper(control); - wrapper.addListener(listener); - wrappers.add(wrapper); - - revalidate(false); - } - - /** - * Adds the given control. Its width will be used along with the width of all - * the other registered controls in order to get the greater witdh and use - * it as the width for all the controls. - * - * @param controlAligner The <code>ControlAligner</code> to be added - * @exception IllegalArgumentException Can't add the <code>ControlAligner</code> - * to itself - */ - public void add(ControlAligner controlAligner) { - - Assert.isNotNull(controlAligner, "Can't add null to this ControlAligner"); - Assert.isLegal(controlAligner != this, "Can't add the ControlAligner to itself"); - - Wrapper wrapper = buildWrapper(controlAligner); - wrapper.addListener(listener); - wrappers.add(wrapper); - - if (!controlAligner.wrappers.isEmpty()) { - revalidate(false); - } - } - - /** - * Adds the items contained in the given collection into this - * <code>ControlAligner</code>. The preferred width of each item will be - * used along with the width of all the other items in order to get the - * widest control and use its width as the width for all the controls. - * - * @param aligners The collection of <code>ControlAligner</code>s - */ - public void addAllControlAligners(Collection<ControlAligner> aligners) { - - // Deactivate the auto validation while adding all the Controls and/or - // ControlAligners in order to improve performance - boolean oldAutoValidate = autoValidate; - autoValidate = false; - - for (ControlAligner aligner : aligners) { - add(aligner); - } - - autoValidate = oldAutoValidate; - revalidate(false); - } - - /** - * Adds the items contained in the given collection into this - * <code>ControlAligner</code>. The preferred width of each item will be - * used along with the width of all the other items in order to get the - * widest control and use its width as the width for all the controls. - * - * @param controls The collection of <code>Control</code>s - */ - public void addAllControls(Collection<? extends Control> controls) { - - // Deactivate the auto validation while adding all the Controls and/or - // ControlAligners in order to improve performance - boolean oldAutoValidate = autoValidate; - autoValidate = false; - - for (Control control : controls) { - add(control); - } - - autoValidate = oldAutoValidate; - revalidate(false); - } - - /** - * Adds the given <code>ControListener</code>. - * - * @param listener The <code>Listener</code> to be added - */ - private void addListener(Listener listener) { - - if (changeSupport == null) { - changeSupport = new ArrayList<Listener>(); - } - - changeSupport.add(listener); - } - - /** - * Creates a new <code>Wrapper</code> that encapsulates the given source. - * - * @param control The control to be wrapped - * @return A new {@link Wrapper} - */ - private Wrapper buildWrapper(Control control) { - return new ControlWrapper(control); - } - - /** - * Creates a new <code>Wrapper</code> that encapsulates the given source. - * - * @param ControlAligner The <code>ControlAligner</code> to be wrapped - * @return A new {@link ControlAlignerWrapper} - */ - private Wrapper buildWrapper(ControlAligner ControlAligner) { - return new ControlAlignerWrapper(ControlAligner); - } - - /** - * Calculates the width taken by the widgets and returns the maximum width. - * - * @param recalculateSize <code>true</code> to recalculate the preferred size - * of all the wrappers contained within them rather than using the cached - * size; <code>false</code> to use the cached size - */ - private int calculateWidth(boolean recalculateSize) { - - int width = 0; - - for (Wrapper wrapper : wrappers) { - Point size = wrapper.cachedSize(); - - // The size has not been calculated yet - if (recalculateSize || (size.x == 0)) { - size = wrapper.calculateSize(); - } - - // Only keep the greatest width - width = Math.max(size.x, width); - } - - return width; - } - - /** - * Reports a bound property change. - * - * @param oldValue the old value of the property (as an int) - * @param newValue the new value of the property (as an int) - */ - private void controlResized(int oldValue, int newValue) { - - if ((changeSupport != null) && (oldValue != newValue)) { - Event event = new Event(); - event.widget = SWTUtil.getShell(); - event.data = this; - - for (Listener listener : changeSupport) { - listener.handleEvent(event); - } - } - } - - /** - * Disposes this <code>ControlAligner</code>, this can improve the speed of - * disposing a pane. When a pane is disposed, this aligner doesn't need to - * revalidate its size upon dispose of its widgets. - */ - public void dispose() { - - for (Iterator<Wrapper> iter = wrappers.iterator(); iter.hasNext(); ) { - Wrapper wrapper = iter.next(); - wrapper.removeListener(listener); - iter.remove(); - } - - this.wrappers.clear(); - } - - /** - * Returns the length of the widest control. If the length was not - * calculated, then this value is 0. - * - * @return The width of the widest control or 0 if the length has not been - * calculated yet - */ - public int getMaximumWidth() { - return maximumWidth; - } - - /** - * Initializes this <code>ControlAligner</code>. - */ - private void initialize() { - - this.autoValidate = true; - this.maximumWidth = 0; - this.listener = new ListenerHandler(); - this.wrappers = new ArrayList<Wrapper>(); - } - - /** - * Invalidates the size of the given object. - * - * @param source The source object to be invalidated - */ - private void invalidate(Object source) { - - Wrapper wrapper = retrieveWrapper(source); - - if (!wrapper.locked()) { - Point size = wrapper.cachedSize(); - size.x = size.y = 0; - wrapper.setSize(DEFAULT_SIZE); - } - } - - /** - * Updates the maximum length based on the widest control. This methods - * does not update the width of the controls. - * - * @param recalculateSize <code>true</code> to recalculate the preferred size - * of all the wrappers contained within them rather than using the cached - * size; <code>false</code> to use the cached size - */ - private void recalculateWidth(boolean recalculateSize) { - - int width = calculateWidth(recalculateSize); - - try { - locked = true; - setMaximumWidth(width); - } - finally { - locked = false; - } - } - - /** - * Removes the given control. Its preferred width will not be used when - * calculating the preferred width. - * - * @param control The control to be removed - * @exception AssertionFailedException If the given <code>Control</code> is - * <code>null</code> - */ - public void remove(Control control) { - - Assert.isNotNull(control, "The Control to remove cannot be null"); - - Wrapper wrapper = retrieveWrapper(control); - wrapper.removeListener(listener); - wrappers.remove(wrapper); - - revalidate(true); - } - - /** - * Removes the given <code>ControlAligner</code>. Its preferred width - * will not be used when calculating the preferred witdh. - * - * @param controlAligner The <code>ControlAligner</code> to be removed - * @exception AssertionFailedException If the given <code>ControlAligner</code> - * is <code>null</code> - */ - public void remove(ControlAligner controlAligner) { - - Assert.isNotNull(controlAligner, "The ControlAligner to remove cannot be null"); - - Wrapper wrapper = retrieveWrapper(controlAligner); - wrapper.removeListener(listener); - wrappers.remove(wrapper); - - revalidate(true); - } - - /** - * Removes the given <code>Listener</code>. - * - * @param listener The <code>Listener</code> to be removed - */ - private void removeListener(Listener listener) { - - changeSupport.remove(listener); - - if (changeSupport.isEmpty()) { - changeSupport = null; - } - } - - /** - * Retrieves the <code>Wrapper</code> that is encapsulating the given object. - * - * @param source Either a <code>Control</code> or a <code>ControlAligner</code> - * @return Its <code>Wrapper</code> - */ - private Wrapper retrieveWrapper(Object source) { - - for (Wrapper wrapper : wrappers) { - if (wrapper.source() == source) { - return wrapper; - } - } - - throw new IllegalArgumentException("Can't retrieve the Wrapper for " + source); - } - - /** - * If the count of control is greater than one and {@link #isAutoValidate()} - * returns <code>true</code>, then the size of all the registered - * <code>Control</code>s will be udpated. - * - * @param recalculateSize <code>true</code> to recalculate the preferred size - * of all the wrappers contained within them rather than using the cached - * size; <code>false</code> to use the cached size - */ - private void revalidate(boolean recalculateSize) { - - if (autoValidate) { - recalculateWidth(recalculateSize); - updateWrapperSize(recalculateSize); - } - } - - /** - * Bases on the information contained in the given <code>Event</code>, - * resize the controls. - * - * @param event The <code>Event</code> sent by the UI thread when the state - * of a widget changed - */ - private void revalidate(Event event) { - - // We don't need to revalidate during a revalidation process - if (locked) { - return; - } - - Object source; - - if (event.widget != SWTUtil.getShell()) { - source = event.widget; - Control control = (Control) source; - - // When a dialog is opened, we need to actually force a layout of - // the controls, this is required because the control is actually - // not visible when the preferred width is caculated - if (control == control.getShell()) { - if (event.type == SWT.Dispose) { - return; - } - - source = null; - } - } - else { - source = event.data; - } - - // Either remove the ControlWrapper if the widget was disposed or - // invalidate the widget in order to recalculate the preferred size - if (source != null) { - if (event.type == SWT.Dispose) { - Wrapper wrapper = retrieveWrapper(source); - wrappers.remove(wrapper); - } - else { - invalidate(source); - } - } - - // Now revalidate all the Controls and ControlAligners - revalidate(true); - } - - /** - * Sets the length of the widest control. If the length was not calulcated, - * then this value is 0. - * - * @param maximumWidth The width of the widest control - */ - private void setMaximumWidth(int maximumWidth) { - - int oldMaximumWidth = this.maximumWidth; - this.maximumWidth = maximumWidth; - controlResized(oldMaximumWidth, maximumWidth); - } - - /** - * Returns a string representation of this <code>ControlAligner</code>. - * - * @return Information about this object - */ - @Override - public String toString() { - - StringBuffer sb = new StringBuffer(); - sb.append("maximumWidth="); - sb.append(maximumWidth); - sb.append(", wrappers="); - sb.append(wrappers); - return StringTools.buildToStringFor(this, sb); - } - - /** - * Updates the size of every <code>Wrapper</code> based on the maximum width. - * - * @param forceRevalidate <code>true</code> to revalidate the wrapper's size - * even though its current size might be the same as the maximum width; - * <code>false</code> to only revalidate the wrappers with a different width - */ - private void updateWrapperSize(boolean forceRevalidate) { - - for (Wrapper wrapper : wrappers) { - Point cachedSize = wrapper.cachedSize(); - - // No need to change the size of the wrapper since it's always using - // the maximum width - if (forceRevalidate || (cachedSize.x != maximumWidth)) { - Point size = new Point(maximumWidth, cachedSize.y); - wrapper.setSize(size); - } - } - } - - /** - * This <code>Wrapper</code> encapsulates a {@link ControlAligner}. - */ - private class ControlAlignerWrapper implements Wrapper { - /** - * The cached size, which is {@link ControlAligner#maximumWidth}. - */ - private final Point cachedSize; - - /** - * The <code>ControlAligner</code> encapsulated by this - * <code>Wrapper</code>. - */ - private final ControlAligner controlAligner; - - /** - * Creates a new <code>ControlAlignerWrapper</code> that encapsulates - * the given <code>ControlAligner</code>. - * - * @param controlAligner The <code>ControlAligner</code> to be - * encapsulated by this <code>Wrapper</code> - */ - private ControlAlignerWrapper(ControlAligner controlAligner) { - super(); - this.controlAligner = controlAligner; - this.cachedSize = new Point(controlAligner.maximumWidth, 0); - } - - /* - * (non-Javadoc) - */ - public void addListener(Listener listener) { - controlAligner.addListener(listener); - } - - /* - * (non-Javadoc) - */ - public Point cachedSize() { - cachedSize.x = controlAligner.maximumWidth; - return cachedSize; - } - - /* - * (non-Javadoc) - */ - public Point calculateSize() { - - Point size = new Point(controlAligner.calculateWidth(false), 0); - - if (size.x != SWT.DEFAULT) { - cachedSize.x = size.x; - } - else { - cachedSize.x = 0; - } - - if (size.y != SWT.DEFAULT) { - cachedSize.y = size.y; - } - else { - cachedSize.y = 0; - } - - return size; - } - - /* - * (non-Javadoc) - */ - public boolean locked() { - return controlAligner.locked; - } - - /* - * (non-Javadoc) - */ - public void removeListener(Listener listener) { - controlAligner.removeListener(listener); - } - - /* - * (non-Javadoc) - */ - public void setSize(Point size) { - - if (size == DEFAULT_SIZE) { - controlAligner.maximumWidth = 0; - } - else if (controlAligner.maximumWidth != size.x) { - controlAligner.maximumWidth = size.x; - controlAligner.updateWrapperSize(true); - } - } - - /* - * (non-Javadoc) - */ - public Object source() { - return controlAligner; - } - - /* - * (non-Javadoc) - */ - @Override - public String toString() { - - StringBuffer sb = new StringBuffer(); - sb.append("Cached size="); - sb.append(cachedSize); - sb.append(", ControlAligner="); - sb.append(controlAligner); - return StringTools.buildToStringFor(this, sb); - } - } - - /** - * This <code>Wrapper</code> encapsulates a {@link Control}. - */ - private class ControlWrapper implements Wrapper { - /** - * The cached size, which is control's size. - */ - private Point cachedSize; - - /** - * The control to be encapsulated by this <code>Wrapper</code>. - */ - private final Control control; - - /** - * Creates a new <code>controlWrapper</code> that encapsulates the given - * control. - * - * @param control The control to be encapsulated by this <code>Wrapper</code> - */ - private ControlWrapper(Control control) { - super(); - - this.control = control; - this.cachedSize = new Point(0, 0); - } - - /* - * (non-Javadoc) - */ - public void addListener(Listener listener) { - - for (int eventType : EVENT_TYPES) { - control.addListener(eventType, listener); - } - } - - /* - * (non-Javadoc) - */ - public Point cachedSize() { - return cachedSize; - } - - /* - * (non-Javadoc) - */ - public Point calculateSize() { - - cachedSize = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); - - // Update right away the control's GridData - GridData gridData = (GridData) control.getLayoutData(); - - if (gridData == null) { - gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); - control.setLayoutData(gridData); - } - - gridData.widthHint = cachedSize.x; - gridData.heightHint = cachedSize.y; - - // Make sure the size is not -1 - if (cachedSize.x == SWT.DEFAULT) { - cachedSize.x = 0; - } - - if (cachedSize.y == SWT.DEFAULT) { - cachedSize.y = 0; - } - - return cachedSize; - } - - /* - * (non-Javadoc) - */ - public boolean locked() { - return false; - } - - /* - * (non-Javadoc) - */ - public void removeListener(Listener listener) { - - for (int eventType : EVENT_TYPES) { - control.removeListener(eventType, listener); - } - } - - /* - * (non-Javadoc) - */ - public void setSize(Point size) { - - if (control.isDisposed()) { - return; - } - - // Update the GridData with the new size - GridData gridData = (GridData) control.getLayoutData(); - - if (gridData == null) { - gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); - control.setLayoutData(gridData); - } - - gridData.widthHint = size.x; - gridData.heightHint = size.y; - - // Force the control to be resized, and tell its parent to layout - // its widgets - if (size.x > 0) { -// locked = true; -// try { -//// control.getParent().layout(new Control[] { control }); -// control.getParent().layout(true); -// } -// finally { -// locked = false; -// } - Rectangle bounds = control.getBounds(); - - // Only update the control's width if it's - // different from the current size - if (bounds.width != size.x) { - locked = true; - - try { -// control.setBounds(bounds.x, bounds.y, size.x, size.y); - control.getParent().layout(true); - } - finally - { - locked = false; - } - } - } - } - - /* - * (non-Javadoc) - */ - public Control source() { - return control; - } - - /* - * (non-Javadoc) - */ - @Override - public String toString() { - - StringBuffer sb = new StringBuffer(); - sb.append("Cached size="); - sb.append(cachedSize); - sb.append(", Control="); - sb.append(control); - return StringTools.buildToStringFor(this, sb); - } - } - - /** - * The listener added to each of the control that is notified in order to - * revalidate the preferred size. - */ - private class ListenerHandler implements Listener { - public void handleEvent(Event event) { - ControlAligner.this.revalidate(event); - } - } - - /** - * This <code>Wrapper</code> helps to encapsulate heterogeneous objects and - * apply the same behavior on them. - */ - private interface Wrapper { - /** - * Adds the given <code>Listener</code> to wrapped object in order to - * receive notification when its property changed. - * - * @param listener The <code>Listener</code> to be added - */ - void addListener(Listener listener); - - /** - * Returns the cached size of the encapsulated source. - * - * @return A non-<code>null</code> <code>Point</code> where the x is the - * width and the y is the height of the widget - */ - Point cachedSize(); - - /** - * Calculates the preferred size the wrapped object would take by itself. - * - * @return The calculated size - */ - Point calculateSize(); - - /** - * Prevents infinite recursion when recalculating the preferred width. - * This happens in an hierarchy of <code>ControlAligner</code>s. - * - * @return <code>true</code> to prevent this <code>Wrapper</code> from - * being invalidated; otherwise <code>false</code> - */ - boolean locked(); - - /** - * Removes the given <code>Listener</code>. - * - * @param listener The <code>Listener</code> to be removed - */ - void removeListener(Listener listener); - - /** - * Sets the size on the encapsulated source. - * - * @param size The new size - */ - void setSize(Point size); - - /** - * Returns the encapsulated object. - * - * @return The object that is been wrapped - */ - Object source(); - } -}
\ No newline at end of file |