diff options
author | Brian Vosburgh | 2013-04-10 19:19:09 +0000 |
---|---|---|
committer | Brian Vosburgh | 2013-04-16 20:04:52 +0000 |
commit | b560d825c446f26712e348f45a12823f1d7f242e (patch) | |
tree | b8fcf329aee253be64c4f0b93c9fd4470c446d61 /common/plugins/org.eclipse.jpt.common.ui | |
parent | 65512b3154161a233cee773c6ddda56201ade3ca (diff) | |
download | webtools.dali-b560d825c446f26712e348f45a12823f1d7f242e.tar.gz webtools.dali-b560d825c446f26712e348f45a12823f1d7f242e.tar.xz webtools.dali-b560d825c446f26712e348f45a12823f1d7f242e.zip |
rework ControlSwitcher -> PageBookModelBinding
Diffstat (limited to 'common/plugins/org.eclipse.jpt.common.ui')
3 files changed, 211 insertions, 157 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/PageBookModelBinding.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/PageBookModelBinding.java new file mode 100644 index 0000000000..a7d8af3c73 --- /dev/null +++ b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/PageBookModelBinding.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2008, 2013 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.swt.bind; + +import org.eclipse.jpt.common.ui.internal.listeners.SWTPropertyChangeListenerWrapper; +import org.eclipse.jpt.common.ui.internal.swt.events.DisposeAdapter; +import org.eclipse.jpt.common.ui.internal.swt.widgets.ControlTools; +import org.eclipse.jpt.common.utility.internal.ObjectTools; +import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; +import org.eclipse.jpt.common.utility.model.listener.PropertyChangeAdapter; +import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; +import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; +import org.eclipse.jpt.common.utility.transformer.Transformer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.part.PageBook; + +/** + * This binding can be used to keep a page book's current page synchronized + * with a model. + * @see PropertyValueModel + * @see PageBook + */ +final class PageBookModelBinding<T> { + // ***** model + /** + * The value model that determines the page to be displayed. + */ + private final PropertyValueModel<T> valueModel; + + /** + * A listener that allows us to synchronize the page book's current page + * with the value model. + */ + private final PropertyChangeListener valueModelListener; + + // ***** transformer + /** + * The transformer that converts the model's value to the control + * to be displayed by the page book. If the transformer returns + * <code>null</code>, the page book will display the null page. + */ + private final Transformer<? super T, Control> transformer; + + // ***** UI + /** + * The page book whose current page is determined by the value model. + */ + private final PageBook pageBook; + + /** + * A listener that allows us to stop listening to stuff when the page book + * is disposed. (Critical for preventing memory leaks.) + */ + private final DisposeListener pageBookDisposeListener; + + /** + * The control to be displayed in the page book if the control transformer + * returns <code>null</code>. + */ + private final Control defaultPage; + + + // ********** construction ********** + + /** + * Constructor - the model, transformer, and page book are required. + */ + PageBookModelBinding(PropertyValueModel<T> valueModel, Transformer<? super T, Control> transformer, PageBook pageBook, Control defaultPage) { + super(); + if ((valueModel == null) || (transformer == null) || (pageBook == null)) { + throw new NullPointerException(); + } + this.valueModel = valueModel; + this.transformer = transformer; + this.pageBook = pageBook; + + this.defaultPage = (defaultPage != null) ? defaultPage : this.buildDefaultDefaultPage(); + if (this.defaultPage.getParent() != this.pageBook) { + throw new IllegalArgumentException("The null page's parent must be the page book: " + defaultPage); //$NON-NLS-1$ + } + + this.valueModelListener = this.buildValueModelListener(); + this.valueModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.valueModelListener); + + this.pageBookDisposeListener = this.buildPageBookDisposeListener(); + this.pageBook.addDisposeListener(this.pageBookDisposeListener); + + this.showPage(this.valueModel.getValue()); + } + + private Control buildDefaultDefaultPage() { + // SWT.SHADOW_NONE makes the line separator invisible + return new Label(this.pageBook, SWT.SEPARATOR | SWT.SHADOW_NONE | SWT.HORIZONTAL); + } + + private PropertyChangeListener buildValueModelListener() { + return new SWTPropertyChangeListenerWrapper(new ValueModelListener()); + } + + /* CU private */ class ValueModelListener + extends PropertyChangeAdapter + { + @Override + @SuppressWarnings("unchecked") + public void propertyChanged(PropertyChangeEvent event) { + PageBookModelBinding.this.showPage((T) event.getNewValue()); + } + } + + private DisposeListener buildPageBookDisposeListener() { + return new PageBookDisposeListener(); + } + + /* CU private */ class PageBookDisposeListener + extends DisposeAdapter + { + @Override + public void widgetDisposed(DisposeEvent event) { + PageBookModelBinding.this.pageBookDisposed(); + } + } + + + // ********** model events ********** + + /** + * Show the page corresponding to the specified model value. + */ + /* CU private */ void showPage(T value) { + if (this.pageBook.isDisposed()) { + return; + } + Control page = this.transformer.transform(value); + this.pageBook.showPage((page != null) ? page : this.defaultPage); + ControlTools.reflow(this.pageBook); + } + + + // ********** UI events ********** + + /* CU private */ void pageBookDisposed() { + // the page book is not yet "disposed" when we receive this event + // so we can still remove our listener + this.pageBook.removeDisposeListener(this.pageBookDisposeListener); + this.valueModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.valueModelListener); + } + + + // ********** misc ********** + + @Override + public String toString() { + return ObjectTools.toString(this, this.valueModel); + } +} diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/SWTBindTools.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/SWTBindTools.java index 7afdc59df9..5dcbc7054d 100644 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/SWTBindTools.java +++ b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/swt/bind/SWTBindTools.java @@ -28,6 +28,7 @@ import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.part.PageBook; /** * Various SWT tools. @@ -206,6 +207,50 @@ public final class SWTBindTools { } + // ********** page book ********** + + /** + * Bind the specified control model to the specified page book. The model's + * value will determine which page the page book displays. + */ + public static void bind(PropertyValueModel<Control> controlModel, PageBook pageBook) { + bind(controlModel, pageBook, null); + } + + /** + * Bind the specified control model to the specified page book. The model's + * value will determine which page the page book displays. If the model's + * value is <code>null</code>, the page book will display the specified + * default page. + */ + public static void bind(PropertyValueModel<Control> controlModel, PageBook pageBook, Control defaultPage) { + bind(controlModel, TransformerTools.<Control>passThruTransformer(), pageBook, defaultPage); + } + + /** + * Bind the specified model to the specified page book. The model's value will + * determine which page the page book displays. The specified transformer + * will convert the model's value into the control to be displayed in the + * page book. + */ + public static <T> void bind(PropertyValueModel<T> valueModel, Transformer<? super T, Control> transformer, PageBook pageBook) { + bind(valueModel, transformer, pageBook, null); + } + + /** + * Bind the specified model to the specified page book. The model's value will + * determine which page the page book displays. The specified transformer + * will convert the model's value into the control to be displayed in the + * page book. If the transformer converts the model's value into + * <code>null</code>, the page book will display the specified default + * page. + */ + @SuppressWarnings("unused") + public static <T> void bind(PropertyValueModel<T> valueModel, Transformer<? super T, Control> transformer, PageBook pageBook, Control defaultPage) { + new PageBookModelBinding<T>(valueModel, transformer, pageBook, defaultPage); + } + + // ********** 'enabled' state ********** /** diff --git a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlSwitcher.java b/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlSwitcher.java deleted file mode 100644 index 932f992a54..0000000000 --- a/common/plugins/org.eclipse.jpt.common.ui/src/org/eclipse/jpt/common/ui/internal/util/ControlSwitcher.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2011 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 org.eclipse.jpt.common.ui.internal.listeners.SWTPropertyChangeListenerWrapper; -import org.eclipse.jpt.common.ui.internal.swt.widgets.ControlTools; -import org.eclipse.jpt.common.utility.internal.transformer.AbstractTransformer; -import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent; -import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener; -import org.eclipse.jpt.common.utility.model.value.PropertyValueModel; -import org.eclipse.jpt.common.utility.transformer.Transformer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.ui.part.PageBook; - -/** - * This controller is responsible to switch the active page based on a value. A - * <code>Transformer</code> is used to transformed that value into a - * <code>Control</code>. - * - * @version 2.3 - * @since 2.0 - */ -public final class ControlSwitcher -{ - /** - * The widget that is used to show the active <code>Control</code>. - */ - private PageBook pageBook; - - /** - * The <code>Transformer</code> used to transform the value into a - * <code>Control</code>. - */ - private Transformer<?, Control> controlTransformer; - - private Label emptyLabel; - - /** - * Creates a new <code>ControlSwitcher</code>. - * - * @param switchHolder The holder of the value that will be used to retrieve - * the right <code>Control</code> when passed to the given transformer - * @param controlTransformer The <code>Transformer</code> used to transform the value into a - * <code>Control</code> - * @param pageBook The <code>PageBook</code> used for switching the <code>Control</code> - */ - public <T> ControlSwitcher(PropertyValueModel<? extends T> switchHolder, - Transformer<T, Control> controlTransformer, - PageBook pageBook) - { - super(); - initialize(switchHolder, controlTransformer, pageBook); - } - - public <T> ControlSwitcher(PropertyValueModel<? extends T> switchHolder, - Control control, - PageBook pageBook) - { - this(switchHolder, buildNullControlTransformer(control), pageBook); - } - - private static <T> Transformer<T, Control> buildNullControlTransformer(Control control) { - return new NullControlTransformer<T>(control); - } - - protected static class NullControlTransformer<T> - extends AbstractTransformer<T, Control> - { - private final Control control; - - protected NullControlTransformer(Control control) { - this.control = control; - } - - @Override - public Control transform_(T model) { - return this.control; - } - } - - private void initialize(PropertyValueModel<?> switchHolder, - Transformer<?, Control> controlTransformer, - PageBook pageBook) - { - this.pageBook = pageBook; - this.controlTransformer = controlTransformer; - - this.emptyLabel = this.buildEmptyLabel(); - - switchHolder.addPropertyChangeListener( - PropertyValueModel.VALUE, - buildPropertyChangeListener() - ); - - switchPages(switchHolder.getValue()); - } - - //Build an empty label to display in the page book when the controlTransformer returns null. - //SWT.SHADOW_NONE makes the line separator not visible - //This is the best we can come up with for an empty page - private Label buildEmptyLabel() { - return new Label(this.pageBook, SWT.SEPARATOR | SWT.SHADOW_NONE | SWT.HORIZONTAL); - } - - private PropertyChangeListener buildPropertyChangeListener() { - return new SWTPropertyChangeListenerWrapper( - buildPropertyChangeListener_() - ); - } - - private PropertyChangeListener buildPropertyChangeListener_() { - return new PropertyChangeListener() { - public void propertyChanged(PropertyChangeEvent e) { - switchPages(e.getNewValue()); - } - }; - } - - /** - * Switches the active page by transforming the given value into its - * corresponding control. - * - * @param value The state passed to the transformer in order to retrieve the - * new control - */ - private void switchPages(Object value) { - if (this.pageBook.isDisposed()) { - return; - } - - // Retrieve the Control for the new value - Control page = transform(value); - - if (page == null) { - //Note: We can't pass in null due to a bug in PageBook - page = this.emptyLabel; - } - this.pageBook.showPage(page); - - // Revalidate the parents in order to update the layout - ControlTools.reflow(this.pageBook); - } - - @SuppressWarnings("unchecked") - private Control transform(Object value) { - return ((Transformer<Object, Control>) this.controlTransformer).transform(value); - } -}
\ No newline at end of file |