Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmoore2011-01-31 16:48:09 -0500
committerkmoore2011-01-31 16:48:09 -0500
commitd573fb171a36de122ae964b913a1a8b6e1c95e7e (patch)
tree33bf57a8bd9f893f51498b332504d19e67e31ee1 /common/tests/org.eclipse.jpt.common.ui.tests
parent750f1789146ac827adb3667026b96a794fdcb875 (diff)
downloadwebtools.dali-d573fb171a36de122ae964b913a1a8b6e1c95e7e.tar.gz
webtools.dali-d573fb171a36de122ae964b913a1a8b6e1c95e7e.tar.xz
webtools.dali-d573fb171a36de122ae964b913a1a8b6e1c95e7e.zip
Phase 1 - refactoring to org.eclipse.jpt.common.*
Diffstat (limited to 'common/tests/org.eclipse.jpt.common.ui.tests')
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/.classpath12
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/.project28
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/META-INF/MANIFEST.MF21
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/build.properties13
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/plugin.properties23
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/JptCommonUiTests.java34
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingLabelProviderUiTest.java602
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingTreeContentProviderUiTest.java563
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/AbstractComboModelAdapterTest.java777
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/ComboModelAdapterTest.java78
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/JptUiSWTTests.java38
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/SpinnerModelAdapterTest.java342
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TableModelAdapterTest.java1201
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TriStateCheckBoxModelAdapterUITest.java319
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlAlignerTest.java803
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlEnablerTest.java85
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlSwitcherTest.java189
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlVisibilityEnablerTest.java85
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/JptUiUtilTests.java44
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledButtonTest.java122
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledControlUpdaterTest.java124
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledLabelTest.java122
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneEnablerTest.java93
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneVisibilityEnablerTest.java93
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/BooleanStateControllerUITest.java278
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/CheckBoxModelBindingUITest.java318
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/DropDownListBoxModelBindingUITest.java664
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/ListBoxModelBindingUITest.java626
-rw-r--r--common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/TextFieldModelBindingUITest.java252
30 files changed, 7957 insertions, 0 deletions
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/.classpath b/common/tests/org.eclipse.jpt.common.ui.tests/.classpath
new file mode 100644
index 0000000000..dfdcc5f10e
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/jpt/common/ui/**"/>
+ <accessrule kind="accessible" pattern="org/eclipse/jpt/utility/**"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/.project b/common/tests/org.eclipse.jpt.common.ui.tests/.project
new file mode 100644
index 0000000000..0e0633e91a
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.jpt.common.ui.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/.settings/org.eclipse.jdt.core.prefs b/common/tests/org.eclipse.jpt.common.ui.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..c07512e2f6
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon Jan 24 14:35:58 EST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/META-INF/MANIFEST.MF b/common/tests/org.eclipse.jpt.common.ui.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..3be249db22
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-SymbolicName: org.eclipse.jpt.common.ui.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle:
+ org.junit;bundle-version="4.3.1",
+ org.eclipse.core.runtime;bundle-version="[3.6.100,4.0.0)",
+ org.eclipse.jface;bundle-version="[3.7.0,4.0.0)",
+ org.eclipse.jpt.utility;bundle-version="[1.6.0,2.0.0)",
+ org.eclipse.jpt.common.ui;bundle-version="[1.0.0,2.0.0)",
+ org.eclipse.ui.forms;bundle-version="[3.5.100,4.0.0)",
+ org.eclipse.ui.workbench;bundle-version="[3.7.0,4.0.0)",
+ org.eclipse.ui.navigator;bundle-version="[3.5.0,4.0.0)"
+Export-Package: org.eclipse.jpt.common.ui.tests,
+ org.eclipse.jpt.common.ui.tests.internal.jface;x-internal:=true,
+ org.eclipse.jpt.common.ui.tests.internal.swt;x-internal:=true,
+ org.eclipse.jpt.common.ui.tests.internal.util;x-internal:=true,
+ org.eclipse.jpt.common.ui.tests.internal.utility.swt;x-internal:=true
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/build.properties b/common/tests/org.eclipse.jpt.common.ui.tests/build.properties
new file mode 100644
index 0000000000..4dce676b59
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/build.properties
@@ -0,0 +1,13 @@
+################################################################################
+# Copyright (c) 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
+################################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/plugin.properties b/common/tests/org.eclipse.jpt.common.ui.tests/plugin.properties
new file mode 100644
index 0000000000..7b81997383
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/plugin.properties
@@ -0,0 +1,23 @@
+################################################################################
+# Copyright (c) 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
+################################################################################
+# ====================================================================
+# To code developer:
+# Do NOT change the properties between this line and the
+# "%%% END OF TRANSLATED PROPERTIES %%%" line.
+# Make a new property name, append to the end of the file and change
+# the code to use the new property.
+# ====================================================================
+
+# ====================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# ====================================================================
+
+pluginName=Dali Java Persistence Tools - Common UI Tests
+providerName=Eclipse Web Tools Platform
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/JptCommonUiTests.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/JptCommonUiTests.java
new file mode 100644
index 0000000000..bb3b72fe07
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/JptCommonUiTests.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.jpt.common.ui.tests.internal.swt.JptUiSWTTests;
+import org.eclipse.jpt.common.ui.tests.internal.util.JptUiUtilTests;
+
+/**
+ * Runs all JPT UI Tests
+ */
+public class JptCommonUiTests {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(JptCommonUiTests.class.getPackage().getName());
+ suite.addTest(JptUiSWTTests.suite());
+ suite.addTest(JptUiUtilTests.suite());
+ return suite;
+ }
+
+ private JptCommonUiTests() {
+ super();
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingLabelProviderUiTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingLabelProviderUiTest.java
new file mode 100644
index 0000000000..737b549ebd
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingLabelProviderUiTest.java
@@ -0,0 +1,602 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.jface;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.jface.AbstractItemLabelProvider;
+import org.eclipse.jpt.common.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.common.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.common.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.common.ui.jface.ItemLabelProvider;
+import org.eclipse.jpt.common.ui.jface.ItemLabelProviderFactory;
+import org.eclipse.jpt.common.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.common.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.NullCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.StaticCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.StaticPropertyValueModel;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class DelegatingLabelProviderUiTest extends ApplicationWindow
+{
+ private TreeViewer tree;
+
+ private WritablePropertyValueModel<Vehicle> selectedVehicle;
+
+
+ public static void main(String[] args) {
+ Window window = new DelegatingLabelProviderUiTest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+
+ private DelegatingLabelProviderUiTest(String[] args) {
+ super(null);
+ this.selectedVehicle = new SimplePropertyValueModel<Vehicle>();
+ }
+
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(400, 400);
+ parent.setLayout(new GridLayout());
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+ mainPanel.setLayout(new GridLayout());
+ buildTreePanel(mainPanel);
+ buildControlPanel(mainPanel);
+ return mainPanel;
+ }
+
+ private void buildTreePanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+ panel.setLayout(new GridLayout());
+
+ Label label = new Label(panel, SWT.NONE);
+ label.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false));
+ label.setText("My Vehicles");
+
+ tree = new TreeViewer(panel, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ tree.getTree().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+ DelegatingContentAndLabelProvider contentAndLabelProvider =
+ new DelegatingTreeContentAndLabelProvider(
+ new VehicleContentProviderFactory(),
+ new VehicleLabelProviderFactory());
+ tree.setContentProvider(contentAndLabelProvider);
+ tree.setLabelProvider(contentAndLabelProvider);
+ tree.setInput(new Root());
+ tree.addSelectionChangedListener(buildTreeSelectionChangedListener());
+ }
+
+ private ISelectionChangedListener buildTreeSelectionChangedListener() {
+ return new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ selectedVehicle.setValue((Vehicle) ((IStructuredSelection) event.getSelection()).getFirstElement());
+ }
+ };
+ }
+
+ private void buildControlPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ panel.setLayout(new GridLayout());
+ buildUpperControlPanel(panel);
+ buildLowerControlPanel(panel);
+ }
+
+ private void buildUpperControlPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ panel.setLayout(new GridLayout(2, true));
+ buildVehicleCombo(panel);
+ buildColorCombo(panel);
+ }
+
+ private void buildVehicleCombo(Composite parent) {
+ final ComboViewer combo = new ComboViewer(parent, SWT.READ_ONLY);
+ combo.getCombo().setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ combo.setContentProvider(new ArrayContentProvider());
+ combo.setLabelProvider(new VehicleTypeLabelProvider());
+ combo.setInput(
+ new VehicleType[] {
+ VehicleType.BICYCLE, VehicleType.CAR,
+ VehicleType.TRUCK, VehicleType.BOAT
+ });
+ combo.getCombo().setEnabled(false);
+ combo.addSelectionChangedListener(
+ new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ selectedVehicle().setVehicleType((VehicleType) ((StructuredSelection) event.getSelection()).getFirstElement());
+ }
+ });
+ selectedVehicle.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ Vehicle vehicle = selectedVehicle();
+ combo.getCombo().setEnabled(vehicle != null);
+ combo.setSelection(new StructuredSelection((vehicle == null) ? null : vehicle.vehicleType()));
+ }
+ });
+ }
+
+ private void buildColorCombo(Composite parent) {
+ final ComboViewer combo = new ComboViewer(parent, SWT.READ_ONLY);
+ combo.getCombo().setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ combo.setContentProvider(new ArrayContentProvider());
+ combo.setLabelProvider(new ColorLabelProvider());
+ combo.setInput(new Color[] {Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN});
+ combo.addSelectionChangedListener(
+ new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ selectedVehicle().setColor((Color) ((StructuredSelection) event.getSelection()).getFirstElement());
+ }
+ });
+ selectedVehicle.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ Vehicle vehicle = selectedVehicle();
+ combo.getCombo().setEnabled(vehicle != null);
+ combo.setSelection(new StructuredSelection((vehicle == null) ? null : vehicle.color()));
+ }
+ });
+ }
+
+ private void buildLowerControlPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ panel.setLayout(new GridLayout(3, false));
+ buildEffectsLabel(panel);
+ buildGreyedCheckBox(panel);
+ buildTranslucentCheckBox(panel);
+ buildActionPanel(panel);
+ }
+
+ private void buildEffectsLabel(Composite parent) {
+ Label label = new Label(parent, SWT.LEFT);
+ label.setText("Color effects: ");
+ label.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false, 3, 1));
+ }
+
+ private void buildGreyedCheckBox(Composite parent) {
+ final Button button = new Button(parent, SWT.CHECK);
+ button.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false));
+ button.setText("greyed");
+ button.setEnabled(false);
+ button.addSelectionListener(
+ new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedVehicle().setGreyed(button.getSelection());
+ }
+ });
+ selectedVehicle.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ Vehicle vehicle = selectedVehicle();
+ button.setEnabled(vehicle != null);
+ button.setSelection(vehicle != null && vehicle.isGreyed());
+ }
+ });
+ }
+
+ private void buildTranslucentCheckBox(Composite parent) {
+ final Button button = new Button(parent, SWT.CHECK);
+ button.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false));
+ button.setText("translucent");
+ button.setEnabled(false);
+ button.addSelectionListener(
+ new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedVehicle().setTranslucent(button.getSelection());
+ }
+ });
+ selectedVehicle.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ Vehicle vehicle = selectedVehicle();
+ button.setEnabled(vehicle != null);
+ button.setSelection(vehicle != null && vehicle.isTranslucent());
+ }
+ });
+ }
+
+ private void buildActionPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.END, GridData.FILL, false, false));
+ panel.setLayout(new GridLayout());
+ buildRefreshTreeACI().fill(panel);
+ }
+
+ private ActionContributionItem buildRefreshTreeACI() {
+ Action action = new Action("Refresh tree", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ refreshTree();
+ }
+ };
+ action.setToolTipText("Refresh the tree's labels");
+ return new ActionContributionItem(action);
+ }
+
+ void refreshTree() {
+ tree.refresh();
+ }
+
+ private Vehicle selectedVehicle() {
+ return selectedVehicle.getValue();
+ }
+
+
+ private static class VehicleTypeLabelProvider extends BaseLabelProvider
+ implements ILabelProvider
+ {
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ public String getText(Object element) {
+ return ((VehicleType) element).description();
+ }
+ }
+
+
+ private static class ColorLabelProvider extends BaseLabelProvider
+ implements ILabelProvider
+ {
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ public String getText(Object element) {
+ return ((Color) element).description();
+ }
+ }
+
+
+ private static class VehicleContentProviderFactory
+ implements TreeItemContentProviderFactory
+ {
+ public TreeItemContentProvider buildItemContentProvider(Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+ if (item instanceof Root) {
+ return new RootContentProvider(
+ (Root) item, (DelegatingTreeContentAndLabelProvider) contentAndLabelProvider);
+ }
+ return new VehicleContentProvider(
+ (Vehicle) item, (DelegatingTreeContentAndLabelProvider) contentAndLabelProvider);
+ }
+ }
+
+
+ private static class RootContentProvider extends AbstractTreeItemContentProvider<Vehicle>
+ {
+ public RootContentProvider(Root item, DelegatingTreeContentAndLabelProvider contentAndLabelProvider) {
+ super(item, contentAndLabelProvider);
+ }
+
+ @Override
+ public Root getModel() {
+ return (Root) super.getModel();
+ }
+
+ @Override
+ public Object getParent() {
+ return null;
+ }
+
+ @Override
+ protected CollectionValueModel<Vehicle> buildChildrenModel() {
+ return new StaticCollectionValueModel<Vehicle>(this.getModel().vehicles());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static class VehicleContentProvider extends AbstractTreeItemContentProvider
+ {
+ public VehicleContentProvider(Vehicle item, DelegatingTreeContentAndLabelProvider contentAndLabelProvider) {
+ super(item, contentAndLabelProvider);
+ }
+
+ @Override
+ public Vehicle getModel() {
+ return (Vehicle) super.getModel();
+ }
+
+ @Override
+ public Object getParent() {
+ return getModel().parent();
+ }
+
+ @Override
+ protected CollectionValueModel buildChildrenModel() {
+ return new NullCollectionValueModel();
+ }
+ }
+
+
+ private static class VehicleLabelProviderFactory
+ implements ItemLabelProviderFactory
+ {
+ public ItemLabelProvider buildItemLabelProvider(Object element, DelegatingContentAndLabelProvider labelProvider) {
+ return new VehicleLabelProvider((Vehicle) element, labelProvider);
+ }
+ }
+
+
+ private static class VehicleLabelProvider extends AbstractItemLabelProvider
+ {
+ public VehicleLabelProvider(Vehicle vehicle, DelegatingContentAndLabelProvider labelProvider) {
+ super(vehicle, labelProvider);
+ }
+
+ @Override
+ protected PropertyValueModel<Image> buildImageModel() {
+ return new PropertyAspectAdapter<Vehicle, Image>(
+ new StaticPropertyValueModel<Vehicle>((Vehicle) model()),
+ Vehicle.COLOR_PROPERTY, Vehicle.GREYED_PROPERTY, Vehicle.TRANSLUCENT_PROPERTY) {
+ @Override
+ protected Image buildValue_() {
+ return subject.image();
+ }
+ };
+ }
+
+ @Override
+ protected PropertyValueModel<String> buildTextModel() {
+ return new PropertyAspectAdapter<Vehicle, String>(
+ new StaticPropertyValueModel<Vehicle>((Vehicle) model()),
+ Vehicle.VEHICLE_TYPE_PROPERTY, Vehicle.COLOR_PROPERTY) {
+ @Override
+ protected String buildValue_() {
+ return subject.color().description() + ' ' + subject.vehicleType().description();
+ }
+ };
+ }
+
+ @Override
+ protected PropertyValueModel<String> buildDescriptionModel() {
+ return buildTextModel();
+ }
+ }
+
+
+ private static abstract class TreeNode extends AbstractModel
+ {
+ private TreeNode parent;
+
+
+ public TreeNode(TreeNode parent) {
+ this.parent = parent;
+ }
+
+
+ public TreeNode parent() {
+ return parent;
+ }
+ }
+
+
+ private static class Root extends TreeNode
+ {
+ protected final Vehicle[] vehicles;
+
+
+ public Root() {
+ super(null);
+ vehicles = new Vehicle[] {
+ new Vehicle(this, VehicleType.BICYCLE, Color.BLUE),
+ new Vehicle(this, VehicleType.CAR, Color.YELLOW),
+ new Vehicle(this, VehicleType.TRUCK, Color.RED),
+ new Vehicle(this, VehicleType.BOAT, Color.GREEN)};
+ }
+
+ public Vehicle[] vehicles() {
+ return vehicles;
+ }
+ }
+
+
+ private static class Vehicle extends TreeNode
+ {
+ private VehicleType vehicleType;
+ public final static String VEHICLE_TYPE_PROPERTY = "vehicleType";
+
+ private Color color;
+ public final static String COLOR_PROPERTY = "color";
+
+ private boolean greyed = false;
+ public final static String GREYED_PROPERTY = "greyed";
+
+ private boolean translucent = false;
+ public final static String TRANSLUCENT_PROPERTY = "translucent";
+
+ private Image image;
+
+
+ public Vehicle(TreeNode parent, VehicleType vehicleType, Color color) {
+ super(parent);
+ this.vehicleType = vehicleType;
+ this.color = color;
+ }
+
+ public VehicleType vehicleType() {
+ return vehicleType;
+ }
+
+ public void setVehicleType(VehicleType newVehicleType) {
+ VehicleType oldVehicleType = vehicleType;
+ vehicleType = newVehicleType;
+ firePropertyChanged(VEHICLE_TYPE_PROPERTY, oldVehicleType, newVehicleType);
+ }
+
+ public Color color() {
+ return color;
+ }
+
+ public void setColor(Color newColor) {
+ Color oldColor = color;
+ color = newColor;
+ firePropertyChanged(COLOR_PROPERTY, oldColor, newColor);
+ }
+
+ public boolean isGreyed() {
+ return greyed;
+ }
+
+ public void setGreyed(boolean newGreyed) {
+ boolean oldGreyed = greyed;
+ greyed = newGreyed;
+ firePropertyChanged(GREYED_PROPERTY, oldGreyed, newGreyed);
+ }
+
+ public boolean isTranslucent() {
+ return translucent;
+ }
+
+ public void setTranslucent(boolean newTranslucent) {
+ boolean oldTranslucent = translucent;
+ translucent = newTranslucent;
+ firePropertyChanged(TRANSLUCENT_PROPERTY, oldTranslucent, newTranslucent);
+ }
+
+ public Image image() {
+ if (image != null) {
+ image.dispose();
+ }
+
+ return ImageFactory.image(color(), greyed, translucent);
+ }
+ }
+
+
+ private static enum VehicleType
+ {
+ BICYCLE("bicycle"),
+ CAR("car"),
+ TRUCK("truck"),
+ BOAT("boat");
+
+ private final String description;
+
+ private VehicleType(String description) {
+ this.description = description;
+ }
+
+ public String description() {
+ return description;
+ }
+
+ @Override
+ public String toString() {
+ return description();
+ }
+ }
+
+
+ private static enum Color
+ {
+ RED("red", new RGB(255, 0, 0)),
+ BLUE("blue", new RGB(0, 0, 255)),
+ YELLOW("yellow", new RGB(255, 255, 0)),
+ GREEN("green", new RGB(0, 255, 0));
+
+ private final String description;
+
+ private final RGB rgb;
+
+ private Color(String description, RGB rgb) {
+ this.description = description;
+ this.rgb = rgb;
+ }
+
+ public String description() {
+ return description;
+ }
+
+ public RGB rgb() {
+ return rgb;
+ }
+
+ @Override
+ public String toString() {
+ return description();
+ }
+ }
+
+
+ private static class ImageFactory
+ {
+ private static RGB rgb(Color color, boolean greyed, boolean translucent) {
+ RGB rgb = (greyed) ? new RGB(127, 127, 127) : color.rgb();
+ if (translucent) {
+ rgb = new RGB(translucify(rgb.red), translucify(rgb.green), translucify(rgb.blue));
+ }
+ return rgb;
+ }
+
+ private static int translucify(int color) {
+ return 255 - (int) ((255 - color) * 0.3);
+ }
+
+ public static Image image(Color color, boolean greyed, boolean translucent) {
+ PaletteData pd = new PaletteData(new RGB[] {rgb(color, greyed, translucent)});
+ ImageData id = new ImageData(20, 20, 1, pd);
+ for (int x = 0; x < 20; x ++) {
+ for (int y = 0; y < 20; y ++) {
+ id.setPixel(x, y, 0);
+ }
+ }
+ return new Image(Display.getCurrent(), id);
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingTreeContentProviderUiTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingTreeContentProviderUiTest.java
new file mode 100644
index 0000000000..cbd21cf12b
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/jface/DelegatingTreeContentProviderUiTest.java
@@ -0,0 +1,563 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.jface;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.jface.AbstractTreeItemContentProvider;
+import org.eclipse.jpt.common.ui.internal.jface.DelegatingTreeContentAndLabelProvider;
+import org.eclipse.jpt.common.ui.jface.DelegatingContentAndLabelProvider;
+import org.eclipse.jpt.common.ui.jface.TreeItemContentProvider;
+import org.eclipse.jpt.common.ui.jface.TreeItemContentProviderFactory;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.NotNullFilter;
+import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
+import org.eclipse.jpt.utility.internal.iterators.ReadOnlyListIterator;
+import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.CompositeCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.StaticCollectionValueModel;
+import org.eclipse.jpt.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+@SuppressWarnings("nls")
+public class DelegatingTreeContentProviderUiTest extends ApplicationWindow
+{
+ private final Root root;
+
+ private WritablePropertyValueModel<TreeNode> selectedNode;
+
+ private TreeViewer controlTree;
+
+ private TreeViewer viewTree;
+
+ private Text nodeNameText;
+
+
+ public static void main(String[] args) {
+ Window window = new DelegatingTreeContentProviderUiTest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private DelegatingTreeContentProviderUiTest(String[] args) {
+ super(null);
+ this.root = new Root();
+ this.root.addChild("Parent_1");
+ this.selectedNode = new SimplePropertyValueModel<TreeNode>(this.root);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(800, 400);
+ parent.setLayout(new GridLayout());
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+ mainPanel.setLayout(new GridLayout());
+ buildTreePanel(mainPanel);
+ buildControlPanel(mainPanel);
+ return mainPanel;
+ }
+
+ private void buildTreePanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+ panel.setLayout(new GridLayout(2, true));
+ buildControlTreePanel(panel);
+ buildViewTreePanel(panel);
+ }
+
+ private void buildControlTreePanel(Composite parent) {
+ controlTree = buildTreePanel(
+ parent, "Control tree",
+ new DelegatingTreeContentAndLabelProvider(new ControlTreeItemContentProviderFactory()),
+ new LabelProvider());
+ controlTree.addSelectionChangedListener(buildTreeSelectionChangedListener());
+ selectedNode.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ controlTree.setSelection(new StructuredSelection(event.getNewValue()));
+ }
+ }
+ );
+ }
+
+ private void buildViewTreePanel(Composite parent) {
+ viewTree = buildTreePanel(
+ parent, "View tree",
+ new DelegatingTreeContentAndLabelProvider(new ViewTreeItemContentProviderFactory()),
+ new LabelProvider());
+ }
+
+ private TreeViewer buildTreePanel(Composite parent, String labelText, ITreeContentProvider contentProvider, ILabelProvider labelProvider) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+ panel.setLayout(new GridLayout());
+
+ Label label = new Label(panel, SWT.LEFT);
+ label.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false));
+ label.setText(labelText);
+
+ final TreeViewer tree = new TreeViewer(panel, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ tree.getTree().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+ tree.setContentProvider(contentProvider);
+ tree.setLabelProvider(labelProvider);
+ tree.setInput(root);
+
+ return tree;
+ }
+
+ private ISelectionChangedListener buildTreeSelectionChangedListener() {
+ return new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ TreeNode selection = (TreeNode) ((IStructuredSelection) event.getSelection()).getFirstElement();
+ selectedNode.setValue((selection == null) ? root : selection);
+ }
+ };
+ }
+
+ private void buildControlPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+ panel.setLayout(new GridLayout(6, false));
+ buildNodeNameText(panel);
+ buildAddChildACI().fill(panel);
+ buildAddNestedChildACI().fill(panel);
+ buildRemoveACI().fill(panel);
+ buildClearModelACI().fill(panel);
+ buildRestoreModelACI().fill(panel);
+ }
+
+ private void buildNodeNameText(Composite parent) {
+ nodeNameText = new Text(parent, SWT.SINGLE | SWT.BORDER);
+ nodeNameText.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ }
+
+ private ActionContributionItem buildAddChildACI() {
+ final Action action = new Action("Add child", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ addChild();
+ }
+ };
+ action.setToolTipText("Add a child with the given name");
+ selectedNode.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ action.setEnabled(((TreeNode) event.getNewValue()).canHaveChildren());
+ }
+ }
+ );
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildAddNestedChildACI() {
+ final Action action = new Action("Add nested child", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ addNestedChild();
+ }
+ };
+ action.setToolTipText("Add a nested child with the given name");
+ action.setEnabled(false);
+ selectedNode.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ action.setEnabled(((TreeNode) event.getNewValue()).canHaveNestedChildren());
+ }
+ }
+ );
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildRemoveACI() {
+ final Action action = new Action("Remove", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ remove();
+ }
+ };
+ action.setToolTipText("Remove the selected node");
+ action.setEnabled(false);
+ selectedNode.addPropertyChangeListener(
+ PropertyValueModel.VALUE,
+ new PropertyChangeListener() {
+ public void propertyChanged(PropertyChangeEvent event) {
+ action.setEnabled(event.getNewValue() != root);
+ }
+ }
+ );
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildClearModelACI() {
+ Action action = new Action("Clear model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ clearModel();
+ }
+ };
+ action.setToolTipText("Clear the model");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildRestoreModelACI() {
+ Action action = new Action("Restore model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ restoreModel();
+ }
+ };
+ action.setToolTipText("Restore the model");
+ return new ActionContributionItem(action);
+ }
+
+ void addChild() {
+ String nodeName = nodeNameText.getText();
+ if (nodeName.length() != 0) {
+ selectedNode.getValue().addChild(nodeName);
+ }
+ }
+
+ void addNestedChild() {
+ String nodeName = nodeNameText.getText();
+ if (nodeName.length() != 0) {
+ selectedNode.getValue().addNestedChild(nodeName);
+ }
+ }
+
+ void remove() {
+ TreeNode node = selectedNode.getValue();
+ node.parent().removeChild(node);
+ }
+
+ void clearModel() {
+ controlTree.setInput(null);
+ viewTree.setInput(null);
+ }
+
+ void restoreModel() {
+ controlTree.setInput(root);
+ viewTree.setInput(root);
+ }
+
+
+ static abstract class AbstractTreeItemContentProviderFactory
+ implements TreeItemContentProviderFactory
+ {
+ public TreeItemContentProvider buildItemContentProvider(
+ Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+ return new GenericTreeItemContentProvider(
+ (TreeNode) item, (DelegatingTreeContentAndLabelProvider) contentAndLabelProvider);
+ }
+ }
+
+
+ static class ControlTreeItemContentProviderFactory extends AbstractTreeItemContentProviderFactory
+ {
+
+ }
+
+
+ static class ViewTreeItemContentProviderFactory
+ extends AbstractTreeItemContentProviderFactory
+ {
+ @Override
+ public TreeItemContentProvider buildItemContentProvider(
+ Object item, DelegatingContentAndLabelProvider contentAndLabelProvider) {
+ if (item instanceof Parent) {
+ return new ViewTreeParentItemContentProvider(
+ (Parent) item, (DelegatingTreeContentAndLabelProvider) contentAndLabelProvider);
+ }
+ return super.buildItemContentProvider(item, contentAndLabelProvider);
+ }
+ }
+
+
+ static class GenericTreeItemContentProvider extends AbstractTreeItemContentProvider<TreeNode>
+ {
+ public GenericTreeItemContentProvider(
+ TreeNode treeNode, DelegatingTreeContentAndLabelProvider treeContentAndLabelProvider) {
+ super(treeNode, treeContentAndLabelProvider);
+ }
+
+ protected TreeNode treeNode() {
+ return (TreeNode) getModel();
+ }
+
+ @Override
+ public TreeNode getParent() {
+ return treeNode().parent();
+ }
+
+ @Override
+ protected CollectionValueModel<TreeNode> buildChildrenModel() {
+ return new ListCollectionValueModelAdapter<TreeNode>(
+ new ListAspectAdapter<TreeNode, TreeNode>(TreeNode.CHILDREN_LIST, treeNode()) {
+ @Override
+ protected ListIterator<TreeNode> listIterator_() {
+ return treeNode().children();
+ }
+ });
+ }
+ }
+
+ static class ViewTreeParentItemContentProvider extends GenericTreeItemContentProvider
+ {
+ public ViewTreeParentItemContentProvider(
+ TreeNode treeNode, DelegatingTreeContentAndLabelProvider treeContentAndLabelProvider) {
+ super(treeNode, treeContentAndLabelProvider);
+ }
+
+ @Override
+ public TreeNode getParent() {
+ TreeNode parent = super.getParent();
+ if (parent instanceof Nest) {
+ parent = parent.parent();
+ }
+ return parent;
+ }
+
+ @Override
+ protected CollectionValueModel<TreeNode> buildChildrenModel() {
+ return new CompositeCollectionValueModel<TreeNode, TreeNode>(super.buildChildrenModel()) {
+ @Override
+ protected CollectionValueModel<TreeNode> transform(TreeNode value) {
+ if (value instanceof Nest) {
+ final Nest nest = (Nest) value;
+ return new ListCollectionValueModelAdapter<TreeNode>(
+ new ListAspectAdapter<TreeNode, TreeNode>(TreeNode.CHILDREN_LIST, nest) {
+ @Override
+ protected ListIterator<TreeNode> listIterator_() {
+ return nest.children();
+ }
+ }
+ );
+ }
+ return new StaticCollectionValueModel<TreeNode>(CollectionTools.collection(value));
+ }
+ };
+ }
+ }
+
+
+ static class LabelProvider extends BaseLabelProvider
+ implements ILabelProvider
+ {
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ public String getText(Object element) {
+ return ((TreeNode) element).getName();
+ }
+ }
+
+
+ static abstract class TreeNode extends AbstractModel
+ {
+ private TreeNode parent;
+
+ protected final List<TreeNode> children;
+ public final static String CHILDREN_LIST = "children";
+
+ protected String name;
+ public final static String NAME_PROPERTY = "name";
+
+
+ public TreeNode(TreeNode parent, String name) {
+ this.parent = parent;
+ this.children = new ArrayList<TreeNode>();
+ this.name = name;
+ }
+
+ public TreeNode parent() {
+ return parent;
+ }
+
+ public ListIterator<TreeNode> children() {
+ return new ReadOnlyListIterator<TreeNode>(children);
+ }
+
+ protected void addChild(TreeNode child) {
+ addItemToList(child, children, CHILDREN_LIST);
+ }
+
+ public void removeChild(TreeNode child) {
+ removeItemFromList(child, children, CHILDREN_LIST);
+ }
+
+ public void removeChild(int index) {
+ removeItemFromList(index, children, CHILDREN_LIST);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String newName) {
+ String oldName = name;
+ name = newName;
+ firePropertyChanged(NAME_PROPERTY, oldName, newName);
+ }
+
+ public boolean canHaveChildren() {
+ return false;
+ }
+
+ public void addChild(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean canHaveNestedChildren() {
+ return false;
+ }
+
+ public void addNestedChild(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void toString(StringBuilder sb) {
+ sb.append(getName());
+ }
+ }
+
+
+ static class Root extends TreeNode
+ {
+ public Root() {
+ super(null, null);
+ }
+
+ @Override
+ public boolean canHaveChildren() {
+ return true;
+ }
+
+ @Override
+ public void addChild(String name) {
+ addChild(new Parent(this, name));
+ }
+ }
+
+
+ static class Parent extends TreeNode
+ {
+ public Parent(TreeNode parent, String name) {
+ super(parent, name);
+ }
+
+ @Override
+ public boolean canHaveChildren() {
+ return true;
+ }
+
+ @Override
+ public void addChild(String name) {
+ addChild(new Child(this, name));
+ }
+
+ @Override
+ public boolean canHaveNestedChildren() {
+ return true;
+ }
+
+ @Override
+ public void addNestedChild(String name) {
+ TreeNode nest = new Nest(this);
+ addChild(nest);
+ nest.addChild(name);
+ }
+
+ public Iterator<Child> nestlessChildren() {
+ return new FilteringIterator<Child>(
+ new TransformationIterator<TreeNode, Child>(children()) {
+ @Override
+ protected Child transform(TreeNode next) {
+ if (next instanceof Nest) {
+ return ((Nest) next).child();
+ }
+ return (Child) next;
+ }
+ },
+ NotNullFilter.<Child>instance()
+ );
+ }
+ }
+
+
+ static class Nest extends TreeNode
+ {
+ public Nest(TreeNode parent) {
+ super(parent, "nest");
+ }
+
+ @Override
+ public boolean canHaveChildren() {
+ return children.size() == 0;
+ }
+
+ @Override
+ public void addChild(String name) {
+ addChild(new Child(this, name));
+ }
+
+ /* can only have one child */
+ public Child child() {
+ return (children.isEmpty()) ? null : (Child) children.get(0);
+ }
+ }
+
+
+ static class Child extends TreeNode
+ {
+ public Child(TreeNode parent, String name) {
+ super(parent, name);
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/AbstractComboModelAdapterTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/AbstractComboModelAdapterTest.java
new file mode 100644
index 0000000000..d77566bf7a
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/AbstractComboModelAdapterTest.java
@@ -0,0 +1,777 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.swt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jpt.common.ui.internal.swt.AbstractComboModelAdapter;
+import org.eclipse.jpt.common.ui.internal.swt.AbstractComboModelAdapter.SelectionChangeEvent;
+import org.eclipse.jpt.common.ui.internal.swt.AbstractComboModelAdapter.SelectionChangeListener;
+import org.eclipse.jpt.utility.internal.StringConverter;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.swing.SimpleDisplayable;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public abstract class AbstractComboModelAdapterTest {
+
+ private Model model;
+ private WritablePropertyValueModel<SimpleDisplayable> selectedItemHolder;
+ private Shell shell;
+ private WritablePropertyValueModel<Model> subjectHolder;
+
+ protected abstract AbstractComboModelAdapter<SimpleDisplayable> buildEditableComboModelAdapter();
+
+ protected final ListValueModel<SimpleDisplayable> buildEmptyListHolder() {
+ return new SimpleListValueModel<SimpleDisplayable>();
+ }
+
+ private List<SimpleDisplayable> buildList() {
+ List<SimpleDisplayable> list = new ArrayList<SimpleDisplayable>();
+ populateCollection(list);
+ return list;
+ }
+
+ protected final ListValueModel<SimpleDisplayable> buildListHolder() {
+ return new ListAspectAdapter<Model, SimpleDisplayable>(subjectHolder, Model.ITEMS_LIST) {
+ @Override
+ protected ListIterator<SimpleDisplayable> listIterator_() {
+ return subject.items();
+ }
+
+ @Override
+ protected int size_() {
+ return subject.itemsSize();
+ }
+ };
+ }
+
+ protected abstract AbstractComboModelAdapter<SimpleDisplayable> buildReadOnlyComboModelAdapter();
+
+ private SimpleDisplayable buildSelectedItem() {
+ return new SimpleDisplayable("baz");
+ }
+
+ private WritablePropertyValueModel<SimpleDisplayable> buildSelectedItemHolder() {
+ return new PropertyAspectAdapter<Model, SimpleDisplayable>(subjectHolder, Model.ITEM_PROPERTY) {
+ @Override
+ protected SimpleDisplayable buildValue_() {
+ return subject.getItem();
+ }
+
+ @Override
+ protected void setValue_(SimpleDisplayable value) {
+ subject.setItem(value);
+ }
+ };
+ }
+
+ protected final StringConverter<SimpleDisplayable> buildStringConverter() {
+ return new StringConverter<SimpleDisplayable>() {
+ public String convertToString(SimpleDisplayable value) {
+ return (value == null) ? "" : value.displayString();
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Model> buildSubjectHolder() {
+ return new SimplePropertyValueModel<Model>();
+ }
+
+ public abstract String comboSelectedItem();
+
+ protected abstract boolean emptyComboCanHaveSelectedValue();
+
+ protected abstract String itemAt(int index);
+
+ protected abstract int itemCounts();
+
+ private void populateCollection(Collection<SimpleDisplayable> c) {
+ c.add(new SimpleDisplayable("foo"));
+ c.add(new SimpleDisplayable("bar"));
+ c.add(new SimpleDisplayable("baz"));
+ c.add(new SimpleDisplayable("joo"));
+ c.add(new SimpleDisplayable("jar"));
+ c.add(new SimpleDisplayable("jaz"));
+ }
+
+ protected final WritablePropertyValueModel<SimpleDisplayable> selectedItemHolder() {
+ return selectedItemHolder;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+
+ shell = new Shell(Display.getCurrent());
+ model = new Model();
+ subjectHolder = buildSubjectHolder();
+ selectedItemHolder = buildSelectedItemHolder();
+ }
+
+ protected final Shell shell() {
+ return shell;
+ }
+
+ protected final WritablePropertyValueModel<Model> subjectHolder() {
+ return subjectHolder;
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ if (!shell.isDisposed()) {
+ shell.dispose();
+ }
+
+ shell = null;
+ subjectHolder = null;
+ selectedItemHolder = null;
+ }
+
+ private void testItems() {
+
+ assertEquals(
+ "The count of items is not in sync with the model",
+ model.itemsSize(),
+ itemCounts()
+ );
+
+ for (int index = 0; index < model.itemsSize(); index++) {
+ assertEquals(
+ "The item at index " + index + " is not the same between the model and the combo",
+ model.itemAt(index).displayString(),
+ itemAt(index)
+ );
+ }
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_AddedAfter_ReadOnly() throws Exception {
+
+ buildReadOnlyComboModelAdapter();
+ testRemoveItems_AddedAfter();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_AddedAfter_RemoveItems_Editable() throws Exception {
+
+ buildEditableComboModelAdapter();
+ testRemoveItems_AddedAfter();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_AddedBefore_RemoveItems_Editable() throws Exception {
+
+ subjectHolder.setValue(model);
+ model.addItems(buildList());
+
+ buildEditableComboModelAdapter();
+ testSelectedItem(null);
+ testItems();
+
+ ArrayList<SimpleDisplayable> items = new ArrayList<SimpleDisplayable>();
+ items.add(model.itemAt(0));
+ items.add(model.itemAt(3));
+ model.removeItems(items.iterator());
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_AddedBefore_RemoveItems_ReadOnly() throws Exception {
+
+ subjectHolder.setValue(model);
+ model.addItems(buildList());
+
+ buildReadOnlyComboModelAdapter();
+ testSelectedItem(null);
+ testItems();
+
+ ArrayList<SimpleDisplayable> items = new ArrayList<SimpleDisplayable>();
+ items.add(model.itemAt(0));
+ items.add(model.itemAt(3));
+ model.removeItems(items.iterator());
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_ItemsAfterAfter_Editable() throws Exception {
+
+ buildEditableComboModelAdapter();
+
+ subjectHolder.setValue(model);
+ model.addItems(buildList());
+
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_ItemsAfterAfter_ReadOnly() throws Exception {
+
+ buildReadOnlyComboModelAdapter();
+
+ subjectHolder.setValue(model);
+ model.addItems(buildList());
+
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_ItemsAfterBefore_Editable() throws Exception {
+
+ buildEditableComboModelAdapter();
+
+ model.addItems(buildList());
+ subjectHolder.setValue(model);
+
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_ItemsAfterBefore_ReadOnly() throws Exception {
+
+ buildReadOnlyComboModelAdapter();
+
+ model.addItems(buildList());
+ subjectHolder.setValue(model);
+
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_ItemsBefore_Editable() throws Exception {
+
+ model.addItems(buildList());
+ buildEditableComboModelAdapter();
+
+ subjectHolder.setValue(model);
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_ItemsBefore_ReadOnly() throws Exception {
+
+ model.addItems(buildList());
+ buildReadOnlyComboModelAdapter();
+
+ subjectHolder.setValue(model);
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_NoItems_Editable() throws Exception {
+
+ buildEditableComboModelAdapter();
+
+ subjectHolder.setValue(model);
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_NullSelectedItem_NoItems_ReadOnly() throws Exception {
+
+ buildReadOnlyComboModelAdapter();
+
+ subjectHolder.setValue(model);
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectAfter_SelectedItemChanged_ReadOnly() throws Exception {
+
+ subjectHolder.setValue(model);
+ model.addItems(buildList());
+
+ SimpleDisplayable selectedItem = model.itemAt(0);
+
+ AbstractComboModelAdapter<SimpleDisplayable> adapter = buildEditableComboModelAdapter();
+ SelectionListener selectionListener = new SelectionListener();
+ adapter.addSelectionChangeListener(selectionListener);
+
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+ testSelectedItem(null);
+
+ testSelectedItemChanged(selectedItem, selectionListener);
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemAfter_Editable() throws Exception {
+
+ SimpleDisplayable selectedItem = buildSelectedItem();
+ subjectHolder.setValue(model);
+
+ buildEditableComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemAfter_Items_Editable() throws Exception {
+
+ SimpleDisplayable selectedItem = buildSelectedItem();
+ subjectHolder.setValue(model);
+
+ buildEditableComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemAfter_Items_ReadOnly() throws Exception {
+
+ List<SimpleDisplayable> list = buildList();
+ SimpleDisplayable selectedItem = list.get(0);
+ subjectHolder.setValue(model);
+
+ buildReadOnlyComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemAfter_ReadOnly() throws Exception {
+
+ List<SimpleDisplayable> list = buildList();
+ SimpleDisplayable selectedItem = list.get(0);
+ subjectHolder.setValue(model);
+
+ buildReadOnlyComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemBefore_Editable() throws Exception {
+
+ model.addItems(buildList());
+ SimpleDisplayable selectedItem = model.itemAt(0);
+ subjectHolder.setValue(model);
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ model.clearItemCalledFlag();
+ buildEditableComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemBefore_Items_Editable() throws Exception {
+
+ model.addItems(buildList());
+ SimpleDisplayable selectedItem = model.itemAt(0);
+ subjectHolder.setValue(model);
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ model.clearItemCalledFlag();
+ buildEditableComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemBefore_Items_ReadOnly() throws Exception {
+
+ List<SimpleDisplayable> list = buildList();
+ SimpleDisplayable selectedItem = list.get(0);
+ subjectHolder.setValue(model);
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ model.clearItemCalledFlag();
+ buildReadOnlyComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NonNullSelectedItemBefore_ReadOnly() throws Exception {
+
+ List<SimpleDisplayable> list = buildList();
+ SimpleDisplayable selectedItem = list.get(0);
+ subjectHolder.setValue(model);
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+
+ model.clearItemCalledFlag();
+ buildReadOnlyComboModelAdapter();
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+
+ testSelectedItem(selectedItem);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NullSelectedItem_Items_Editable() throws Exception {
+
+ subjectHolder.setValue(model);
+
+ buildEditableComboModelAdapter();
+
+ assertFalse("The item wasn't supposed to be modified", model.isSetItemCalled());
+ assertNull("The selected item is supposed to remain null", model.getItem());
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NullSelectedItem_Items_ReadOnly() throws Exception {
+
+ subjectHolder.setValue(model);
+
+ buildEditableComboModelAdapter();
+
+ assertFalse("The item wasn't supposed to be modified", model.isSetItemCalled());
+ assertNull("The selected item is supposed to remain null", model.getItem());
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NullSelectedItem_NoItems_Editable() throws Exception {
+
+ subjectHolder.setValue(model);
+
+ buildEditableComboModelAdapter();
+
+ assertFalse("The item wasn't supposed to be modified", model.isSetItemCalled());
+ assertNull("The selected item is supposed to remain null", model.getItem());
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_NullSelectedItem_NoItems_ReadOnly() throws Exception {
+
+ subjectHolder.setValue(model);
+
+ buildEditableComboModelAdapter();
+
+ assertFalse("The item wasn't supposed to be modified", model.isSetItemCalled());
+ assertNull("The selected item is supposed to remain null", model.getItem());
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNonNullSubjectBefore_SelectedItemChanged_Editable() throws Exception {
+
+ model.addItems(buildList());
+
+ SimpleDisplayable selectedItem = model.itemAt(3);
+ subjectHolder.setValue(model);
+
+ AbstractComboModelAdapter<SimpleDisplayable> adapter = buildEditableComboModelAdapter();
+ SelectionListener selectionListener = new SelectionListener();
+ adapter.addSelectionChangeListener(selectionListener);
+
+ assertFalse("The selected item wasn't supposed to be modified", model.isSetItemCalled());
+ testSelectedItem(null);
+
+ testSelectedItemChanged(selectedItem, selectionListener);
+ }
+
+ private void testNullSubject() throws Exception {
+
+ assertNull("The selected item should be null", selectedItemHolder.getValue());
+
+ selectedItemHolder.setValue(buildSelectedItem());
+ assertFalse("The item wasn't supposed to be modified", model.isSetItemCalled());
+
+ // Null because the subject holder doesn't have the subject set
+ testSelectedItem(null);
+ testItems();
+ }
+
+ @Test
+ public void testNullSubject_NullSelectedItem_Items_Editable() throws Exception {
+ buildEditableComboModelAdapter();
+ testNullSubject();
+ testItems();
+ testSelectedItem(null);
+ }
+
+ @Test
+ public void testNullSubject_NullSelectedItem_Items_ReadOnly() throws Exception {
+ buildReadOnlyComboModelAdapter();
+ testNullSubject();
+ testItems();
+ testSelectedItem(null);
+ }
+
+ @Test
+ public void testNullSubject_NullSelectedItem_NoItems_Editable() throws Exception {
+ buildEditableComboModelAdapter();
+ testNullSubject();
+ testItems();
+ testSelectedItem(null);
+ }
+
+ @Test
+ public void testNullSubject_NullSelectedItem_NoItems_ReadOnly() throws Exception {
+ buildReadOnlyComboModelAdapter();
+ testNullSubject();
+ testItems();
+ testSelectedItem(null);
+ }
+
+ private void testRemoveItems_AddedAfter() {
+
+ subjectHolder.setValue(model);
+ model.addItems(buildList());
+
+ testSelectedItem(null);
+ testItems();
+ testSelectedItem(null);
+
+ ArrayList<SimpleDisplayable> items = new ArrayList<SimpleDisplayable>();
+ items.add(model.itemAt(0));
+ items.add(model.itemAt(3));
+ model.removeItems(items.iterator());
+
+ testItems();
+ testSelectedItem(null);
+ }
+
+ private void testSelectedItem(SimpleDisplayable selectedItem) {
+
+ if (selectedItem == null) {
+
+ assertNull(
+ "The selected item is supposed to be null",
+ model.getItem()
+ );
+
+ assertEquals(
+ "The combo's selected item should be null",
+ "",
+ comboSelectedItem()
+ );
+ }
+ else if (!emptyComboCanHaveSelectedValue()) {
+
+ assertEquals(
+ "The selected item wasn't set correctly",
+ selectedItem,
+ model.getItem()
+ );
+
+ assertEquals(
+ "The combo's selected item should be null",
+ "",
+ comboSelectedItem()
+ );
+ }
+ else {
+
+ assertEquals(
+ "The selected item wasn't set correctly",
+ selectedItem,
+ model.getItem()
+ );
+
+ assertEquals(
+ "The selected item wasn't set correctly",
+ selectedItem.displayString(),
+ comboSelectedItem()
+ );
+ }
+ }
+
+ private void testSelectedItemChanged(SimpleDisplayable selectedItem,
+ SelectionListener selectionListener) {
+
+ // Test 1
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+ assertTrue("The SelectionListener was supposed to be notified", selectionListener.isListenerNotified());
+ assertSame("The SelectionListener was supposed to be notified", selectedItem, selectionListener.getItem());
+ testSelectedItem(selectedItem);
+
+ // Test 2
+ selectedItem = model.itemAt(1);
+ model.clearItemCalledFlag();
+ selectionListener.clearInfo();
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+ assertTrue("The SelectionListener was supposed to be notified", selectionListener.isListenerNotified());
+ assertSame("The SelectionListener was supposed to be notified", selectedItem, selectionListener.getItem());
+ testSelectedItem(selectedItem);
+
+ // Test 3
+ selectedItem = null;
+ model.clearItemCalledFlag();
+ selectionListener.clearInfo();
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertNull("The selected item wasn't set properly", model.getItem());
+ assertTrue("The SelectionListener was supposed to be notified", selectionListener.isListenerNotified());
+ assertSame("The SelectionListener was supposed to be notified", selectedItem, selectionListener.getItem());
+ testSelectedItem(selectedItem);
+
+ // Test 3
+ selectedItem = model.itemAt(2);
+ model.clearItemCalledFlag();
+ selectionListener.clearInfo();
+
+ model.setItem(selectedItem);
+ assertTrue("The selected item was supposed to be modified", model.isSetItemCalled());
+ assertSame("The selected item wasn't set properly", selectedItem, model.getItem());
+ assertTrue("The SelectionListener was supposed to be notified", selectionListener.isListenerNotified());
+ assertSame("The SelectionListener was supposed to be notified", selectedItem, selectionListener.getItem());
+ testSelectedItem(selectedItem);
+ }
+
+ private static class Model extends AbstractModel {
+
+ private SimpleDisplayable item;
+ private List<SimpleDisplayable> items = new ArrayList<SimpleDisplayable>();
+ private boolean setItemCalled;
+
+ static final String ITEM_PROPERTY = "item";
+ static final String ITEMS_LIST = "items";
+
+ void addItems(Iterator<SimpleDisplayable> items) {
+ addItemsToList(items, this.items, ITEMS_LIST);
+ }
+
+ void addItems(List<SimpleDisplayable> items) {
+ addItemsToList(items, this.items, ITEMS_LIST);
+ }
+
+ void clearItemCalledFlag() {
+ setItemCalled = false;
+ }
+
+ SimpleDisplayable getItem() {
+ return item;
+ }
+
+ boolean isSetItemCalled() {
+ return setItemCalled;
+ }
+
+ SimpleDisplayable itemAt(int index) {
+ return this.items.get(index);
+ }
+
+ ListIterator<SimpleDisplayable> items() {
+ return items.listIterator();
+ }
+
+ int itemsSize() {
+ return items.size();
+ }
+
+ void removeItems(Iterator<SimpleDisplayable> items) {
+ removeItemsFromList(items, this.items, ITEMS_LIST);
+ }
+
+ void setItem(SimpleDisplayable item) {
+ setItemCalled = true;
+
+ SimpleDisplayable oldItem = this.item;
+ this.item = item;
+ firePropertyChanged(ITEM_PROPERTY, oldItem, item);
+ }
+ }
+
+ private class SelectionListener implements SelectionChangeListener<SimpleDisplayable> {
+
+ private SimpleDisplayable item;
+ private boolean listenerNotified;
+
+ void clearInfo() {
+ this.listenerNotified = false;
+ this.item = null;
+ }
+
+ SimpleDisplayable getItem() {
+ return item;
+ }
+
+ public boolean isListenerNotified() {
+ return listenerNotified;
+ }
+
+ public void selectionChanged(SelectionChangeEvent<SimpleDisplayable> e) {
+ listenerNotified = true;
+ item = e.selectedItem();
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/ComboModelAdapterTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/ComboModelAdapterTest.java
new file mode 100644
index 0000000000..5c855ef705
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/ComboModelAdapterTest.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.swt;
+
+import org.eclipse.jpt.common.ui.internal.swt.AbstractComboModelAdapter;
+import org.eclipse.jpt.common.ui.internal.swt.ComboModelAdapter;
+import org.eclipse.jpt.utility.internal.swing.SimpleDisplayable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Combo;
+import org.junit.After;
+
+public class ComboModelAdapterTest extends AbstractComboModelAdapterTest {
+
+ private Combo combo;
+ private boolean editable;
+
+ @Override
+ protected AbstractComboModelAdapter<SimpleDisplayable> buildEditableComboModelAdapter() {
+
+ combo = new Combo(shell(), SWT.NULL);
+ editable = true;
+
+ return ComboModelAdapter.adapt(
+ buildListHolder(),
+ selectedItemHolder(),
+ combo,
+ buildStringConverter()
+ );
+ }
+
+ @Override
+ protected AbstractComboModelAdapter<SimpleDisplayable> buildReadOnlyComboModelAdapter() {
+
+ combo = new Combo(shell(), SWT.READ_ONLY);
+ editable = false;
+
+ return ComboModelAdapter.adapt(
+ buildListHolder(),
+ selectedItemHolder(),
+ combo,
+ buildStringConverter()
+ );
+ }
+
+ @Override
+ public String comboSelectedItem() {
+ return combo.getText();
+ }
+
+ @Override
+ protected boolean emptyComboCanHaveSelectedValue() {
+ return editable;
+ }
+
+ @Override
+ protected String itemAt(int index) {
+ return this.combo.getItem(index);
+ }
+
+ @Override
+ protected int itemCounts() {
+ return combo.getItemCount();
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ combo = null;
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/JptUiSWTTests.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/JptUiSWTTests.java
new file mode 100644
index 0000000000..fb7f5d3d61
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/JptUiSWTTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.swt;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@SuiteClasses
+({
+ ComboModelAdapterTest.class,
+ SpinnerModelAdapterTest.class,
+ TableModelAdapterTest.class
+})
+@RunWith(Suite.class)
+public final class JptUiSWTTests {
+
+ private JptUiSWTTests() {
+ super();
+ throw new UnsupportedOperationException();
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new JUnit4TestAdapter(JptUiSWTTests.class));
+ return suite;
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/SpinnerModelAdapterTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/SpinnerModelAdapterTest.java
new file mode 100644
index 0000000000..11ee14f637
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/SpinnerModelAdapterTest.java
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.swt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import org.eclipse.jpt.common.ui.internal.swt.SpinnerModelAdapter;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Spinner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public class SpinnerModelAdapterTest {
+
+ private Model model;
+ private Shell shell;
+ private WritablePropertyValueModel<Model> subjectHolder;
+
+ private WritablePropertyValueModel<Model> buildSubjectHolder() {
+ return new SimplePropertyValueModel<Model>();
+ }
+
+ private WritablePropertyValueModel<Integer> buildValueHolder() {
+ return new PropertyAspectAdapter<Model, Integer>(subjectHolder, Model.VALUE_PROPERTY) {
+ @Override
+ protected Integer buildValue_() {
+ return subject.getValue();
+ }
+
+ @Override
+ protected void setValue_(Integer value) {
+ subject.setValue(value);
+ }
+ };
+ }
+
+ @Before
+ public void setUp() throws Exception {
+
+ shell = new Shell(Display.getCurrent());
+ model = new Model();
+ subjectHolder = buildSubjectHolder();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ if (!shell.isDisposed()) {
+ shell.dispose();
+ }
+
+ shell = null;
+ subjectHolder = null;
+ }
+
+ @Test
+ public void testDisposed() {
+
+ int value = 2;
+ model.setValue(value);
+ model.clearSetValueCalledFlag();
+ subjectHolder.setValue(model);
+
+ Spinner spinner = new Spinner(shell, SWT.NULL);
+ WritablePropertyValueModel<Integer> numberHolder = buildValueHolder();
+ int defaultValue = 1;
+
+ SpinnerModelAdapter.adapt(
+ numberHolder,
+ spinner,
+ defaultValue
+ );
+
+ assertEquals(
+ "The spinner's value should be coming from the model",
+ value,
+ spinner.getSelection()
+ );
+
+ assertEquals(
+ "The number holder's value should be the model's value",
+ model.getValue(),
+ numberHolder.getValue()
+ );
+
+ assertFalse(
+ "The model should not have received the value during initialization",
+ model.isSetValueCalled()
+ );
+
+ // Change the value in the model
+ spinner.dispose();
+
+ value = 4;
+ model.setValue(value);
+
+ assertEquals(
+ "The model's value was somehow changed",
+ Integer.valueOf(value),
+ model.getValue()
+ );
+ }
+
+ @Test
+ public void testInitialization_1() {
+
+ Spinner spinner = new Spinner(shell, SWT.NULL);
+ WritablePropertyValueModel<Integer> numberHolder = new SimplePropertyValueModel<Integer>();
+ int defaultValue = 1;
+
+ SpinnerModelAdapter.adapt(
+ numberHolder,
+ spinner,
+ defaultValue
+ );
+
+ assertEquals(
+ "The spinner's value should be the default value",
+ defaultValue,
+ spinner.getSelection()
+ );
+
+ assertNull(
+ "The number holder's value should be null",
+ numberHolder.getValue()
+ );
+ }
+
+ @Test
+ public void testInitialization_2() {
+
+ Spinner spinner = new Spinner(shell, SWT.NULL);
+ WritablePropertyValueModel<Integer> numberHolder = buildValueHolder();
+ int defaultValue = 1;
+
+ SpinnerModelAdapter.adapt(
+ numberHolder,
+ spinner,
+ defaultValue
+ );
+
+ assertEquals(
+ "The spinner's value should be the default value",
+ defaultValue,
+ spinner.getSelection()
+ );
+
+ assertNull(
+ "The number holder's value should be null",
+ numberHolder.getValue()
+ );
+ }
+
+ @Test
+ public void testInitialization_3() {
+
+ subjectHolder.setValue(model);
+
+ Spinner spinner = new Spinner(shell, SWT.NULL);
+ WritablePropertyValueModel<Integer> numberHolder = buildValueHolder();
+ int defaultValue = 1;
+
+ SpinnerModelAdapter.adapt(
+ numberHolder,
+ spinner,
+ defaultValue
+ );
+
+ assertEquals(
+ "The spinner's value should be the default value",
+ defaultValue,
+ spinner.getSelection()
+ );
+
+ assertNull(
+ "The number holder's value should be null",
+ numberHolder.getValue()
+ );
+
+ assertFalse(
+ "The model should not have received the value during initialization",
+ model.isSetValueCalled()
+ );
+ }
+
+ @Test
+ public void testInitialization_4() {
+
+ int value = 2;
+ model.setValue(value);
+ model.clearSetValueCalledFlag();
+ subjectHolder.setValue(model);
+
+ Spinner spinner = new Spinner(shell, SWT.NULL);
+ WritablePropertyValueModel<Integer> numberHolder = buildValueHolder();
+ int defaultValue = 1;
+
+ SpinnerModelAdapter.adapt(
+ numberHolder,
+ spinner,
+ defaultValue
+ );
+
+ assertEquals(
+ "The spinner's value should be the value coming from the model",
+ value,
+ spinner.getSelection()
+ );
+
+ assertEquals(
+ "The number holder's value should be " + value,
+ Integer.valueOf(value),
+ numberHolder.getValue()
+ );
+
+ assertFalse(
+ "The model should not have received the value during initialization",
+ model.isSetValueCalled()
+ );
+ }
+
+ @Test
+ public void testValueChanged() {
+
+ int value = 2;
+ model.setValue(value);
+ model.clearSetValueCalledFlag();
+ subjectHolder.setValue(model);
+
+ Spinner spinner = new Spinner(shell, SWT.NULL);
+ WritablePropertyValueModel<Integer> numberHolder = buildValueHolder();
+ int defaultValue = 1;
+
+ SpinnerModelAdapter.adapt(
+ numberHolder,
+ spinner,
+ defaultValue
+ );
+
+ assertEquals(
+ "The spinner's value should be coming from the model",
+ value,
+ spinner.getSelection()
+ );
+
+ assertEquals(
+ "The number holder's value should be the model's value",
+ model.getValue(),
+ numberHolder.getValue()
+ );
+
+ assertFalse(
+ "The model should not have received the value during initialization",
+ model.isSetValueCalled()
+ );
+
+ // Change the value in the model
+ value = 4;
+ model.setValue(value);
+
+ assertEquals(
+ "The spinner's value should be coming from the model",
+ value,
+ spinner.getSelection()
+ );
+
+ assertEquals(
+ "The model's value was somehow changed",
+ Integer.valueOf(value),
+ model.getValue()
+ );
+
+ // Change the value from the spinner
+ value = 6;
+ spinner.setSelection(value);
+
+ assertEquals(
+ "The spinner's value should be the new value set",
+ value,
+ spinner.getSelection()
+ );
+
+ assertEquals(
+ "The model's value was supposed to be updated",
+ Integer.valueOf(value),
+ model.getValue()
+ );
+
+ // Disconnect from model
+ subjectHolder.setValue(null);
+
+ assertEquals(
+ "The spinner's value should be the default value",
+ defaultValue,
+ spinner.getSelection()
+ );
+ }
+
+ private static class Model extends AbstractModel {
+
+ private boolean setValueCalled;
+ private Integer value;
+
+ static final String VALUE_PROPERTY = "value";
+
+ void clearSetValueCalledFlag() {
+ setValueCalled = false;
+ }
+
+ Integer getValue() {
+ return value;
+ }
+
+ boolean isSetValueCalled() {
+ return setValueCalled;
+ }
+
+ void setValue(Integer value) {
+ setValueCalled = true;
+
+ Integer oldValue = this.value;
+ this.value = value;
+ firePropertyChanged(VALUE_PROPERTY, oldValue, value);
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TableModelAdapterTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TableModelAdapterTest.java
new file mode 100644
index 0000000000..7468ce68a7
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TableModelAdapterTest.java
@@ -0,0 +1,1201 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.tests.internal.swt;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jpt.common.ui.internal.swt.ColumnAdapter;
+import org.eclipse.jpt.common.ui.internal.swt.TableModelAdapter;
+import org.eclipse.jpt.common.ui.internal.swt.TableModelAdapter.SelectionChangeEvent;
+import org.eclipse.jpt.common.ui.internal.swt.TableModelAdapter.SelectionChangeListener;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyCollectionValueModelAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public class TableModelAdapterTest {
+
+ private Shell shell;
+ private WritablePropertyValueModel<Manager> subjectHolder;
+
+ private ColumnAdapter<Employee> buildColumnAdapter() {
+ return new TableColumnAdapter();
+ }
+
+ private WritablePropertyValueModel<Employee> buildEmployeeHolder() {
+ return new SimplePropertyValueModel<Employee>();
+ }
+
+ private SimpleCollectionValueModel<Employee> buildEmployeeHolders() {
+ return new SimpleCollectionValueModel<Employee>();
+ }
+
+ private ListValueModel<Employee> buildEmployeeListHolder() {
+ return new ListAspectAdapter<Manager, Employee>(subjectHolder, Manager.EMPLOYEES_LIST) {
+ @Override
+ protected ListIterator<Employee> listIterator_() {
+ return subject.employees();
+ }
+
+ @Override
+ protected int size_() {
+ return subject.employeesSize();
+ }
+ };
+ }
+
+ private ITableLabelProvider buildLabelProvider() {
+ return new TableLabelProvider();
+ }
+
+ private SelectionChangeListener<Employee> buildSelectionChangeListener(final Collection<Employee> employees) {
+ return new SelectionChangeListener<Employee>() {
+ public void selectionChanged(SelectionChangeEvent<Employee> e) {
+ employees.clear();
+ CollectionTools.addAll(employees, e.selection());
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Manager> buildSubjectHolder() {
+ return new SimplePropertyValueModel<Manager>();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+
+ shell = new Shell(Display.getCurrent());
+ subjectHolder = buildSubjectHolder();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ if (!shell.isDisposed()) {
+ shell.dispose();
+ }
+
+ shell = null;
+ subjectHolder = null;
+ }
+
+ @Test
+ public void testChanged() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Make sure the Table was populated
+ Assert.assertEquals("The number of TableItems should be 3", 3, table.getItemCount());
+
+ // Change the list of Employees
+ ArrayList<Employee> employees = new ArrayList<Employee>(3);
+ employees.add(employee3);
+ employees.add(employee2);
+ employees.add(employee1);
+ manager.changeEmployees(employees);
+
+ Assert.assertEquals("The number of TableItems should be 3", 3, table.getItemCount());
+
+ testTableItemProperties(table, 0, expectedName3, expectedManager3, expectedTitle3);
+ testTableItemProperties(table, 1, expectedName2, expectedManager2, expectedTitle2);
+ testTableItemProperties(table, 2, expectedName1, expectedManager1, expectedTitle1);
+ }
+
+ @Test
+ public void testCleared() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Make sure the Table was populated
+ Assert.assertEquals("The number of TableItems should be 3", 3, table.getItemCount());
+
+ // Test removing them all
+ manager.removeAllEmployees();
+
+ Assert.assertEquals("The list holder should have been cleared", 0, listHolder.size());
+ Assert.assertEquals("The Table should have been cleared", 0, table.getItemCount());
+ }
+
+ @Test
+ public void testItemAdded() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create a new Employee
+ String expectedName = "Dali";
+ String expectedManager = "WTP";
+ String expectedTitle = "plug-in";
+
+ Employee employee = manager.addEmployee(expectedName, expectedTitle, expectedManager);
+ Assert.assertNotNull("The new Employee was not created", employee);
+
+ // Retrieve the TableItem representing the new Employee
+ int index = tableModel.indexOf(employee);
+ Assert.assertEquals("The new Employee was not added to the table model", 0, index);
+ Assert.assertEquals("The number of TableItem should be 1", 1, table.getItemCount());
+
+ testTableItemProperties(table, index, expectedName, expectedManager, expectedTitle);
+ }
+
+ @Test
+ public void testItemMoved() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Make sure the Employees were added to the Table
+ Assert.assertEquals("The number of TableItem should be 3", 3, table.getItemCount());
+
+ // Move an Employee up the list
+ manager.moveEmployeeUp(employee2);
+
+ int index1 = tableModel.indexOf(employee1);
+ Assert.assertEquals("The Employee 1 was not moved in the table model", 1, index1);
+
+ int index2 = tableModel.indexOf(employee2);
+ Assert.assertEquals("The Employee 2 was not moved in the table model", 0, index2);
+
+ int index3 = tableModel.indexOf(employee3);
+ Assert.assertEquals("The Employee 3 should not have been moved in the table model", 2, index3);
+
+ testTableItemProperties(table, index1, expectedName1, expectedManager1, expectedTitle1);
+ testTableItemProperties(table, index2, expectedName2, expectedManager2, expectedTitle2);
+ testTableItemProperties(table, index3, expectedName3, expectedManager3, expectedTitle3);
+
+ // Move an Employee down the list
+ manager.moveEmployeeDown(employee1);
+
+ index1 = tableModel.indexOf(employee1);
+ Assert.assertEquals("The Employee 1 should not have been moved in the table model", 2, index1);
+
+ index2 = tableModel.indexOf(employee2);
+ Assert.assertEquals("The Employee 2 was not moved in the table model", 0, index2);
+
+ index3 = tableModel.indexOf(employee3);
+ Assert.assertEquals("The Employee 3 was not moved in the table model", 1, index3);
+
+ testTableItemProperties(table, index1, expectedName1, expectedManager1, expectedTitle1);
+ testTableItemProperties(table, index2, expectedName2, expectedManager2, expectedTitle2);
+ testTableItemProperties(table, index3, expectedName3, expectedManager3, expectedTitle3);
+ }
+
+ @Test
+ public void testItemRemoved() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create a new Employee
+ String expectedName = "Dali";
+ String expectedManager = "WTP";
+ String expectedTitle = "plug-in";
+
+ Employee employee = manager.addEmployee(expectedName, expectedTitle, expectedManager);
+ Assert.assertNotNull("The new Employee was not created", employee);
+ Assert.assertEquals("The number of TableItem should be 1", 1, table.getItemCount());
+
+ // Make sure it was added to the model
+ int index = tableModel.indexOf(employee);
+ Assert.assertEquals("The new Employee was not added to the table model", 0, index);
+ testTableItemProperties(table, index, expectedName, expectedManager, expectedTitle);
+
+ // Retrieve the TableItem representing the new Employee
+ TableItem tableItem = table.getItem(index);
+ Assert.assertNotNull("No TableItem was found for the new Employee", tableItem);
+
+ // Now test the item being removed
+ manager.removeEmployee(employee);
+ index = tableModel.indexOf(employee);
+ Assert.assertEquals("The Employee was not removed from the table model", -1, index);
+ Assert.assertEquals("The number of TableItem should be 0", 0, table.getItemCount());
+ }
+
+ @Test
+ public void testItemReplaced() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create a new Employee
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ Employee employee1 = manager.addEmployee(expectedName1, expectedTitle1, expectedManager1);
+ Assert.assertNotNull("The new Employee was not created", employee1);
+
+ // Make sure it was added to the model
+ int index1 = tableModel.indexOf(employee1);
+ Assert.assertEquals("The new Employee was not added to the table model", 0, index1);
+ Assert.assertEquals("The number of TableItem should be 1", 1, table.getItemCount());
+
+ // Retrieve the TableItem representing the new Employee
+ TableItem tableItem = table.getItem(index1);
+ Assert.assertNotNull("No TableItem was found for the new Employee", tableItem);
+
+ testTableItemProperties(table, index1, expectedName1, expectedManager1, expectedTitle1);
+
+ // Replace the Employee
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ manager.replace(employee1, employee2);
+
+ int index2 = tableModel.indexOf(employee2);
+ Assert.assertSame("The Employee that got replaced should be at index " + index1, index1, index2);
+ Assert.assertEquals("The number of TableItem should be 1", 1, table.getItemCount());
+
+ testTableItemProperties(table, index2, expectedName2, expectedManager2, expectedTitle2);
+ }
+
+ @Test
+ public void testItemsAdded() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Retrieve the TableItems representing the employees
+ Assert.assertEquals("The number of TableItem should be 3", 3, table.getItemCount());
+
+ int index = tableModel.indexOf(employee1);
+ Assert.assertEquals("The Employee 1 was not added to the table model", 0, index);
+
+ index = tableModel.indexOf(employee2);
+ Assert.assertEquals("The Employee 2 was not added to the table model", 1, index);
+
+ index = tableModel.indexOf(employee3);
+ Assert.assertEquals("The Employee 3 was not added to the table model", 2, index);
+
+ // Make sure the TableItem was correctly populated
+ testTableItemProperties(table, 0, expectedName1, expectedManager1, expectedTitle1);
+ testTableItemProperties(table, 1, expectedName2, expectedManager2, expectedTitle2);
+ testTableItemProperties(table, 2, expectedName3, expectedManager3, expectedTitle3);
+ }
+
+ @Test
+ public void testItemsMoved() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ String expectedName4 = "Dali_4";
+ String expectedManager4 = "WTP_4";
+ String expectedTitle4 = "plug-in_4";
+
+ String expectedName5 = "Dali_5";
+ String expectedManager5 = "WTP_5";
+ String expectedTitle5 = "plug-in_5";
+
+ String expectedName6 = "Dali_6";
+ String expectedManager6 = "WTP_6";
+ String expectedTitle6 = "plug-in_6";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+ Employee employee4 = new Employee(expectedName4, expectedTitle4, expectedManager4);
+ Employee employee5 = new Employee(expectedName5, expectedTitle5, expectedManager5);
+ Employee employee6 = new Employee(expectedName6, expectedTitle6, expectedManager6);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+ manager.addEmployee(employee4);
+ manager.addEmployee(employee5);
+ manager.addEmployee(employee6);
+
+ // Make sure the Employees were added to the Table
+ Assert.assertEquals("The number of TableItem should be 6", 6, table.getItemCount());
+
+ // Move an Employee up the list
+ ArrayList<Employee> employees = new ArrayList<Employee>(3);
+ employees.add(employee3);
+ employees.add(employee4);
+ employees.add(employee5);
+ manager.moveEmployees(employees, 0);
+
+ int index1 = tableModel.indexOf(employee1);
+ int index2 = tableModel.indexOf(employee2);
+ int index3 = tableModel.indexOf(employee3);
+ int index4 = tableModel.indexOf(employee4);
+ int index5 = tableModel.indexOf(employee5);
+ int index6 = tableModel.indexOf(employee6);
+
+ Assert.assertEquals("The Employee 1 is not at the right index", 3, index1);
+ Assert.assertEquals("The Employee 2 is not at the right index", 4, index2);
+ Assert.assertEquals("The Employee 3 is not at the right index", 0, index3);
+ Assert.assertEquals("The Employee 4 is not at the right index", 1, index4);
+ Assert.assertEquals("The Employee 5 is not at the right index", 2, index5);
+ Assert.assertEquals("The Employee 6 is not at the right index", 5, index6);
+
+ testTableItemProperties(table, index1, expectedName1, expectedManager1, expectedTitle1);
+ testTableItemProperties(table, index2, expectedName2, expectedManager2, expectedTitle2);
+ testTableItemProperties(table, index3, expectedName3, expectedManager3, expectedTitle3);
+ testTableItemProperties(table, index4, expectedName4, expectedManager4, expectedTitle4);
+ testTableItemProperties(table, index5, expectedName5, expectedManager5, expectedTitle5);
+ testTableItemProperties(table, index6, expectedName6, expectedManager6, expectedTitle6);
+
+ // Move an Employee down the list
+ employees = new ArrayList<Employee>(2);
+ employees.add(employee1);
+ employees.add(employee2);
+ manager.moveEmployees(employees, 4);
+
+ index1 = tableModel.indexOf(employee1);
+ index2 = tableModel.indexOf(employee2);
+ index3 = tableModel.indexOf(employee3);
+ index4 = tableModel.indexOf(employee4);
+ index5 = tableModel.indexOf(employee5);
+ index6 = tableModel.indexOf(employee6);
+
+ Assert.assertEquals("The Employee 1 is not at the right index", 4, index1);
+ Assert.assertEquals("The Employee 2 is not at the right index", 5, index2);
+ Assert.assertEquals("The Employee 3 is not at the right index", 0, index3);
+ Assert.assertEquals("The Employee 4 is not at the right index", 1, index4);
+ Assert.assertEquals("The Employee 5 is not at the right index", 2, index5);
+ Assert.assertEquals("The Employee 6 is not at the right index", 3, index6);
+
+ testTableItemProperties(table, index1, expectedName1, expectedManager1, expectedTitle1);
+ testTableItemProperties(table, index2, expectedName2, expectedManager2, expectedTitle2);
+ testTableItemProperties(table, index3, expectedName3, expectedManager3, expectedTitle3);
+ testTableItemProperties(table, index4, expectedName4, expectedManager4, expectedTitle4);
+ testTableItemProperties(table, index5, expectedName5, expectedManager5, expectedTitle5);
+ testTableItemProperties(table, index6, expectedName6, expectedManager6, expectedTitle6);
+ }
+
+ @Test
+ public void testItemsRemoved() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Retrieve the TableItems representing the employees
+ Assert.assertEquals("The number of TableItem should be 3", 3, table.getItemCount());
+
+ int index = tableModel.indexOf(employee1);
+ Assert.assertEquals("The Employee 1 was not added to the table model", 0, index);
+
+ index = tableModel.indexOf(employee2);
+ Assert.assertEquals("The Employee 2 was not added to the table model", 1, index);
+
+ index = tableModel.indexOf(employee3);
+ Assert.assertEquals("The Employee 3 was not added to the table model", 2, index);
+
+ // Remove 2 items
+ ArrayList<Employee> employees = new ArrayList<Employee>(2);
+ employees.add(employee1);
+ employees.add(employee3);
+ manager.removeEmployees(employees);
+
+ Assert.assertEquals("The number of TableItem should be 1", 1, table.getItemCount());
+ }
+
+ @Test
+ public void testPropertyChanged() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ WritablePropertyValueModel<Employee> selectedItemHolder = buildEmployeeHolder();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create a new Employee
+ String expectedName = "Dali";
+ String expectedManager = "WTP";
+ String expectedTitle = "plug-in";
+
+ Employee employee = manager.addEmployee(expectedName, expectedTitle, expectedManager);
+ Assert.assertNotNull("The new Employee was not created", employee);
+
+ // Make sure it was added to the model
+ int index = tableModel.indexOf(employee);
+ Assert.assertEquals("The new Employee was not added to the table model", 0, index);
+ Assert.assertEquals("The number of TableItem should be 1", 1, table.getItemCount());
+
+ // Retrieve the TableItem representing the new Employee
+ TableItem tableItem = table.getItem(index);
+ Assert.assertNotNull("No TableItem was found for the new Employee", tableItem);
+
+ // Name property
+ String actualName = tableItem.getText(TableColumnAdapter.NAME_COLUMN);
+ Assert.assertEquals("TableItem[NAME_COLUMN] was not set correctly", expectedName, actualName);
+
+ expectedName = "Jpt";
+ employee.setName(expectedName);
+
+ actualName = tableItem.getText(TableColumnAdapter.NAME_COLUMN);
+ Assert.assertEquals("TableItem[NAME_COLUMN] was not set correctly", expectedName, actualName);
+
+ // Manager property
+ String actualManager = tableItem.getText(TableColumnAdapter.MANAGER_COLUMN);
+ Assert.assertEquals("TableItem[MANAGER_COLUMN] was not set correctly", expectedManager, actualManager);
+
+ expectedManager = "boss";
+ employee.setManager(expectedManager);
+
+ actualManager = tableItem.getText(TableColumnAdapter.MANAGER_COLUMN);
+ Assert.assertEquals("TableItem[MANAGER_COLUMN] was not set correctly", expectedManager, actualManager);
+
+ // Title property
+ String actualTitle = tableItem.getText(TableColumnAdapter.TITLE_COLUMN);
+ Assert.assertEquals("TableItem[TITLE_COLUMN] was not set correctly", expectedTitle, actualTitle);
+
+ expectedTitle = "EclipseLink";
+ employee.setTitle(expectedTitle);
+
+ actualTitle = tableItem.getText(TableColumnAdapter.TITLE_COLUMN);
+ Assert.assertEquals("TableItem[TITLE_COLUMN] was not set correctly", expectedTitle, actualTitle);
+ }
+
+ @Test
+ public void testSelectedItemsAddedRemoved() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ SimpleCollectionValueModel<Employee> selectedItemsHolder = buildEmployeeHolders();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemsHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Test adding selected items
+ ArrayList<Employee> employees = new ArrayList<Employee>(2);
+ employees.add(employee1);
+ employees.add(employee3);
+ selectedItemsHolder.addAll(employees);
+
+ Collection<Employee> actualEmployees = tableModel.selectedItems();
+ Assert.assertNotNull("The collection of selected items can't be null", actualEmployees);
+ Assert.assertEquals("The count of selected items should be 2", 2, actualEmployees.size());
+
+ actualEmployees.remove(employee1);
+ actualEmployees.remove(employee3);
+
+ Assert.assertTrue("The selected items was not retrieved correctly", actualEmployees.isEmpty());
+
+ // Test removing selected items
+ selectedItemsHolder.remove(employee1);
+
+ actualEmployees = tableModel.selectedItems();
+ Assert.assertNotNull("The collection of selected items can't be null", actualEmployees);
+ Assert.assertEquals("The count of selected items should be 1", 1, actualEmployees.size());
+
+ actualEmployees.remove(employee3);
+
+ Assert.assertTrue("The selected items was not retrieved correctly", actualEmployees.isEmpty());
+ }
+
+ @Test
+ public void testSelectedItemsCleared() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ ListValueModel<Employee> listHolder = buildEmployeeListHolder();
+ SimpleCollectionValueModel<Employee> selectedItemsHolder = buildEmployeeHolders();
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ listHolder,
+ selectedItemsHolder,
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Test adding selected items
+ ArrayList<Employee> employees = new ArrayList<Employee>(2);
+ employees.add(employee1);
+ employees.add(employee3);
+ selectedItemsHolder.addAll(employees);
+
+ Collection<Employee> actualEmployees = tableModel.selectedItems();
+ Assert.assertNotNull("The collection of selected items can't be null", actualEmployees);
+ Assert.assertEquals("The count of selected items should be 2", 2, actualEmployees.size());
+
+ actualEmployees.remove(employee1);
+ actualEmployees.remove(employee3);
+ Assert.assertTrue("The selected items was not retrieved correctly", actualEmployees.isEmpty());
+
+ // Test removing selected items
+ selectedItemsHolder.clear();
+
+ actualEmployees = tableModel.selectedItems();
+ Assert.assertNotNull("The collection of selected items can't be null", actualEmployees);
+ Assert.assertEquals("The count of selected items should be ", 0, actualEmployees.size());
+ }
+
+ @Test
+ public void testSelectionChangeListener() {
+
+ Table table = new Table(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
+
+ Manager manager = new Manager();
+ subjectHolder.setValue(manager);
+
+ TableModel tableModel = new TableModel(
+ buildEmployeeListHolder(),
+ buildEmployeeHolder(),
+ table,
+ buildColumnAdapter(),
+ buildLabelProvider()
+ );
+
+ Collection<Employee> employees = new ArrayList<Employee>();
+ tableModel.addSelectionChangeListener(buildSelectionChangeListener(employees));
+
+ // Create Employees
+ String expectedName1 = "Dali_1";
+ String expectedManager1 = "WTP_1";
+ String expectedTitle1 = "plug-in_1";
+
+ String expectedName2 = "Dali_2";
+ String expectedManager2 = "WTP_2";
+ String expectedTitle2 = "plug-in_2";
+
+ String expectedName3 = "Dali_3";
+ String expectedManager3 = "WTP_3";
+ String expectedTitle3 = "plug-in_3";
+
+ Employee employee1 = new Employee(expectedName1, expectedTitle1, expectedManager1);
+ Employee employee2 = new Employee(expectedName2, expectedTitle2, expectedManager2);
+ Employee employee3 = new Employee(expectedName3, expectedTitle3, expectedManager3);
+
+ manager.addEmployee(employee1);
+ manager.addEmployee(employee2);
+ manager.addEmployee(employee3);
+
+ // Test adding selected items
+ table.setSelection(new int[] { 0, 2 });
+
+ // It seems a manual selection doesn't send any selection event
+ tableModel.tableSelectionChanged(null);
+
+ Assert.assertNotNull("The collection of selected items can't be null", employees);
+ Assert.assertEquals("The count of selected items should be 2", 2, employees.size());
+
+ employees.remove(employee1);
+ employees.remove(employee3);
+ Assert.assertTrue("The selected items was not retrieved correctly", employees.isEmpty());
+
+ // Test adding selected items
+ employees.add(employee1);
+ employees.add(employee3);
+ table.deselectAll();
+
+ // It seems a manual selection doesn't send any selection event
+ tableModel.tableSelectionChanged(null);
+
+ Assert.assertNotNull("The collection of selected items can't be null", employees);
+ Assert.assertEquals("The count of selected items should be 0", 0, employees.size());
+ }
+
+ private void testTableItemProperties(Table table,
+ int index,
+ String expectedName,
+ String expectedManager,
+ String expectedTitle)
+ {
+ TableItem tableItem = table.getItem(index);
+ Assert.assertNotNull("No TableItem was found for the Employee", tableItem);
+
+ String actualName = tableItem.getText(TableColumnAdapter.NAME_COLUMN);
+ Assert.assertEquals("TableItem[NAME_COLUMN] was not set correctly", expectedName, actualName);
+
+ String actualTitle = tableItem.getText(TableColumnAdapter.TITLE_COLUMN);
+ Assert.assertEquals("TableItem[TITLE_COLUMN] was not set correctly", expectedTitle, actualTitle);
+
+ String actualManager = tableItem.getText(TableColumnAdapter.MANAGER_COLUMN);
+ Assert.assertEquals("TableItem[MANAGER_COLUMN] was not set correctly", expectedManager, actualManager);
+ }
+
+ private class Employee extends AbstractModel {
+
+ private String manager;
+ private String name;
+ private String title;
+
+ static final String MANAGER_PROPERTY = "manager";
+ static final String NAME_PROPERTY = "name";
+ static final String TITLE_PROPERTY = "title";
+
+ Employee(String name, String title, String manager) {
+ super();
+
+ this.name = name;
+ this.title = title;
+ this.manager = manager;
+ }
+
+ String getManager() {
+ return manager;
+ }
+
+ String getName() {
+ return name;
+ }
+
+ String getTitle() {
+ return title;
+ }
+
+ void setManager(String manager) {
+ String oldManager = this.manager;
+ this.manager = manager;
+ firePropertyChanged(MANAGER_PROPERTY, oldManager, manager);
+ }
+
+ void setName(String name) {
+ String oldName = this.name;
+ this.name = name;
+ firePropertyChanged(NAME_PROPERTY, oldName, name);
+ }
+
+ void setTitle(String title) {
+ String oldTitle = this.title;
+ this.title = title;
+ firePropertyChanged(TITLE_PROPERTY, oldTitle, title);
+ }
+ }
+
+ private class Manager extends AbstractModel {
+
+ private List<Employee> employees;
+
+ static final String EMPLOYEES_LIST = "employees";
+
+ Manager() {
+ super();
+ employees = new ArrayList<Employee>();
+ }
+
+ Employee addEmployee(Employee employee) {
+ addItemToList(employee, employees, EMPLOYEES_LIST);
+ return employee;
+ }
+
+ Employee addEmployee(String name, String title, String manager) {
+ Employee employee = new Employee(name, title, manager);
+ return addEmployee(employee);
+ }
+
+ void changeEmployees(List<Employee> newEmployees) {
+ this.synchronizeList(newEmployees, this.employees, EMPLOYEES_LIST);
+ }
+
+ ListIterator<Employee> employees() {
+ return new CloneListIterator<Employee>(employees);
+ }
+
+ int employeesSize() {
+ return employees.size();
+ }
+
+ void moveEmployeeDown(Employee employee) {
+ int index = employees.indexOf(employee);
+ moveItemInList(index + 1, index, employees, EMPLOYEES_LIST);
+ }
+
+ void moveEmployees(Collection<Employee> employees, int targetIndex) {
+
+ int sourceIndex = Integer.MAX_VALUE;
+
+ for (Employee employee : employees) {
+ sourceIndex = Math.min(sourceIndex, this.employees.indexOf(employee));
+ }
+
+ moveItemsInList(
+ targetIndex,
+ sourceIndex,
+ employees.size(),
+ this.employees,
+ EMPLOYEES_LIST
+ );
+ }
+
+ void moveEmployeeUp(Employee employee) {
+ int index = employees.indexOf(employee);
+ moveItemInList(index - 1, index, employees, EMPLOYEES_LIST);
+ }
+
+ void removeAllEmployees() {
+ clearList(employees, EMPLOYEES_LIST);
+ }
+
+ void removeEmployee(Employee employee) {
+ removeItemFromList(employee, employees, EMPLOYEES_LIST);
+ }
+
+ void removeEmployees(Collection<Employee> employees) {
+ removeItemsFromList(employees.iterator(), this.employees, EMPLOYEES_LIST);
+ }
+
+ void replace(Employee oldEmployee, Employee newEmployee) {
+ replaceItemInList(oldEmployee, newEmployee, employees, EMPLOYEES_LIST);
+ }
+ }
+
+ private class TableColumnAdapter implements ColumnAdapter<Employee> {
+
+ static final int COLUMN_COUNT = 3;
+ static final int MANAGER_COLUMN = 2;
+ static final int NAME_COLUMN = 0;
+ static final int TITLE_COLUMN = 1;
+
+ private WritablePropertyValueModel<String> buildManagerHolder(Employee subject) {
+ return new PropertyAspectAdapter<Employee, String>(Employee.MANAGER_PROPERTY, subject) {
+ @Override
+ protected String buildValue_() {
+ return subject.getManager();
+ }
+
+ @Override
+ protected void setValue_(String value) {
+ subject.setManager(value);
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<String> buildNameHolder(Employee subject) {
+ return new PropertyAspectAdapter<Employee, String>(Employee.NAME_PROPERTY, subject) {
+ @Override
+ protected String buildValue_() {
+ return subject.getName();
+ }
+
+ @Override
+ protected void setValue_(String value) {
+ subject.setName(value);
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<String> buildTitleHolder(Employee subject) {
+ return new PropertyAspectAdapter<Employee, String>(Employee.TITLE_PROPERTY, subject) {
+ @Override
+ protected String buildValue_() {
+ return subject.getTitle();
+ }
+
+ @Override
+ protected void setValue_(String value) {
+ subject.setTitle(value);
+ }
+ };
+ }
+
+ public WritablePropertyValueModel<?>[] cellModels(Employee subject) {
+ WritablePropertyValueModel<?>[] holders = new WritablePropertyValueModel<?>[3];
+ holders[NAME_COLUMN] = buildNameHolder(subject);
+ holders[TITLE_COLUMN] = buildTitleHolder(subject);
+ holders[MANAGER_COLUMN] = buildManagerHolder(subject);
+ return holders;
+ }
+
+ public int columnCount() {
+ return COLUMN_COUNT;
+ }
+
+ public String columnName(int columnIndex) {
+ return String.valueOf(columnIndex);
+ }
+ }
+
+ private class TableLabelProvider extends LabelProvider
+ implements ITableLabelProvider {
+
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ Employee employee = (Employee) element;
+
+ if (columnIndex == TableColumnAdapter.NAME_COLUMN) {
+ return employee.getName();
+ }
+
+ if (columnIndex == TableColumnAdapter.TITLE_COLUMN) {
+ return employee.getTitle();
+ }
+
+ return employee.getManager();
+ }
+ }
+
+ private class TableModel extends TableModelAdapter<Employee> {
+
+ TableModel(ListValueModel<Employee> listHolder,
+ CollectionValueModel<Employee> selectedItemsHolder,
+ Table table,
+ ColumnAdapter<Employee> columnAdapter,
+ ITableLabelProvider labelProvider) {
+
+ super(listHolder,
+ selectedItemsHolder,
+ table,
+ columnAdapter,
+ labelProvider);
+ }
+
+ TableModel(ListValueModel<Employee> listHolder,
+ WritablePropertyValueModel<Employee> selectedItemHolder,
+ Table table,
+ ColumnAdapter<Employee> columnAdapter,
+ ITableLabelProvider labelProvider) {
+
+ super(listHolder,
+ new PropertyCollectionValueModelAdapter<Employee>(selectedItemHolder),
+ table,
+ columnAdapter,
+ labelProvider);
+ }
+
+ @Override
+ protected int indexOf(Employee item) {
+ return super.indexOf(item);
+ }
+
+ @Override
+ protected Collection<Employee> selectedItems() {
+ return super.selectedItems();
+ }
+
+ @Override
+ protected void tableSelectionChanged(SelectionEvent event) {
+ super.tableSelectionChanged(event);
+ }
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TriStateCheckBoxModelAdapterUITest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TriStateCheckBoxModelAdapterUITest.java
new file mode 100644
index 0000000000..d86cc9273f
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/swt/TriStateCheckBoxModelAdapterUITest.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.swt;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.swt.TriStateCheckBoxModelAdapter;
+import org.eclipse.jpt.common.ui.internal.widgets.DefaultWidgetFactory;
+import org.eclipse.jpt.common.ui.internal.widgets.TriStateCheckBox;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Play around with a set of tri-state check boxes.
+ */
+public class TriStateCheckBoxModelAdapterUITest
+ extends ApplicationWindow
+{
+ private final TestModel testModel;
+ private final WritablePropertyValueModel<TestModel> testModelHolder;
+ private final WritablePropertyValueModel<Boolean> flag1Holder;
+ private final WritablePropertyValueModel<Boolean> flag2Holder;
+ private final WritablePropertyValueModel<Boolean> notFlag2Holder;
+
+ public static void main(String[] args) throws Exception {
+ Window window = new TriStateCheckBoxModelAdapterUITest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private TriStateCheckBoxModelAdapterUITest(String[] args) {
+ super(null);
+ this.testModel = new TestModel(Boolean.TRUE, Boolean.FALSE);
+ this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+ this.flag1Holder = this.buildFlag1Holder(this.testModelHolder);
+ this.flag2Holder = this.buildFlag2Holder(this.testModelHolder);
+ this.notFlag2Holder = this.buildNotFlag2Holder(this.testModelHolder);
+ }
+
+ private WritablePropertyValueModel<Boolean> buildFlag1Holder(PropertyValueModel<TestModel> subjectHolder) {
+ return new PropertyAspectAdapter<TestModel, Boolean>(subjectHolder, TestModel.FLAG1_PROPERTY) {
+ @Override
+ protected Boolean buildValue_() {
+ return this.subject.isFlag1();
+ }
+ @Override
+ protected void setValue_(Boolean value) {
+ this.subject.setFlag1(value);
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Boolean> buildFlag2Holder(PropertyValueModel<TestModel> subjectHolder) {
+ return new PropertyAspectAdapter<TestModel, Boolean>(subjectHolder, TestModel.FLAG2_PROPERTY) {
+ @Override
+ protected Boolean buildValue_() {
+ return this.subject.isFlag2();
+ }
+ @Override
+ protected void setValue_(Boolean value) {
+ this.subject.setFlag2(value);
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Boolean> buildNotFlag2Holder(PropertyValueModel<TestModel> subjectHolder) {
+ return new PropertyAspectAdapter<TestModel, Boolean>(subjectHolder, TestModel.NOT_FLAG2_PROPERTY) {
+ @Override
+ protected Boolean buildValue_() {
+ return this.subject.isNotFlag2();
+ }
+ @Override
+ protected void setValue_(Boolean value) {
+ this.subject.setNotFlag2(value);
+ }
+ };
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(400, 100);
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayout(new FormLayout());
+ Control checkBoxPanel = this.buildCheckBoxPanel(mainPanel);
+ this.buildControlPanel(mainPanel, checkBoxPanel);
+ return mainPanel;
+ }
+
+ private Control buildCheckBoxPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100, -35);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildFlag1CheckBox(panel);
+ this.buildFlag2CheckBox(panel);
+ this.buildNotFlag2CheckBox(panel);
+ this.buildUnattachedCheckBox(panel);
+
+ return panel;
+ }
+
+ private void buildFlag1CheckBox(Composite parent) {
+ TriStateCheckBox checkBox = new TriStateCheckBox(parent, "flag 1", DefaultWidgetFactory.instance());
+ TriStateCheckBoxModelAdapter.adapt(this.flag1Holder, checkBox);
+ }
+
+ private void buildFlag2CheckBox(Composite parent) {
+ TriStateCheckBox checkBox = new TriStateCheckBox(parent, "flag 2", DefaultWidgetFactory.instance());
+ TriStateCheckBoxModelAdapter.adapt(this.flag2Holder, checkBox);
+ }
+
+ private void buildNotFlag2CheckBox(Composite parent) {
+ TriStateCheckBox checkBox = new TriStateCheckBox(parent, "next flag 2", DefaultWidgetFactory.instance());
+ TriStateCheckBoxModelAdapter.adapt(this.notFlag2Holder, checkBox);
+ }
+
+ private void buildUnattachedCheckBox(Composite parent) {
+ TriStateCheckBox checkBox = new TriStateCheckBox(parent, "unattached", DefaultWidgetFactory.instance());
+ checkBox.addSelectionListener(this.buildUnattachedSelectionListener());
+ }
+
+ private SelectionListener buildUnattachedSelectionListener() {
+ return new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ System.out.println("unattached default selected: " + e);
+ }
+ public void widgetSelected(SelectionEvent e) {
+ System.out.println("unattached selected: " + e);
+ }
+ };
+ }
+
+ private void buildControlPanel(Composite parent, Control checkBoxPanel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(checkBoxPanel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildFlipFlag1Button(panel);
+ this.buildClearModelButton(panel);
+ this.buildRestoreModelButton(panel);
+ this.buildPrintModelButton(panel);
+ }
+
+ private void buildFlipFlag1Button(Composite parent) {
+ this.buildFlipFlag1ACI().fill(parent);
+ }
+
+ private ActionContributionItem buildFlipFlag1ACI() {
+ Action action = new Action("next flag 1", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TriStateCheckBoxModelAdapterUITest.this.nextFlag1();
+ }
+ };
+ action.setToolTipText("next flag 1");
+ return new ActionContributionItem(action);
+ }
+
+ void nextFlag1() {
+ this.testModel.nextFlag1();
+ }
+
+ private void buildClearModelButton(Composite parent) {
+ this.buildClearModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildClearModelACI() {
+ Action action = new Action("clear model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TriStateCheckBoxModelAdapterUITest.this.clearModel();
+ }
+ };
+ action.setToolTipText("clear model");
+ return new ActionContributionItem(action);
+ }
+
+ void clearModel() {
+ this.testModelHolder.setValue(null);
+ }
+
+ private void buildRestoreModelButton(Composite parent) {
+ this.buildRestoreModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildRestoreModelACI() {
+ Action action = new Action("restore model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TriStateCheckBoxModelAdapterUITest.this.restoreModel();
+ }
+ };
+ action.setToolTipText("restore model");
+ return new ActionContributionItem(action);
+ }
+
+ void restoreModel() {
+ this.testModelHolder.setValue(this.testModel);
+ }
+
+ private void buildPrintModelButton(Composite parent) {
+ this.buildPrintModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildPrintModelACI() {
+ Action action = new Action("print model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TriStateCheckBoxModelAdapterUITest.this.printModel();
+ }
+ };
+ action.setToolTipText("print model");
+ return new ActionContributionItem(action);
+ }
+
+ void printModel() {
+ System.out.println("flag 1: " + this.testModel.isFlag1());
+ System.out.println("flag 2: " + this.testModel.isFlag2());
+ System.out.println("not flag 2: " + this.testModel.isNotFlag2());
+ System.out.println("***");
+ }
+
+
+ private class TestModel extends AbstractModel {
+ private Boolean flag1;
+ public static final String FLAG1_PROPERTY = "flag1";
+ private Boolean flag2;
+ public static final String FLAG2_PROPERTY = "flag2";
+ private Boolean notFlag2;
+ public static final String NOT_FLAG2_PROPERTY = "notFlag2";
+
+ public TestModel(Boolean flag1, Boolean flag2) {
+ this.flag1 = flag1;
+ this.flag2 = flag2;
+ this.notFlag2 = this.next(flag2);
+ }
+ private Boolean next(Boolean b) {
+ return (b == null) ? Boolean.TRUE : b.booleanValue() ? Boolean.FALSE : null;
+ }
+ public Boolean isFlag1() {
+ return this.flag1;
+ }
+ public void setFlag1(Boolean flag1) {
+ Boolean old = this.flag1;
+ this.flag1 = flag1;
+ this.firePropertyChanged(FLAG1_PROPERTY, old, flag1);
+ }
+ public void nextFlag1() {
+ this.setFlag1(this.next(this.flag1));
+ }
+ public Boolean isFlag2() {
+ return this.flag2;
+ }
+ public void setFlag2(Boolean flag2) {
+ Boolean old = this.flag2;
+ this.flag2 = flag2;
+ this.firePropertyChanged(FLAG2_PROPERTY, old, flag2);
+
+ old = this.notFlag2;
+ this.notFlag2 = this.next(flag2);
+ this.firePropertyChanged(NOT_FLAG2_PROPERTY, old, this.notFlag2);
+ }
+ public void nextFlag2() {
+ this.setFlag2(this.next(this.flag2));
+ }
+ public Boolean isNotFlag2() {
+ return this.notFlag2;
+ }
+ public void setNotFlag2(Boolean notFlag2) {
+ this.setFlag2(this.next(flag2));
+ }
+ public void nextNotFlag2() {
+ this.setNotFlag2(this.next(this.notFlag2));
+ }
+ @Override
+ public String toString() {
+ return "TestModel(" + this.isFlag1() + " - " + this.isFlag2() + ")";
+ }
+ }
+
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlAlignerTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlAlignerTest.java
new file mode 100644
index 0000000000..0bd8f4cce0
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlAlignerTest.java
@@ -0,0 +1,803 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.fail;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jpt.common.ui.internal.util.ControlAligner;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.ReflectionTools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class ControlAlignerTest {
+
+ private ControlAligner controlAligner;
+ private Composite parent;
+ private Shell shell;
+
+ private Layout buildSpacerLayout() {
+ return new Layout() {
+ @Override
+ protected Point computeSize(Composite composite,
+ int widthHint,
+ int heightHint,
+ boolean flushCache) {
+
+ return new Point(widthHint, heightHint);
+ }
+
+ @Override
+ protected void layout(Composite composite, boolean flushCache) {
+ GridData data = (GridData) composite.getLayoutData();
+ composite.setBounds(0, 0, data.widthHint, data.heightHint);
+ }
+ };
+ }
+
+ @Before
+ public void setUp() {
+
+ controlAligner = new ControlAligner();
+
+ shell = new Shell(Display.getCurrent());
+ shell.setLayout(new GridLayout(1, false));
+
+ parent = new Composite(shell, SWT.NONE);
+ parent.setLayout(new GridLayout(1, false));
+ parent.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ }
+
+ @After
+ public void tearDown() {
+
+ if (controlAligner != null) {
+ controlAligner.dispose();
+ controlAligner = null;
+ }
+
+ if (shell != null) {
+ shell.dispose();
+ shell = null;
+ }
+ }
+
+ @Test
+ public void testAddControl1() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label label = new Label(pane, SWT.NULL);
+ updateGridData(label);
+
+ controlAligner.add(label);
+
+ assertEquals(
+ "The maximum width should be 0,",
+ 0,
+ controlAligner.getMaximumWidth()
+ );
+
+ label.setText("This is a ControlAligner");
+// parent.layout(true, true);
+
+ Point size = label.getSize();
+
+ assertEquals(
+ "The width should be " + size.x + ",",
+ size.x,
+ controlAligner.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testAddControl2() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Button button = new Button(pane, SWT.NULL);
+ button.setText("This is a ControlAligner");
+ updateGridData(button);
+
+ controlAligner.add(button);
+ parent.layout(true, true);
+
+ Point size = button.getSize();
+
+ assertEquals(
+ "The width should be " + size.x + ",",
+ size.x,
+ controlAligner.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testAddControl3() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label label = new Label(pane, SWT.NULL);
+ label.setText("This is very long text");
+ updateGridData(label);
+
+ Button button = new Button(pane, SWT.NULL);
+ button.setText("Short text");
+ updateGridData(button);
+
+// parent.layout(true, true);
+
+ controlAligner.add(label);
+ controlAligner.add(button);
+
+ Point labelSize = label.getSize();
+ Point buttonSize = button.getSize();
+ int max = Math.max(labelSize.x, buttonSize.x);
+
+ assertEquals(
+ "The width should be " + max + ",",
+ max,
+ controlAligner.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testAddControlAligner1() throws Exception {
+
+ Label label1 = new Label(parent, SWT.NULL);
+ Label label2 = new Label(parent, SWT.NULL);
+
+ updateGridData(label1);
+ updateGridData(label2);
+
+ controlAligner.add(label1);
+
+ ControlAligner controlAligner2 = new ControlAligner();
+ controlAligner.add(controlAligner2);
+ controlAligner2.add(label2);
+
+ label1.setText("This is a ControlAligner");
+ label2.setText("This is a very long ControlAligner");
+// parent.layout(true, true);
+
+ Point size1 = label1.getSize();
+ Point size2 = label2.getSize();
+ int width = Math.max(size1.x, size2.x);
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner2.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testAddControlAligner2() throws Exception {
+
+ Label label1 = new Label(parent, SWT.NULL);
+ Label label2 = new Label(parent, SWT.NULL);
+
+ updateGridData(label1);
+ updateGridData(label2);
+
+ controlAligner.add(label1);
+
+ ControlAligner controlAligner2 = new ControlAligner();
+ controlAligner2.add(label2);
+
+ label1.setText("This is a ControlAligner");
+ label2.setText("This is a very long ControlAligner");
+
+ controlAligner.add(controlAligner2);
+// parent.layout(true, true);
+
+ Point size1 = label1.getSize();
+ Point size2 = label2.getSize();
+ int width = Math.max(size1.x, size2.x);
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner2.getMaximumWidth()
+ );
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testAddControlAlignerToItself() throws Exception {
+ controlAligner.add(controlAligner);
+ fail("A ControlAligner can't be added to itself");
+ }
+
+ @Test
+ public void testDialog_AddControl1() throws Exception {
+
+ final int[] maximumWidth = new int[1];
+ final int[] size = new int[1];
+
+ TitleAreaDialog dialog = new TitleAreaDialog(SWTUtil.getShell()) {
+
+ private Label label;
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ label = new Label(pane, SWT.LEFT);
+ label.setText("This is a ControlAligner");
+ updateGridData(label);
+
+ controlAligner.add(label);
+
+ return parent;
+ }
+
+ @Override
+ protected void initializeBounds() {
+ super.initializeBounds();
+ size[0] = label.getSize().x;
+ maximumWidth[0] = controlAligner.getMaximumWidth();
+ }
+ };
+
+ dialog.create();
+ dialog.close();
+
+ assertEquals(
+ "The width should be " + size[0] + ",",
+ size[0],
+ maximumWidth[0]
+ );
+ }
+
+ @Test
+ public void testDialog_AddControl2() throws Exception {
+
+ final int[] maximumWidth = new int[1];
+ final int[] sizes = new int[2];
+
+ TitleAreaDialog dialog = new TitleAreaDialog(SWTUtil.getShell()) {
+
+ private Button button;
+ private Label label;
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ label = new Label(pane, SWT.NULL);
+ label.setText("This is a ControlAligner");
+ updateGridData(label);
+
+ controlAligner.add(label);
+
+ button = new Button(pane, SWT.NULL);
+ button.setText("Short text");
+ updateGridData(button);
+
+ controlAligner.add(button);
+
+ return parent;
+ }
+
+ @Override
+ protected void initializeBounds() {
+ super.initializeBounds();
+ sizes[0] = label.getSize().x;
+ sizes[1] = button.getSize().x;
+ maximumWidth[0] = controlAligner.getMaximumWidth();
+ }
+ };
+
+ dialog.create();
+ dialog.close();
+
+ int labelSize = sizes[0];
+ int buttonSize = sizes[1];
+ int max = Math.max(labelSize, buttonSize);
+
+ assertEquals(
+ "The width should be " + max + ",",
+ max,
+ maximumWidth[0]
+ );
+ }
+
+ @Test
+ public void testDispose() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label label = new Label(pane, SWT.NULL);
+ label.setText("This is very long text");
+ updateGridData(label);
+
+ Button button = new Button(pane, SWT.NULL);
+ button.setText("Short text");
+ updateGridData(button);
+
+ controlAligner.add(label);
+ controlAligner.add(button);
+
+ Point labelSize = label.getSize();
+ Point buttonSize = button.getSize();
+ int max = Math.max(labelSize.x, buttonSize.x);
+
+ assertEquals(
+ "The width should be " + max + ",",
+ max,
+ controlAligner.getMaximumWidth()
+ );
+
+ label.dispose();
+
+ Point newButtonSize = button.getSize();
+
+ assertNotSame(
+ "The old max and new max should not be the same",
+ max,
+ newButtonSize.x
+ );
+
+ assertEquals(
+ "The ControlAligner doesn't have the right maximum width",
+ newButtonSize.x,
+ controlAligner.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testHierarchyOfControlAligners() throws Exception {
+
+ // Aligner1
+ // ^
+ // |-Aligner2
+ // ^
+ // |-Aligner3
+ ControlAligner controlAligner2 = new ControlAligner();
+ controlAligner.add(controlAligner2);
+
+ ControlAligner controlAligner3 = new ControlAligner();
+ controlAligner2.add(controlAligner3);
+
+ // Test 1
+ Label label1 = new Label(parent, SWT.NULL);
+ label1.setText("This is a label widget");
+ parent.layout(true, true);
+
+ int labelWidth1 = label1.getSize().x;
+ controlAligner3.add(label1);
+
+ assertEquals(controlAligner3.getMaximumWidth(), labelWidth1);
+ assertEquals(controlAligner2.getMaximumWidth(), labelWidth1);
+ assertEquals(controlAligner.getMaximumWidth(), labelWidth1);
+
+ // Test 2
+ Label label2 = new Label(parent, SWT.NULL);
+ label2.setText("ShortLabel");
+ controlAligner2.add(label2);
+ parent.layout(true);
+
+ int newLabelWidth1 = label1.getSize().x;
+ int newLabelWidth2 = label2.getSize().x;
+
+ assertEquals(controlAligner3.getMaximumWidth(), controlAligner2.getMaximumWidth());
+ assertEquals(controlAligner2.getMaximumWidth(), controlAligner.getMaximumWidth());
+ assertEquals(newLabelWidth1, newLabelWidth2);
+ assertEquals(newLabelWidth1, controlAligner.getMaximumWidth());
+
+ // Test 3
+ Label label3 = new Label(parent, SWT.NULL);
+ label3.setText("A very long label that takes a lot of horizontal space");
+// parent.layout(true);
+ controlAligner.add(label3);
+
+ newLabelWidth1 = label1.getSize().x;
+ newLabelWidth2 = label2.getSize().x;
+ int newLabelWidth3 = label3.getSize().x;
+
+ assertEquals(controlAligner3.getMaximumWidth(), controlAligner2.getMaximumWidth());
+ assertEquals(controlAligner2.getMaximumWidth(), controlAligner.getMaximumWidth());
+ assertEquals(newLabelWidth1, newLabelWidth2);
+ assertEquals(newLabelWidth2, newLabelWidth3);
+ assertEquals(newLabelWidth1, controlAligner.getMaximumWidth());
+
+ // Make sure all the locked are removed
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner2, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner3, "locked"), Boolean.FALSE);
+
+ // Change the text of label2
+ label2.setText("mm");
+// parent.layout(true);
+
+ newLabelWidth1 = label1.getSize().x;
+ newLabelWidth2 = label2.getSize().x;
+ newLabelWidth3 = label3.getSize().x;
+
+ assertEquals(controlAligner3.getMaximumWidth(), controlAligner2.getMaximumWidth());
+ assertEquals(controlAligner2.getMaximumWidth(), controlAligner.getMaximumWidth());
+ assertEquals(newLabelWidth1, newLabelWidth2);
+ assertEquals(newLabelWidth2, newLabelWidth3);
+ assertEquals(newLabelWidth1, controlAligner.getMaximumWidth());
+
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner2, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner3, "locked"), Boolean.FALSE);
+
+ // Change the text of label1
+ label1.setText("a");
+// parent.layout(true);
+
+ Composite parent1 = new Composite(SWTUtil.getShell(), SWT.NULL);
+ parent1.setLayout(new GridLayout());
+
+ Label tempLabel = new Label(parent1, SWT.NULL);
+ tempLabel.setText("a");
+// parent1.layout(true);
+
+ int realWidth = tempLabel.getSize().x;
+
+ newLabelWidth1 = label1.getSize().x;
+ newLabelWidth2 = label2.getSize().x;
+ newLabelWidth3 = label3.getSize().x;
+
+ assertEquals(controlAligner3.getMaximumWidth(), controlAligner2.getMaximumWidth());
+ assertEquals(controlAligner2.getMaximumWidth(), controlAligner.getMaximumWidth());
+ assertEquals(newLabelWidth1, newLabelWidth2);
+ assertEquals(newLabelWidth2, newLabelWidth3);
+ assertEquals(newLabelWidth1, controlAligner.getMaximumWidth());
+ assertFalse(newLabelWidth1 == realWidth);
+
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner2, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner3, "locked"), Boolean.FALSE);
+
+ // Change the text of label1
+ label1.setText("Yes another big long long text so that all the labels will have to take the size of this label to make sure ControlAligner works correctly");
+// parent.layout(true);
+
+ // Weird: It seems no notification is sent, fire one manually
+ Event event = new Event();
+ event.widget = label1;
+ event.type = SWT.Resize;
+ label1.notifyListeners(SWT.Resize, event);
+
+ Composite parent2 = new Composite(SWTUtil.getShell(), SWT.NULL);
+ parent2.setLayout(new GridLayout());
+
+ tempLabel = new Label(parent2, SWT.NULL);
+ tempLabel.setText(label1.getText());
+ parent2.layout(true);
+
+ realWidth = tempLabel.getSize().x;
+
+ newLabelWidth1 = label1.getSize().x;
+ newLabelWidth2 = label2.getSize().x;
+ newLabelWidth3 = label3.getSize().x;
+
+ assertEquals(controlAligner3.getMaximumWidth(), controlAligner2.getMaximumWidth());
+ assertEquals(controlAligner2.getMaximumWidth(), controlAligner.getMaximumWidth());
+ assertEquals(newLabelWidth1, newLabelWidth2);
+ assertEquals(newLabelWidth2, newLabelWidth3);
+ assertEquals(controlAligner.getMaximumWidth(), newLabelWidth1);
+ assertEquals(realWidth, newLabelWidth1);
+
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner2, "locked"), Boolean.FALSE);
+ assertEquals(ReflectionTools.getFieldValue_(controlAligner3, "locked"), Boolean.FALSE);
+ }
+
+ @Test
+ public void testRemoveControl1() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Button button = new Button(pane, SWT.NULL);
+ button.setText("This is a ControlAligner");
+ updateGridData(button);
+
+ controlAligner.add(button);
+ parent.layout(true, true);
+
+ Point size = button.getSize();
+
+ assertEquals(
+ "The width should be " + size.x + ",",
+ size.x,
+ controlAligner.getMaximumWidth()
+ );
+
+ controlAligner.remove(button);
+
+ assertEquals(
+ "The width should be 0, ",
+ 0,
+ controlAligner.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testRemoveControl2() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label label = new Label(pane, SWT.NULL);
+ label.setText("This is very long text");
+ updateGridData(label);
+
+ Button button = new Button(pane, SWT.NULL);
+ button.setText("Short text");
+ updateGridData(button);
+// parent.layout(true, true);
+
+ controlAligner.add(label);
+ controlAligner.add(button);
+
+ Point labelSize = label.getSize();
+ Point buttonSize = button.getSize();
+ int max = Math.max(labelSize.x, buttonSize.x);
+
+ assertEquals(
+ "The width should be " + max + ",",
+ max,
+ controlAligner.getMaximumWidth()
+ );
+
+ controlAligner.remove(label);
+
+ Point newButtonSize = button.getSize();
+
+ assertNotSame(
+ "The old max and new max should not be the same",
+ max,
+ newButtonSize.x
+ );
+
+ assertEquals(
+ "The ControlAligner doesn't have the right maximum width",
+ newButtonSize.x,
+ controlAligner.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testRemoveControl4() throws Exception {
+
+ Composite pane = new Composite(parent, SWT.NULL);
+ pane.setLayout(new GridLayout(3, false));
+ pane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Widget 1
+ Label label = new Label(pane, SWT.NULL);
+ label.setText("This is very long text");
+ updateGridData(label);
+ controlAligner.add(label);
+
+ // Widget 2
+ Composite spacer = new Composite(pane, SWT.NULL);
+ spacer.setLayout(buildSpacerLayout());
+ updateGridData(spacer);
+ controlAligner.add(spacer);
+
+ // Widget 3
+ Button button = new Button(pane, SWT.NULL);
+ button.setText("Short text");
+ updateGridData(button);
+ controlAligner.add(button);
+
+// parent.layout(true, true);
+
+ // Make sure the 3 widgets have the same width
+ Point labelSize = label.getSize();
+ Point spacerSize = spacer.getSize();
+ Point buttonSize = button.getSize();
+ int max = Math.max(labelSize.x, buttonSize.x);
+ max = Math.max(max, spacerSize.x);
+
+ assertEquals(
+ "The width should be " + max + ",",
+ max,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The spacer's width should be " + max + ",",
+ max,
+ spacerSize.x
+ );
+
+ // Remove the label (the widest widget) and make sure the width was
+ // correctly calculated
+ controlAligner.remove(label);
+
+ spacerSize = spacer.getSize();
+ buttonSize = button.getSize();
+ int max2 = Math.max(spacerSize.x, buttonSize.x);
+
+ assertNotSame(
+ "The old max and new max should not be the same",
+ max,
+ max2
+ );
+
+ assertEquals(
+ "The ControlAligner doesn't have the right maximum width",
+ max2,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The spacer's width should have been adjusted",
+ max2,
+ spacerSize.x
+ );
+ }
+
+ @Test
+ public void testRemoveControlAligner1() throws Exception {
+
+ Label label1 = new Label(parent, SWT.NULL);
+ Label label2 = new Label(parent, SWT.NULL);
+
+ updateGridData(label1);
+ updateGridData(label2);
+
+ controlAligner.add(label1);
+
+ ControlAligner controlAligner2 = new ControlAligner();
+ controlAligner.add(controlAligner2);
+ controlAligner2.add(label2);
+
+ label1.setText("This is a ControlAligner");
+ label2.setText("This is a very long ControlAligner");
+// parent.layout(true, true);
+
+ Point size1 = label1.getSize();
+ Point size2 = label2.getSize();
+ int width = Math.max(size1.x, size2.x);
+
+ // Test 1
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner2.getMaximumWidth()
+ );
+
+ // Test 2
+ controlAligner.remove(label1);
+
+ width = label2.getSize().x;
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner2.getMaximumWidth()
+ );
+ }
+
+ @Test
+ public void testRemoveControlAligner2() throws Exception {
+
+ Label label1 = new Label(parent, SWT.NULL);
+ Label label2 = new Label(parent, SWT.NULL);
+
+ updateGridData(label1);
+ updateGridData(label2);
+
+ controlAligner.add(label1);
+
+ ControlAligner controlAligner2 = new ControlAligner();
+ controlAligner.add(controlAligner2);
+ controlAligner2.add(label2);
+
+ label1.setText("This is a ControlAligner");
+ label2.setText("This is a very long ControlAligner");
+// parent.layout(true, true);
+
+ Point size1 = label1.getSize();
+ Point size2 = label2.getSize();
+ int width = Math.max(size1.x, size2.x);
+
+ // Test 1
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner2.getMaximumWidth()
+ );
+
+ // Test 2
+ controlAligner2.remove(label2);
+
+ width = label1.getSize().x;
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner.getMaximumWidth()
+ );
+
+ assertEquals(
+ "The width should be " + width + ",",
+ width,
+ controlAligner2.getMaximumWidth()
+ );
+ }
+
+ private void updateGridData(Control control) {
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = false;
+ control.setLayoutData(data);
+ }
+} \ No newline at end of file
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlEnablerTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlEnablerTest.java
new file mode 100644
index 0000000000..7c37787011
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlEnablerTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.tests.internal.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class ControlEnablerTest {
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ }
+ }
+
+ @Test
+ public void testSwitchState() {
+
+ SimplePropertyValueModel<Boolean> booleanHolder =
+ new SimplePropertyValueModel<Boolean>(true);
+
+ Combo combo = new Combo(parent, SWT.BORDER);
+
+ SWTTools.controlEnabledState(booleanHolder, combo);
+
+ assertTrue(
+ "The Combo should be enabled",
+ combo.isEnabled()
+ );
+
+ // Change state (null)
+ booleanHolder.setValue(null);
+
+ assertFalse(
+ "The Combo should not be enabled",
+ combo.isEnabled()
+ );
+
+ // Change state (true)
+ booleanHolder.setValue(true);
+
+ assertTrue(
+ "The Combo should be enabled",
+ combo.isEnabled()
+ );
+
+ // Change state (false)
+ booleanHolder.setValue(false);
+
+ assertFalse(
+ "The Combo should not be enabled",
+ combo.isEnabled()
+ );
+
+ // Dispose
+ combo.dispose();
+ booleanHolder.setValue(true);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlSwitcherTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlSwitcherTest.java
new file mode 100644
index 0000000000..9471d5d801
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlSwitcherTest.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import org.eclipse.jpt.common.ui.internal.util.ControlSwitcher;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.ReflectionTools;
+import org.eclipse.jpt.utility.internal.Transformer;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.part.PageBook;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class ControlSwitcherTest {
+
+ private PageBook pageBook;
+ private Composite pane1;
+ private Composite pane2;
+ private Composite parent;
+
+ private Composite buildPane1() {
+
+ if (pane1 == null) {
+
+ pane1 = new Composite(pageBook, SWT.NULL);
+ pane1.setLayout(new GridLayout(2, false));
+
+ Label label = new Label(pane1, SWT.NULL);
+ label.setText("&Test2:");
+
+ Text text = new Text(pane1, SWT.BORDER);
+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Combo combo = new Combo(pane1, SWT.BORDER);
+
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 2;
+ combo.setLayoutData(data);
+ }
+
+ return pane1;
+ }
+
+ private Composite buildPane2() {
+
+ if (pane2 == null) {
+
+ pane2 = new Composite(pageBook, SWT.NULL);
+ pane2.setLayout(new GridLayout(2, false));
+
+ Label label = new Label(pane2, SWT.NULL);
+ label.setText("&Test1:");
+
+ Text text = new Text(pane2, SWT.BORDER);
+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ }
+
+ return pane2;
+ }
+
+ private Transformer<Boolean, Control> buildTransformer() {
+ return new Transformer<Boolean, Control>() {
+ public Control transform(Boolean value) {
+ return (value == null) ? null : (value ? pane1 : pane2);
+ }
+ };
+ }
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+
+ pageBook = new PageBook(parent, SWT.NULL);
+ pageBook.setLayoutData(new GridData());
+ }
+
+ @After
+ public void tearDown() {
+
+ if (parent != null) {
+
+ parent.dispose();
+
+ parent = null;
+ pageBook = null;
+ }
+ }
+
+ @Test
+ public void testSwitch() {
+
+ SimplePropertyValueModel<Boolean> switchHolder = new SimplePropertyValueModel<Boolean>();
+ Transformer<Boolean, Control> transformer = buildTransformer();
+
+ pane1 = buildPane1();
+ pane1.setVisible(false);
+
+ pane2 = buildPane2();
+ pane2.setVisible(false);
+
+ new ControlSwitcher(
+ switchHolder,
+ transformer,
+ pageBook
+ );
+
+ // Test 1
+ switchHolder.setValue(true);
+ Control control = (Control) ReflectionTools.getFieldValue(pageBook, "currentPage");
+
+ assertNotNull(
+ "The page book's page shouldn't be null",
+ control
+ );
+
+ assertSame(
+ "The current pane should be pane1",
+ pane1,
+ control
+ );
+
+ Point pane1Size = pane1.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ Point pageBookSize = pageBook.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+ assertEquals(
+ "The width of the PageBook should be the same as the width of pane1",
+ pane1Size.x,
+ pageBookSize.x
+ );
+
+ assertEquals(
+ "The height of the PageBook should be the same as the height of pane1",
+ pane1Size.y,
+ pageBookSize.y
+ );
+
+ // Test 2
+ switchHolder.setValue(false);
+ control = (Control) ReflectionTools.getFieldValue(pageBook, "currentPage");
+
+ assertNotNull(
+ "The page book's page shouldn't be null",
+ control
+ );
+
+ assertSame(
+ "The current pane should be pane2",
+ pane2,
+ control
+ );
+
+ Point pane2Size = pane2.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ pageBookSize = pageBook.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+ assertEquals(
+ "The width of the PageBook should be the same as the width of pane2",
+ pane2Size.x,
+ pageBookSize.x
+ );
+
+ assertEquals(
+ "The height of the PageBook should be the same as the height of pane2",
+ pane2Size.y,
+ pageBookSize.y
+ );
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlVisibilityEnablerTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlVisibilityEnablerTest.java
new file mode 100644
index 0000000000..bfe86f4613
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/ControlVisibilityEnablerTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.tests.internal.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class ControlVisibilityEnablerTest {
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ }
+ }
+
+ @Test
+ public void testSwitchState() {
+
+ SimplePropertyValueModel<Boolean> booleanHolder =
+ new SimplePropertyValueModel<Boolean>(true);
+
+ Combo combo = new Combo(parent, SWT.BORDER);
+
+ SWTTools.controlVisibleState(booleanHolder, combo);
+
+ assertTrue(
+ "The Combo should be visible",
+ combo.isVisible()
+ );
+
+ // Change state (null)
+ booleanHolder.setValue(null);
+
+ assertFalse(
+ "The Combo should not be visible",
+ combo.isVisible()
+ );
+
+ // Change state (true)
+ booleanHolder.setValue(true);
+
+ assertTrue(
+ "The Combo should be visible",
+ combo.isVisible()
+ );
+
+ // Change state (false)
+ booleanHolder.setValue(false);
+
+ assertFalse(
+ "The Combo should not be visible",
+ combo.isVisible()
+ );
+
+ // Dispose
+ combo.dispose();
+ booleanHolder.setValue(true);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/JptUiUtilTests.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/JptUiUtilTests.java
new file mode 100644
index 0000000000..38f00d21d0
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/JptUiUtilTests.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.util;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@SuiteClasses
+({
+ ControlAlignerTest.class,
+ ControlSwitcherTest.class,
+ ControlEnablerTest.class,
+ ControlVisibilityEnablerTest.class,
+ LabeledButtonTest.class,
+ LabeledLabelTest.class,
+ LabeledControlUpdaterTest.class,
+ PaneEnablerTest.class,
+ PaneVisibilityEnablerTest.class,
+})
+@RunWith(Suite.class)
+public final class JptUiUtilTests {
+
+ private JptUiUtilTests() {
+ super();
+ throw new UnsupportedOperationException();
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new JUnit4TestAdapter(JptUiUtilTests.class));
+ return suite;
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledButtonTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledButtonTest.java
new file mode 100644
index 0000000000..52515acb41
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledButtonTest.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.util;
+
+import static org.junit.Assert.assertEquals;
+import org.eclipse.core.runtime.AssertionFailedException;
+import org.eclipse.jpt.common.ui.internal.util.LabeledButton;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class LabeledButtonTest {
+
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ parent = null;
+ }
+ }
+
+ @Test
+ public void testLabeledButton1() {
+ Button button = new Button(parent, SWT.NULL);
+ new LabeledButton(button);
+ }
+
+ @Test(expected=AssertionFailedException.class)
+ public void testLabeledButton2() {
+ new LabeledButton(null);
+ }
+
+ @Test
+ public void testSetImage() {
+
+ Image expected = new Image(parent.getDisplay(), 16, 16);
+
+ try {
+ Button button = new Button(parent, SWT.NULL);
+ LabeledButton labeledButton = new LabeledButton(button);
+
+ labeledButton.setImage(expected);
+
+ assertEquals(
+ "The Button didn't receive the Image",
+ expected,
+ button.getImage()
+ );
+ }
+ finally {
+ expected.dispose();
+ }
+ }
+
+ @Test
+ public void testSetImageDispose() {
+
+ Image expected = new Image(parent.getDisplay(), 16, 16);
+
+ try {
+ Button button = new Button(parent, SWT.NULL);
+ LabeledButton labeledButton = new LabeledButton(button);
+
+ button.dispose();
+
+ // This should not fail but simply do nothing
+ labeledButton.setImage(expected);
+ }
+ finally {
+ expected.dispose();
+ }
+ }
+
+ @Test
+ public void testSetText() {
+ Button button = new Button(parent, SWT.NULL);
+ LabeledButton labeledButton = new LabeledButton(button);
+
+ String expected = "This is a test";
+ labeledButton.setText(expected);
+
+ assertEquals(
+ "The Button didn't receive the text",
+ expected,
+ button.getText()
+ );
+ }
+
+ @Test
+ public void testSetTextDispose() {
+ Button button = new Button(parent, SWT.NULL);
+ LabeledButton labeledButton = new LabeledButton(button);
+
+ button.dispose();
+
+ // This should not fail but simply do nothing
+ String expected = "This is a test";
+ labeledButton.setText(expected);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledControlUpdaterTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledControlUpdaterTest.java
new file mode 100644
index 0000000000..461dac698e
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledControlUpdaterTest.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.util;
+
+import static org.junit.Assert.assertEquals;
+import org.eclipse.jpt.common.ui.internal.util.LabeledControlUpdater;
+import org.eclipse.jpt.common.ui.internal.util.LabeledLabel;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class LabeledControlUpdaterTest {
+
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ parent = null;
+ }
+ }
+
+ @Test
+ public void testSetImage() {
+
+ Image expected = new Image(parent.getDisplay(), 16, 16);
+
+ try {
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ WritablePropertyValueModel<Image> imageHolder = new SimplePropertyValueModel<Image>();
+ new LabeledControlUpdater(labeledLabel, null, imageHolder);
+
+ labeledLabel.setImage(expected);
+
+ assertEquals(
+ "The Label didn't receive the Image",
+ expected,
+ label.getImage()
+ );
+ }
+ finally {
+ expected.dispose();
+ }
+ }
+
+ @Test
+ public void testSetImageDispose() {
+
+ Image expected = new Image(parent.getDisplay(), 16, 16);
+
+ try {
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ WritablePropertyValueModel<Image> imageHolder = new SimplePropertyValueModel<Image>();
+ new LabeledControlUpdater(labeledLabel, null, imageHolder);
+
+ label.dispose();
+ labeledLabel.setImage(expected);
+ }
+ finally {
+ expected.dispose();
+ }
+ }
+
+ @Test
+ public void testSetText() {
+
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ WritablePropertyValueModel<String> textHolder = new SimplePropertyValueModel<String>();
+ new LabeledControlUpdater(labeledLabel, textHolder);
+
+ String expected = "This is a test";
+ textHolder.setValue(expected);
+
+ assertEquals(
+ "The Label didn't receive the text",
+ expected,
+ label.getText()
+ );
+ }
+
+ @Test
+ public void testSetTextDispose() {
+
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ WritablePropertyValueModel<String> textHolder = new SimplePropertyValueModel<String>();
+ new LabeledControlUpdater(labeledLabel, textHolder);
+
+ label.dispose();
+
+ String expected = "This is a test";
+ textHolder.setValue(expected);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledLabelTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledLabelTest.java
new file mode 100644
index 0000000000..d43bcee4fb
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/LabeledLabelTest.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tests.internal.util;
+
+import static org.junit.Assert.assertEquals;
+import org.eclipse.core.runtime.AssertionFailedException;
+import org.eclipse.jpt.common.ui.internal.util.LabeledLabel;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class LabeledLabelTest {
+
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ parent = null;
+ }
+ }
+
+ @Test
+ public void testLabeledButton1() {
+ Label label = new Label(parent, SWT.NULL);
+ new LabeledLabel(label);
+ }
+
+ @Test(expected=AssertionFailedException.class)
+ public void testLabeledButton2() {
+ new LabeledLabel(null);
+ }
+
+ @Test
+ public void testSetImage() {
+
+ Image expected = new Image(parent.getDisplay(), 16, 16);
+
+ try {
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ labeledLabel.setImage(expected);
+
+ assertEquals(
+ "The Label didn't receive the Image",
+ expected,
+ label.getImage()
+ );
+ }
+ finally {
+ expected.dispose();
+ }
+ }
+
+ @Test
+ public void testSetImageDispose() {
+
+ Image expected = new Image(parent.getDisplay(), 16, 16);
+
+ try {
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ label.dispose();
+
+ // This should not fail but simply do nothing
+ labeledLabel.setImage(expected);
+ }
+ finally {
+ expected.dispose();
+ }
+ }
+
+ @Test
+ public void testSetText() {
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ String expected = "This is a test";
+ labeledLabel.setText(expected);
+
+ assertEquals(
+ "The Label didn't receive the text",
+ expected,
+ label.getText()
+ );
+ }
+
+ @Test
+ public void testSetTextDispose() {
+ Label label = new Label(parent, SWT.NULL);
+ LabeledLabel labeledLabel = new LabeledLabel(label);
+
+ label.dispose();
+
+ // This should not fail but simply do nothing
+ String expected = "This is a test";
+ labeledLabel.setText(expected);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneEnablerTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneEnablerTest.java
new file mode 100644
index 0000000000..dfba84b24d
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneEnablerTest.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.tests.internal.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.eclipse.jpt.common.ui.internal.util.PaneEnabler;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.common.ui.internal.widgets.DialogPane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class PaneEnablerTest {
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ }
+ }
+
+ @Test
+ public void testSwitchState() {
+
+ SimplePropertyValueModel<Boolean> booleanHolder =
+ new SimplePropertyValueModel<Boolean>(true);
+
+ DialogPane<Node> pane = new DialogPane<Node>(
+ new SimplePropertyValueModel<Node>(),
+ parent)
+ {
+ @Override
+ protected void initializeLayout(Composite container) {
+ }
+ };
+
+ new PaneEnabler(booleanHolder, pane);
+
+ assertTrue(
+ "The pane should be enabled",
+ pane.getControl().isEnabled()
+ );
+
+ // Change state (null)
+ booleanHolder.setValue(null);
+
+ assertFalse(
+ "The pane should not be enabled",
+ pane.getControl().isEnabled()
+ );
+
+ // Change state (true)
+ booleanHolder.setValue(true);
+
+ assertTrue(
+ "The pane should be enabled",
+ pane.getControl().isEnabled()
+ );
+
+ // Change state (false)
+ booleanHolder.setValue(false);
+
+ assertFalse(
+ "The pane should not be enabled",
+ pane.getControl().isEnabled()
+ );
+
+ // Dispose
+ pane.dispose();
+ booleanHolder.setValue(true);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneVisibilityEnablerTest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneVisibilityEnablerTest.java
new file mode 100644
index 0000000000..ed8af111f8
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/util/PaneVisibilityEnablerTest.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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.tests.internal.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.eclipse.jpt.common.ui.internal.util.PaneVisibilityEnabler;
+import org.eclipse.jpt.common.ui.internal.util.SWTUtil;
+import org.eclipse.jpt.common.ui.internal.widgets.DialogPane;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public final class PaneVisibilityEnablerTest {
+ private Composite parent;
+
+ @Before
+ public void setUp() {
+ parent = new Composite(SWTUtil.getShell(), SWT.NONE);
+ parent.setLayout(new GridLayout());
+ }
+
+ @After
+ public void tearDown() {
+ if (parent != null) {
+ parent.dispose();
+ }
+ }
+
+ @Test
+ public void testSwitchState() {
+
+ SimplePropertyValueModel<Boolean> booleanHolder =
+ new SimplePropertyValueModel<Boolean>(true);
+
+ DialogPane<Node> pane = new DialogPane<Node>(
+ new SimplePropertyValueModel<Node>(),
+ parent)
+ {
+ @Override
+ protected void initializeLayout(Composite container) {
+ }
+ };
+
+ new PaneVisibilityEnabler(booleanHolder, pane);
+
+ assertTrue(
+ "The pane should be visible",
+ pane.getControl().isVisible()
+ );
+
+ // Change state (null)
+ booleanHolder.setValue(null);
+
+ assertFalse(
+ "The pane should not be visible",
+ pane.getControl().isVisible()
+ );
+
+ // Change state (true)
+ booleanHolder.setValue(true);
+
+ assertTrue(
+ "The pane should be visible",
+ pane.getControl().isVisible()
+ );
+
+ // Change state (false)
+ booleanHolder.setValue(false);
+
+ assertFalse(
+ "The pane should not be visible",
+ pane.getControl().isVisible()
+ );
+
+ // Dispose
+ pane.dispose();
+ booleanHolder.setValue(true);
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/BooleanStateControllerUITest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/BooleanStateControllerUITest.java
new file mode 100644
index 0000000000..a476861e2b
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/BooleanStateControllerUITest.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 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.tests.internal.utility.swt;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.value.SimpleListValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Play around with boolean state controllers ('enabled' and 'visible').
+ * <p>
+ * Note the behavior of composites:<ul>
+ * <li>When a composite is disabled, its children are disabled but <em>not</em>
+ * grayed out.
+ * <li>When a composite is made invisible, its children are also made
+ * invisible.
+ * </ul>
+ */
+@SuppressWarnings("nls")
+public class BooleanStateControllerUITest
+ extends ApplicationWindow
+{
+ private final WritablePropertyValueModel<Boolean> enabledHolder;
+ private final WritablePropertyValueModel<Boolean> visibleHolder;
+ private final SimpleListValueModel<String> listHolder;
+ private final WritablePropertyValueModel<String> listSelectionHolder;
+
+ public static void main(String[] args) throws Exception {
+ Window window = new BooleanStateControllerUITest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private BooleanStateControllerUITest(@SuppressWarnings("unused") String[] args) {
+ super(null);
+ this.enabledHolder = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+ this.visibleHolder = new SimplePropertyValueModel<Boolean>(Boolean.TRUE);
+ this.listHolder = this.buildListHolder();
+ this.listSelectionHolder = new SimplePropertyValueModel<String>(null);
+ }
+
+ private SimpleListValueModel<String> buildListHolder() {
+ SimpleListValueModel<String> result = new SimpleListValueModel<String>();
+ result.add("zero");
+ result.add("one");
+ result.add("two");
+ result.add("three");
+ result.add("four");
+ result.add("five");
+ result.add("six");
+ result.add("seven");
+ return result;
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(500, 150);
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayout(new FormLayout());
+ Control widgetPanel = this.buildWidgetPanels(mainPanel);
+ this.buildControlPanel(mainPanel, widgetPanel);
+ return mainPanel;
+ }
+
+ private Control buildWidgetPanels(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100, -35);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout(SWT.VERTICAL));
+
+ this.buildWidgetPanel1(panel);
+ this.buildWidgetPanel2(panel);
+
+ return panel;
+ }
+
+ private void buildWidgetPanel1(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayout(new FillLayout(SWT.HORIZONTAL));
+
+ Button enabledComboBoxCheckBox = this.buildEnabledComboBoxCheckBox(panel);
+ SWTTools.bind(this.enabledHolder, enabledComboBoxCheckBox);
+
+ Button visibleComboBoxCheckBox = this.buildVisibleComboBoxCheckBox(panel);
+ SWTTools.bind(this.visibleHolder, visibleComboBoxCheckBox);
+
+ Label comboBoxLabel = this.buildComboBoxLabel(panel);
+ Combo comboBox = this.buildComboBox(panel);
+ SWTTools.bind(this.listHolder, this.listSelectionHolder, comboBox);
+ SWTTools.controlEnabledState(this.enabledHolder, comboBoxLabel, comboBox);
+ SWTTools.controlVisibleState(this.visibleHolder, comboBoxLabel, comboBox);
+ }
+
+ private Button buildEnabledComboBoxCheckBox(Composite parent) {
+ return this.buildCheckBox(parent, "enabled");
+ }
+
+ private Button buildVisibleComboBoxCheckBox(Composite parent) {
+ return this.buildCheckBox(parent, "visible");
+ }
+
+ private Button buildCheckBox(Composite parent, String text) {
+ Button checkBox = new Button(parent, SWT.CHECK);
+ checkBox.setText(text);
+ return checkBox;
+ }
+
+ private Label buildComboBoxLabel(Composite parent) {
+ Label label = new Label(parent, SWT.LEFT);
+ label.setText("list:");
+ return label;
+ }
+
+ private Combo buildComboBox(Composite parent) {
+ return new Combo(parent, SWT.READ_ONLY);
+ }
+
+ private void buildWidgetPanel2(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayout(new FillLayout(SWT.HORIZONTAL));
+
+ Button checkBox1 = this.buildCheckBox(panel, "one");
+ this.buildCheckBox(panel, "two");
+ this.buildCheckBox(panel, "three");
+ this.buildCheckBox(panel, "four");
+
+ SWTTools.controlEnabledState(this.enabledHolder, panel, checkBox1);
+ SWTTools.controlVisibleState(this.visibleHolder, panel);
+ }
+
+ private void buildControlPanel(Composite parent, Control widgetPanel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(widgetPanel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildClearEnabledModelButton(panel);
+ this.buildClearVisibleModelButton(panel);
+ this.buildNullSelectionModelButton(panel);
+ this.buildNextButton(panel);
+ }
+
+ private void buildClearEnabledModelButton(Composite parent) {
+ this.buildClearEnabledModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildClearEnabledModelACI() {
+ Action action = new Action("clear enabled model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ BooleanStateControllerUITest.this.clearEnabledModel();
+ }
+ };
+ action.setToolTipText("clear enabled model");
+ return new ActionContributionItem(action);
+ }
+
+ void clearEnabledModel() {
+ this.enabledHolder.setValue(null);
+ }
+
+ private void buildClearVisibleModelButton(Composite parent) {
+ this.buildClearVisibleModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildClearVisibleModelACI() {
+ Action action = new Action("clear visible model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ BooleanStateControllerUITest.this.clearVisibleModel();
+ }
+ };
+ action.setToolTipText("clear visible model");
+ return new ActionContributionItem(action);
+ }
+
+ void clearVisibleModel() {
+ this.visibleHolder.setValue(null);
+ }
+
+ private void buildNullSelectionModelButton(Composite parent) {
+ this.buildNullSelectionModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildNullSelectionModelACI() {
+ Action action = new Action("null selection model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ BooleanStateControllerUITest.this.setSelectionModelNull();
+ }
+ };
+ action.setToolTipText("null selection model");
+ return new ActionContributionItem(action);
+ }
+
+ void setSelectionModelNull() {
+ this.listSelectionHolder.setValue(null);
+ }
+
+ private void buildNextButton(Composite parent) {
+ this.buildNextACI().fill(parent);
+ }
+
+ private ActionContributionItem buildNextACI() {
+ Action action = new Action("next", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ BooleanStateControllerUITest.this.next();
+ }
+ };
+ action.setToolTipText("next");
+ return new ActionContributionItem(action);
+ }
+
+ void next() {
+ this.listSelectionHolder.setValue(this.getNextListSelection());
+ }
+
+ private String getNextListSelection() {
+ return this.listHolder.get(this.getNextListSelectionIndex());
+ }
+
+ private int getNextListSelectionIndex() {
+ int index = this.getListSelectionIndex();
+ if (index == -1) {
+ return 0;
+ }
+ index++;
+ return (index == this.listHolder.size()) ? 0 : index;
+ }
+
+ private int getListSelectionIndex() {
+ return this.listHolder.indexOf(this.getListSelection());
+ }
+
+ private String getListSelection() {
+ return this.listSelectionHolder.getValue();
+ }
+
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/CheckBoxModelBindingUITest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/CheckBoxModelBindingUITest.java
new file mode 100644
index 0000000000..6220dae3f3
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/CheckBoxModelBindingUITest.java
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * 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.tests.internal.utility.swt;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Play around with a set of check boxes.
+ */
+@SuppressWarnings("nls")
+public class CheckBoxModelBindingUITest
+ extends ApplicationWindow
+{
+ private final TestModel testModel;
+ private final WritablePropertyValueModel<TestModel> testModelHolder;
+ private final WritablePropertyValueModel<Boolean> flag1Holder;
+ private final WritablePropertyValueModel<Boolean> flag2Holder;
+ private final WritablePropertyValueModel<Boolean> notFlag2Holder;
+
+ public static void main(String[] args) throws Exception {
+ Window window = new CheckBoxModelBindingUITest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private CheckBoxModelBindingUITest(@SuppressWarnings("unused") String[] args) {
+ super(null);
+ this.testModel = new TestModel(true, true);
+ this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+ this.flag1Holder = this.buildFlag1Holder(this.testModelHolder);
+ this.flag2Holder = this.buildFlag2Holder(this.testModelHolder);
+ this.notFlag2Holder = this.buildNotFlag2Holder(this.testModelHolder);
+ }
+
+ private WritablePropertyValueModel<Boolean> buildFlag1Holder(PropertyValueModel<TestModel> subjectHolder) {
+ return new PropertyAspectAdapter<TestModel, Boolean>(subjectHolder, TestModel.FLAG1_PROPERTY) {
+ @Override
+ protected Boolean buildValue_() {
+ return Boolean.valueOf(this.subject.isFlag1());
+ }
+ @Override
+ protected void setValue_(Boolean value) {
+ this.subject.setFlag1(value.booleanValue());
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Boolean> buildFlag2Holder(PropertyValueModel<TestModel> subjectHolder) {
+ return new PropertyAspectAdapter<TestModel, Boolean>(subjectHolder, TestModel.FLAG2_PROPERTY) {
+ @Override
+ protected Boolean buildValue_() {
+ return Boolean.valueOf(this.subject.isFlag2());
+ }
+ @Override
+ protected void setValue_(Boolean value) {
+ this.subject.setFlag2(value.booleanValue());
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Boolean> buildNotFlag2Holder(PropertyValueModel<TestModel> subjectHolder) {
+ return new PropertyAspectAdapter<TestModel, Boolean>(subjectHolder, TestModel.NOT_FLAG2_PROPERTY) {
+ @Override
+ protected Boolean buildValue_() {
+ return Boolean.valueOf(this.subject.isNotFlag2());
+ }
+ @Override
+ protected void setValue_(Boolean value) {
+ this.subject.setNotFlag2(value.booleanValue());
+ }
+ };
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(400, 100);
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayout(new FormLayout());
+ Control checkBoxPanel = this.buildCheckBoxPanel(mainPanel);
+ this.buildControlPanel(mainPanel, checkBoxPanel);
+ return mainPanel;
+ }
+
+ private Control buildCheckBoxPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100, -35);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildFlag1CheckBox(panel);
+ this.buildFlag2CheckBox(panel);
+ this.buildNotFlag2CheckBox(panel);
+ this.buildUnattachedCheckBox(panel);
+
+ return panel;
+ }
+
+ private void buildFlag1CheckBox(Composite parent) {
+ Button checkBox = new Button(parent, SWT.CHECK);
+ checkBox.setText("flag 1");
+ SWTTools.bind(this.flag1Holder, checkBox);
+ }
+
+ private void buildFlag2CheckBox(Composite parent) {
+ Button checkBox = new Button(parent, SWT.CHECK);
+ checkBox.setText("flag 2");
+ SWTTools.bind(this.flag2Holder, checkBox);
+ }
+
+ private void buildNotFlag2CheckBox(Composite parent) {
+ Button checkBox = new Button(parent, SWT.CHECK);
+ checkBox.setText("not flag 2");
+ SWTTools.bind(this.notFlag2Holder, checkBox);
+ }
+
+ private void buildUnattachedCheckBox(Composite parent) {
+ Button checkBox = new Button(parent, SWT.CHECK);
+ checkBox.setText("unattached");
+ checkBox.addSelectionListener(this.buildUnattachedSelectionListener());
+ }
+
+ private SelectionListener buildUnattachedSelectionListener() {
+ return new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ System.out.println("unattached default selected: " + e);
+ }
+ public void widgetSelected(SelectionEvent e) {
+ System.out.println("unattached selected: " + e);
+ }
+ };
+ }
+
+ private void buildControlPanel(Composite parent, Control checkBoxPanel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(checkBoxPanel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildFlipFlag1Button(panel);
+ this.buildNotFlag2ToggleButton(panel);
+ this.buildClearModelButton(panel);
+ this.buildRestoreModelButton(panel);
+ this.buildPrintModelButton(panel);
+ }
+
+ private void buildFlipFlag1Button(Composite parent) {
+ this.buildFlipFlag1ACI().fill(parent);
+ }
+
+ private ActionContributionItem buildFlipFlag1ACI() {
+ Action action = new Action("flip flag 1", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ CheckBoxModelBindingUITest.this.flipFlag1();
+ }
+ };
+ action.setToolTipText("flip flag 1");
+ return new ActionContributionItem(action);
+ }
+
+ void flipFlag1() {
+ this.testModel.setFlag1( ! this.testModel.isFlag1());
+ }
+
+ private void buildNotFlag2ToggleButton(Composite parent) {
+ Button checkBox = new Button(parent, SWT.TOGGLE);
+ checkBox.setText("not flag 2");
+ SWTTools.bind(this.notFlag2Holder, checkBox);
+ }
+
+ private void buildClearModelButton(Composite parent) {
+ this.buildClearModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildClearModelACI() {
+ Action action = new Action("clear model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ CheckBoxModelBindingUITest.this.clearModel();
+ }
+ };
+ action.setToolTipText("clear model");
+ return new ActionContributionItem(action);
+ }
+
+ void clearModel() {
+ this.testModelHolder.setValue(null);
+ }
+
+ private void buildRestoreModelButton(Composite parent) {
+ this.buildRestoreModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildRestoreModelACI() {
+ Action action = new Action("restore model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ CheckBoxModelBindingUITest.this.restoreModel();
+ }
+ };
+ action.setToolTipText("restore model");
+ return new ActionContributionItem(action);
+ }
+
+ void restoreModel() {
+ this.testModelHolder.setValue(this.testModel);
+ }
+
+ private void buildPrintModelButton(Composite parent) {
+ this.buildPrintModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildPrintModelACI() {
+ Action action = new Action("print model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ CheckBoxModelBindingUITest.this.printModel();
+ }
+ };
+ action.setToolTipText("print model");
+ return new ActionContributionItem(action);
+ }
+
+ void printModel() {
+ System.out.println("flag 1: " + this.testModel.isFlag1());
+ System.out.println("flag 2: " + this.testModel.isFlag2());
+ System.out.println("not flag 2: " + this.testModel.isNotFlag2());
+ System.out.println("***");
+ }
+
+
+ public static class TestModel extends AbstractModel {
+ private boolean flag1;
+ public static final String FLAG1_PROPERTY = "flag1";
+ private boolean flag2;
+ public static final String FLAG2_PROPERTY = "flag2";
+ private boolean notFlag2;
+ public static final String NOT_FLAG2_PROPERTY = "notFlag2";
+
+ public TestModel(boolean flag1, boolean flag2) {
+ this.flag1 = flag1;
+ this.flag2 = flag2;
+ this.notFlag2 = ! flag2;
+ }
+ public boolean isFlag1() {
+ return this.flag1;
+ }
+ public void setFlag1(boolean flag1) {
+ boolean old = this.flag1;
+ this.flag1 = flag1;
+ this.firePropertyChanged(FLAG1_PROPERTY, old, flag1);
+ }
+ public boolean isFlag2() {
+ return this.flag2;
+ }
+ public void setFlag2(boolean flag2) {
+ boolean old = this.flag2;
+ this.flag2 = flag2;
+ this.firePropertyChanged(FLAG2_PROPERTY, old, flag2);
+
+ old = this.notFlag2;
+ this.notFlag2 = ! flag2;
+ this.firePropertyChanged(NOT_FLAG2_PROPERTY, old, this.notFlag2);
+ }
+ public boolean isNotFlag2() {
+ return this.notFlag2;
+ }
+ public void setNotFlag2(boolean notFlag2) {
+ this.setFlag2( ! notFlag2);
+ }
+ @Override
+ public String toString() {
+ return "TestModel(" + this.isFlag1() + " - " + this.isFlag2() + ")";
+ }
+ }
+
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/DropDownListBoxModelBindingUITest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/DropDownListBoxModelBindingUITest.java
new file mode 100644
index 0000000000..8ca1962cd0
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/DropDownListBoxModelBindingUITest.java
@@ -0,0 +1,664 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 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.tests.internal.utility.swt;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelWrapper;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Play around with a set of read-only combo-boxes.
+ */
+@SuppressWarnings("nls")
+public class DropDownListBoxModelBindingUITest
+ extends ApplicationWindow
+{
+ final TaskList taskList;
+ private final WritablePropertyValueModel<TaskList> taskListHolder;
+ private Text taskTextField;
+
+ public static void main(String[] args) throws Exception {
+ Window window = new DropDownListBoxModelBindingUITest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private DropDownListBoxModelBindingUITest(@SuppressWarnings("unused") String[] args) {
+ super(null);
+ this.taskList = new TaskList();
+ this.taskListHolder = new SimplePropertyValueModel<TaskList>(this.taskList);
+ this.taskList.addTask("swim");
+ this.taskList.addTask("bike");
+ this.taskList.addTask("run");
+ Task rest = this.taskList.addTask("rest");
+ this.taskList.addTask("repeat");
+ this.taskList.setPriorityTask(rest);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(800, 300);
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayout(new FormLayout());
+ Control taskListPanel = this.buildTaskListPanel(mainPanel);
+ this.buildControlPanel(mainPanel, taskListPanel);
+ return mainPanel;
+ }
+
+ private Control buildTaskListPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100, -30);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ this.buildTaskListPanel_(panel); // false = native (Combo)
+
+ return panel;
+ }
+
+ private Control buildTaskListPanel_(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(50);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ this.buildPrimitiveTaskListPanel(panel);
+ this.buildObjectTaskListPanel(panel);
+
+ return panel;
+ }
+
+ private void buildPrimitiveTaskListPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(50);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildUnsortedPrimitiveListPanel(panel);
+ this.buildStandardSortedPrimitiveListPanel(panel);
+ this.buildCustomSortedPrimitiveListPanel(panel);
+ }
+
+ private void buildObjectTaskListPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(50);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildUnsortedObjectListPanel(panel);
+ this.buildStandardSortedObjectListPanel(panel);
+ this.buildCustomSortedObjectListPanel(panel);
+ }
+
+ private void buildUnsortedPrimitiveListPanel(Composite parent) {
+ String label = "primitive unsorted";
+ this.buildComboBoxPanel(parent, label, this.buildUnsortedPrimitiveListModel(), this.buildPriorityTaskNameAdapter());
+ }
+
+ private void buildStandardSortedPrimitiveListPanel(Composite parent) {
+ String label = "primitive sorted";
+ this.buildComboBoxPanel(parent, label, this.buildStandardSortedPrimitiveListModel(), this.buildPriorityTaskNameAdapter());
+ }
+
+ private void buildCustomSortedPrimitiveListPanel(Composite parent) {
+ String label = "primitive reverse sorted";
+ this.buildComboBoxPanel(parent, label, this.buildCustomSortedPrimitiveListModel(), this.buildPriorityTaskNameAdapter());
+ }
+
+ private void buildUnsortedObjectListPanel(Composite parent) {
+ String label = "object unsorted";
+ this.buildComboBoxPanel(parent, label, this.buildUnsortedObjectListModel(), this.buildPriorityTaskAdapter());
+ }
+
+ private void buildStandardSortedObjectListPanel(Composite parent) {
+ String label = "object sorted";
+ this.buildComboBoxPanel(parent, label, this.buildStandardSortedObjectListModel(), this.buildPriorityTaskAdapter());
+ }
+
+ private void buildCustomSortedObjectListPanel(Composite parent) {
+ String label = "object reverse sorted";
+ this.buildComboBoxPanel(parent, label, this.buildCustomSortedObjectListModel(), this.buildPriorityTaskAdapter());
+ }
+
+ private ListValueModel<String> buildUnsortedPrimitiveListModel() {
+ return this.buildPrimitiveTaskListAdapter();
+ }
+
+ private ListValueModel<String> buildStandardSortedPrimitiveListModel() {
+ return new SortedListValueModelWrapper<String>(this.buildPrimitiveTaskListAdapter());
+ }
+
+ private ListValueModel<String> buildCustomSortedPrimitiveListModel() {
+ return new SortedListValueModelWrapper<String>(this.buildPrimitiveTaskListAdapter(), this.buildCustomStringComparator());
+ }
+
+ private ListValueModel<Task> buildUnsortedObjectListModel() {
+ return this.buildObjectTaskListAdapter();
+ }
+
+ private ListValueModel<Task> buildStandardSortedObjectListModel() {
+ return new SortedListValueModelWrapper<Task>(this.buildObjectTaskListAdapter());
+ }
+
+ private ListValueModel<Task> buildCustomSortedObjectListModel() {
+ return new SortedListValueModelWrapper<Task>(this.buildObjectTaskListAdapter(), this.buildCustomTaskComparator());
+ }
+
+ private <E> void buildComboBoxPanel(Composite parent, String label, ListValueModel<E> model, WritablePropertyValueModel<E> selectedItemModel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayout(new FormLayout());
+
+ Label comboBoxLabel = new Label(panel, SWT.LEFT | SWT.VERTICAL);
+ comboBoxLabel.setText(label);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0, 3);
+ fd.bottom = new FormAttachment(0, 20);
+ fd.left = new FormAttachment(0, 5);
+ fd.right = new FormAttachment(100);
+ comboBoxLabel.setLayoutData(fd);
+
+ Combo comboBox = this.buildComboBox(panel);
+ fd = new FormData();
+ fd.top = new FormAttachment(comboBoxLabel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ comboBox.setLayoutData(fd);
+ SWTTools.bind(model, selectedItemModel, comboBox); // use #toString()
+ }
+
+ private Combo buildComboBox(Composite parent) {
+ return new Combo(parent, SWT.READ_ONLY);
+ }
+
+ private Comparator<String> buildCustomStringComparator() {
+ return new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return s2.compareTo(s1);
+ }
+ };
+ }
+
+ private Comparator<Task> buildCustomTaskComparator() {
+ return new Comparator<Task>() {
+ public int compare(Task to1, Task to2) {
+ return to2.compareTo(to1);
+ }
+ };
+ }
+
+ private ListValueModel<String> buildPrimitiveTaskListAdapter() {
+ return new ListAspectAdapter<TaskList, String>(this.taskListHolder, TaskList.TASK_NAMES_LIST) {
+ @Override
+ protected ListIterator<String> listIterator_() {
+ return this.subject.taskNames();
+ }
+ };
+ }
+
+ private ListValueModel<Task> buildObjectTaskListAdapter() {
+ return new ListAspectAdapter<TaskList, Task>(this.taskListHolder, TaskList.TASKS_LIST) {
+ @Override
+ protected ListIterator<Task> listIterator_() {
+ return this.subject.tasks();
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<Task> buildPriorityTaskAdapter() {
+ return new PriorityTaskAdapter(this.taskListHolder);
+ }
+
+ static class PriorityTaskAdapter
+ extends PropertyAspectAdapter<TaskList, Task>
+ {
+ PriorityTaskAdapter(WritablePropertyValueModel<TaskList> taskListHolder) {
+ super(taskListHolder, TaskList.PRIORITY_TASK_PROPERTY);
+ }
+ @Override
+ protected Task buildValue_() {
+ return this.subject.getPriorityTask();
+ }
+ @Override
+ protected void setValue_(Task value) {
+ this.subject.setPriorityTask(value);
+ }
+ }
+
+ private WritablePropertyValueModel<String> buildPriorityTaskNameAdapter() {
+ return new PriorityTaskNameAdapter(this.taskListHolder);
+ }
+
+ static class PriorityTaskNameAdapter
+ extends PropertyAspectAdapter<TaskList, String>
+ {
+ PriorityTaskNameAdapter(WritablePropertyValueModel<TaskList> taskListHolder) {
+ super(taskListHolder, TaskList.PRIORITY_TASK_NAME_PROPERTY);
+ }
+ @Override
+ protected String buildValue_() {
+ return this.subject.getPriorityTaskName();
+ }
+ @Override
+ protected void setValue_(String value) {
+ // ignore
+ }
+ }
+
+ private void buildControlPanel(Composite parent, Control taskListPanel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(taskListPanel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ Control misc = this.buildMiscTaskPanel(panel);
+ this.buildAddRemoveTaskPanel(panel, misc);
+ }
+
+ // is there a better way to associate an ACI with form data?
+ private Control buildMiscTaskPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(100, -400);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildClearListACI().fill(panel);
+ this.buildClearModelACI().fill(panel);
+ this.buildRestoreModelACI().fill(panel);
+ this.buildChangePriorityTaskACI().fill(panel);
+ this.buildClearPriorityTaskACI().fill(panel);
+ return panel;
+ }
+
+ private ActionContributionItem buildClearListACI() {
+ Action action = new Action("clear list", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.clearTasks();
+ }
+ };
+ action.setToolTipText("clear all the tasks");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildClearModelACI() {
+ Action action = new Action("clear model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.clearModel();
+ }
+ };
+ action.setToolTipText("clear the task list model");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildRestoreModelACI() {
+ Action action = new Action("restore model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.restoreModel();
+ }
+ };
+ action.setToolTipText("restore the task list model");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildChangePriorityTaskACI() {
+ Action action = new Action("change priority", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.changePriorityTask();
+ }
+ };
+ action.setToolTipText("change the priority task");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildClearPriorityTaskACI() {
+ Action action = new Action("clear priority", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.clearPriorityTask();
+ }
+ };
+ action.setToolTipText("clear the priority task");
+ return new ActionContributionItem(action);
+ }
+
+ private void buildAddRemoveTaskPanel(Composite parent, Control clearButton) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(clearButton);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ Control addButton = this.buildAddButton(panel);
+ Control removeButton = this.buildRemoveButton(panel);
+ this.buildTaskTextField(panel, addButton, removeButton);
+ }
+
+ // is there a better way to associate an ACI with form data?
+ private Control buildAddButton(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(0, 50);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildAddACI().fill(panel);
+ return panel;
+ }
+
+ private ActionContributionItem buildAddACI() {
+ Action action = new Action("add", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.addTask();
+ }
+ };
+ action.setToolTipText("add a task with the name in the entry field");
+ return new ActionContributionItem(action);
+ }
+
+ // is there a better way to associate an ACI with form data?
+ private Control buildRemoveButton(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(100, -50);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildRemoveACI().fill(panel);
+ return panel;
+ }
+
+ private ActionContributionItem buildRemoveACI() {
+ Action action = new Action("remove", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ DropDownListBoxModelBindingUITest.this.removeTask();
+ }
+ };
+ action.setToolTipText("remove the task with the name in the entry field");
+ return new ActionContributionItem(action);
+ }
+
+ private void buildTaskTextField(Composite parent, Control addButton, Control removeButton) {
+ this.taskTextField = new Text(parent, SWT.SINGLE | SWT.BORDER);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(addButton);
+ fd.right = new FormAttachment(removeButton);
+ this.taskTextField.setLayoutData(fd);
+ }
+
+ private String taskTextFieldText() {
+ return this.taskTextField.getText();
+ }
+
+ void addTask() {
+ String taskText = this.taskTextFieldText();
+ if (taskText.length() != 0) {
+ this.taskList.addTask(taskText);
+ }
+ }
+
+ void removeTask() {
+ String task = this.taskTextFieldText();
+ if (task.length() != 0) {
+ this.taskList.removeTask(task);
+ }
+ }
+
+ void clearTasks() {
+ this.taskList.clearTasks();
+ }
+
+ void clearModel() {
+ this.taskListHolder.setValue(null);
+ }
+
+ void restoreModel() {
+ this.taskListHolder.setValue(this.taskList);
+ }
+
+ void changePriorityTask() {
+ boolean found = false;
+ for (Task task : this.taskList.getTasks()) {
+ if (this.taskList.getPriorityTask() == task) {
+ found = true;
+ } else {
+ if (found) {
+ this.taskList.setPriorityTask(task);
+ return;
+ }
+ }
+ }
+ Iterator<Task> tasks = this.taskList.tasks();
+ if (tasks.hasNext()) {
+ this.taskList.setPriorityTask(tasks.next());
+ }
+ }
+
+ void clearPriorityTask() {
+ this.taskList.setPriorityTask(null);
+ }
+
+
+ // ********** TaskList **********
+
+ // note absence of validation...
+ public static class TaskList extends AbstractModel {
+ private final List<String> taskNames = new ArrayList<String>();
+ public static final String TASK_NAMES_LIST = "taskNames";
+ private final List<Task> tasks = new ArrayList<Task>();
+ public static final String TASKS_LIST = "tasks";
+ private String priorityTaskName = null;
+ public static final String PRIORITY_TASK_NAME_PROPERTY = "priorityTaskName";
+ private Task priorityTask = null;
+ public static final String PRIORITY_TASK_PROPERTY = "priorityTask";
+ public TaskList() {
+ super();
+ }
+ public ListIterator<String> taskNames() {
+ return this.taskNames.listIterator();
+ }
+ public Iterable<Task> getTasks() {
+ return this.tasks;
+ }
+ public ListIterator<Task> tasks() {
+ return this.tasks.listIterator();
+ }
+ public String getPriorityTaskName() {
+ return this.priorityTaskName;
+ }
+ public Task getPriorityTask() {
+ return this.priorityTask;
+ }
+ public Task addTask(String taskName) {
+ this.addItemToList(taskName, this.taskNames, TASK_NAMES_LIST);
+ Task task = new Task(taskName);
+ this.addItemToList(task, this.tasks, TASKS_LIST);
+ return task;
+ }
+ public void removeTask(String taskName) {
+ int index = this.taskNames.indexOf(taskName);
+ if (index != -1) {
+ Task task = this.tasks.get(index);
+ if (task == this.priorityTask) {
+ this.setPriorityTask(null);
+ }
+ // assume the indexes match...
+ this.removeItemFromList(index, this.taskNames, TASK_NAMES_LIST);
+ this.removeItemFromList(index, this.tasks, TASKS_LIST);
+ }
+ }
+ public void clearTasks() {
+ this.setPriorityTask(null);
+ this.clearList(this.taskNames, TASK_NAMES_LIST);
+ this.clearList(this.tasks, TASKS_LIST);
+ }
+ private void setPriorityTaskName(String priorityTaskName) {
+ String old = this.priorityTaskName;
+ this.priorityTaskName = priorityTaskName;
+ this.firePropertyChanged(PRIORITY_TASK_NAME_PROPERTY, old, priorityTaskName);
+ }
+ public void setPriorityTask(Task priorityTask) {
+ Task old = this.priorityTask;
+ this.priorityTask = priorityTask;
+ this.firePropertyChanged(PRIORITY_TASK_PROPERTY, old, priorityTask);
+ this.setPriorityTaskName((priorityTask == null) ? null : priorityTask.getName());
+ }
+ }
+
+
+ // ********** Task **********
+
+ public static class Task extends AbstractModel implements Displayable {
+ private String name;
+ private int instanceCount;
+ private static int INSTANCE_COUNT = 1;
+ public Task(String name) {
+ this.name = name;
+ this.instanceCount = INSTANCE_COUNT++;
+ }
+ public String displayString() {
+ return this.name + ": " + this.instanceCount;
+ }
+ public int compareTo(Displayable o) {
+ return DEFAULT_COMPARATOR.compare(this, o);
+ }
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ Object old = this.name;
+ this.name = name;
+ this.firePropertyChanged(DISPLAY_STRING_PROPERTY, old, name);
+ }
+ @Override
+ public String toString() {
+ return this.displayString();
+ }
+ }
+
+ public interface Displayable extends Model, Comparable<Displayable> {
+
+ String displayString();
+ String DISPLAY_STRING_PROPERTY = "displayString";
+
+
+ // ********** helper implementations **********
+
+ Collator DEFAULT_COLLATOR = Collator.getInstance();
+
+ Comparator<Displayable> DEFAULT_COMPARATOR =
+ new Comparator<Displayable>() {
+ public int compare(Displayable d1, Displayable d2) {
+ // disallow duplicates based on object identity
+ if (d1 == d2) {
+ return 0;
+ }
+
+ // first compare display strings using the default collator
+ int result = DEFAULT_COLLATOR.compare(d1.displayString(), d2.displayString());
+ if (result != 0) {
+ return result;
+ }
+
+ // then compare using object-id
+ result = System.identityHashCode(d1) - System.identityHashCode(d2);
+ if (result != 0) {
+ return result;
+ }
+
+ // It's unlikely that we get to this point; but, just in case, we will return -1.
+ // Unfortunately, this introduces some mild unpredictability to the sort order
+ // (unless the objects are always passed into this method in the same order).
+ return -1; // if all else fails, indicate that o1 < o2
+ }
+ @Override
+ public String toString() {
+ return "Displayable.DEFAULT_COMPARATOR";
+ }
+ };
+
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/ListBoxModelBindingUITest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/ListBoxModelBindingUITest.java
new file mode 100644
index 0000000000..ebc80085ed
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/ListBoxModelBindingUITest.java
@@ -0,0 +1,626 @@
+/*******************************************************************************
+ * 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.tests.internal.utility.swt;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.CollectionAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.ListAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimpleCollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.SortedListValueModelWrapper;
+import org.eclipse.jpt.utility.model.Model;
+import org.eclipse.jpt.utility.model.value.ListValueModel;
+import org.eclipse.jpt.utility.model.value.WritableCollectionValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Play around with a set of list boxes.
+ */
+@SuppressWarnings("nls")
+public class ListBoxModelBindingUITest
+ extends ApplicationWindow
+{
+ final TaskList taskList;
+ private final WritablePropertyValueModel<TaskList> taskListHolder;
+ private Text taskTextField;
+
+ public static void main(String[] args) throws Exception {
+ Window window = new ListBoxModelBindingUITest(args);
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private ListBoxModelBindingUITest(@SuppressWarnings("unused") String[] args) {
+ super(null);
+ this.taskList = new TaskList();
+ this.taskListHolder = new SimplePropertyValueModel<TaskList>(this.taskList);
+ this.taskList.addTask("swim");
+ this.taskList.addTask("bike");
+ this.taskList.addTask("run");
+ Task rest = this.taskList.addTask("rest");
+ this.taskList.addPriorityTask(rest);
+ Task repeat = this.taskList.addTask("repeat");
+ this.taskList.addPriorityTask(repeat);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(800, 400);
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayout(new FormLayout());
+ Control taskListPanel = this.buildTaskListPanel(mainPanel);
+ this.buildControlPanel(mainPanel, taskListPanel);
+ return mainPanel;
+ }
+
+ private Control buildTaskListPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100, -30);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ this.buildPrimitiveTaskListPanel(panel);
+ this.buildObjectTaskListPanel(panel);
+
+ return panel;
+ }
+
+ private void buildPrimitiveTaskListPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(50);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildUnsortedPrimitiveListPanel(panel);
+ this.buildStandardSortedPrimitiveListPanel(panel);
+ this.buildCustomSortedPrimitiveListPanel(panel);
+ }
+
+ private void buildObjectTaskListPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(50);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildUnsortedObjectListPanel(panel);
+ this.buildStandardSortedObjectListPanel(panel);
+ this.buildCustomSortedObjectListPanel(panel);
+ }
+
+ private void buildUnsortedPrimitiveListPanel(Composite parent) {
+ this.buildListPanel(parent, "primitive unsorted", this.buildUnsortedPrimitiveListModel(), new SimpleCollectionValueModel<String>());
+ }
+
+ private void buildStandardSortedPrimitiveListPanel(Composite parent) {
+ this.buildListPanel(parent, "primitive sorted", this.buildStandardSortedPrimitiveListModel(), new SimpleCollectionValueModel<String>());
+ }
+
+ private void buildCustomSortedPrimitiveListPanel(Composite parent) {
+ this.buildListPanel(parent, "primitive reverse sorted", this.buildCustomSortedPrimitiveListModel(), new SimpleCollectionValueModel<String>());
+ }
+
+ private void buildUnsortedObjectListPanel(Composite parent) {
+ this.buildListPanel(parent, "object unsorted", this.buildUnsortedObjectListModel(), this.buildPriorityTaskListAdapter());
+ }
+
+ private void buildStandardSortedObjectListPanel(Composite parent) {
+ this.buildListPanel(parent, "object sorted", this.buildStandardSortedObjectListModel(), this.buildPriorityTaskListAdapter());
+ }
+
+ private void buildCustomSortedObjectListPanel(Composite parent) {
+ this.buildListPanel(parent, "object reverse sorted", this.buildCustomSortedObjectListModel(), this.buildPriorityTaskListAdapter());
+ }
+
+ private ListValueModel<String> buildUnsortedPrimitiveListModel() {
+ return this.buildPrimitiveTaskListAdapter();
+ }
+
+ private ListValueModel<String> buildStandardSortedPrimitiveListModel() {
+ return new SortedListValueModelWrapper<String>(this.buildPrimitiveTaskListAdapter());
+ }
+
+ private ListValueModel<String> buildCustomSortedPrimitiveListModel() {
+ return new SortedListValueModelWrapper<String>(this.buildPrimitiveTaskListAdapter(), this.buildCustomStringComparator());
+ }
+
+ private ListValueModel<Task> buildUnsortedObjectListModel() {
+ return this.buildObjectTaskListAdapter();
+ }
+
+ private ListValueModel<Task> buildStandardSortedObjectListModel() {
+ return new SortedListValueModelWrapper<Task>(this.buildObjectTaskListAdapter());
+ }
+
+ private ListValueModel<Task> buildCustomSortedObjectListModel() {
+ return new SortedListValueModelWrapper<Task>(this.buildObjectTaskListAdapter(), this.buildCustomTaskComparator());
+ }
+
+ private <E> org.eclipse.swt.widgets.List buildListPanel(Composite parent, String label, ListValueModel<E> model, WritableCollectionValueModel<E> selectedItemsModel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayout(new FormLayout());
+
+ Label listLabel = new Label(panel, SWT.LEFT | SWT.VERTICAL);
+ listLabel.setText(label);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0, 3);
+ fd.bottom = new FormAttachment(0, 20);
+ fd.left = new FormAttachment(0, 5);
+ fd.right = new FormAttachment(100);
+ listLabel.setLayoutData(fd);
+
+ org.eclipse.swt.widgets.List listBox = new org.eclipse.swt.widgets.List(panel, SWT.MULTI | SWT.BORDER);
+ fd = new FormData();
+ fd.top = new FormAttachment(listLabel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ listBox.setLayoutData(fd);
+ SWTTools.bind(model, selectedItemsModel, listBox); // use #toString()
+ return listBox;
+ }
+
+ private Comparator<String> buildCustomStringComparator() {
+ return new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return s2.compareTo(s1);
+ }
+ };
+ }
+
+ private Comparator<Task> buildCustomTaskComparator() {
+ return new Comparator<Task>() {
+ public int compare(Task to1, Task to2) {
+ return to2.compareTo(to1);
+ }
+ };
+ }
+
+ private ListValueModel<String> buildPrimitiveTaskListAdapter() {
+ return new ListAspectAdapter<TaskList, String>(this.taskListHolder, TaskList.TASK_NAMES_LIST) {
+ @Override
+ protected ListIterator<String> listIterator_() {
+ return this.subject.taskNames();
+ }
+ };
+ }
+
+ private ListValueModel<Task> buildObjectTaskListAdapter() {
+ return new ListAspectAdapter<TaskList, Task>(this.taskListHolder, TaskList.TASKS_LIST) {
+ @Override
+ protected ListIterator<Task> listIterator_() {
+ return this.subject.tasks();
+ }
+ };
+ }
+
+ private WritableCollectionValueModel<Task> buildPriorityTaskListAdapter() {
+ return new PriorityTaskListAdapter(this.taskListHolder);
+ }
+
+ static class PriorityTaskListAdapter
+ extends CollectionAspectAdapter<TaskList, Task>
+ implements WritableCollectionValueModel<Task>
+ {
+ PriorityTaskListAdapter(WritablePropertyValueModel<TaskList> taskListHolder) {
+ super(taskListHolder, TaskList.PRIORITY_TASKS_COLLECTION);
+ }
+ @Override
+ protected Iterator<Task> iterator_() {
+ return this.subject.priorityTasks();
+ }
+ public void setValues(Iterable<Task> values) {
+ this.subject.setPriorityTasks(values);
+ }
+ }
+
+ private void buildControlPanel(Composite parent, Control taskListPanel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(taskListPanel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ Control misc = this.buildMiscTaskPanel(panel);
+ this.buildAddRemoveTaskPanel(panel, misc);
+ }
+
+ // is there a better way to associate an ACI with form data?
+ private Control buildMiscTaskPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(100, -400);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildClearListACI().fill(panel);
+ this.buildClearModelACI().fill(panel);
+ this.buildRestoreModelACI().fill(panel);
+ this.buildAddPriorityTaskACI().fill(panel);
+ this.buildRemovePriorityTaskACI().fill(panel);
+ this.buildClearPriorityTasksACI().fill(panel);
+ return panel;
+ }
+
+ private ActionContributionItem buildClearListACI() {
+ Action action = new Action("clear list", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.clearTasks();
+ }
+ };
+ action.setToolTipText("clear all the tasks");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildClearModelACI() {
+ Action action = new Action("clear model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.clearModel();
+ }
+ };
+ action.setToolTipText("clear the task list model");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildRestoreModelACI() {
+ Action action = new Action("restore model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.restoreModel();
+ }
+ };
+ action.setToolTipText("restore the task list model");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildAddPriorityTaskACI() {
+ Action action = new Action("add priority", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.addPriorityTask();
+ }
+ };
+ action.setToolTipText("add a task to the priority tasks");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildRemovePriorityTaskACI() {
+ Action action = new Action("remove priority", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.removePriorityTask();
+ }
+ };
+ action.setToolTipText("remove a task from the priority tasks");
+ return new ActionContributionItem(action);
+ }
+
+ private ActionContributionItem buildClearPriorityTasksACI() {
+ Action action = new Action("clear priority", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.clearPriorityTasks();
+ }
+ };
+ action.setToolTipText("clear the priority tasks");
+ return new ActionContributionItem(action);
+ }
+
+ private void buildAddRemoveTaskPanel(Composite parent, Control clearButton) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(clearButton);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FormLayout());
+ Control addButton = this.buildAddButton(panel);
+ Control removeButton = this.buildRemoveButton(panel);
+ this.buildTaskTextField(panel, addButton, removeButton);
+ }
+
+ // is there a better way to associate an ACI with form data?
+ private Control buildAddButton(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(0, 50);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildAddACI().fill(panel);
+ return panel;
+ }
+
+ private ActionContributionItem buildAddACI() {
+ Action action = new Action("add", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.addTask();
+ }
+ };
+ action.setToolTipText("add a task with the name in the entry field");
+ return new ActionContributionItem(action);
+ }
+
+ // is there a better way to associate an ACI with form data?
+ private Control buildRemoveButton(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(100, -50);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildRemoveACI().fill(panel);
+ return panel;
+ }
+
+ private ActionContributionItem buildRemoveACI() {
+ Action action = new Action("remove", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ ListBoxModelBindingUITest.this.removeTask();
+ }
+ };
+ action.setToolTipText("remove the task with the name in the entry field");
+ return new ActionContributionItem(action);
+ }
+
+ private void buildTaskTextField(Composite parent, Control addButton, Control removeButton) {
+ this.taskTextField = new Text(parent, SWT.SINGLE | SWT.BORDER);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(addButton);
+ fd.right = new FormAttachment(removeButton);
+ this.taskTextField.setLayoutData(fd);
+ }
+
+ private String taskTextFieldText() {
+ return this.taskTextField.getText();
+ }
+
+ void addTask() {
+ String taskText = this.taskTextFieldText();
+ if (taskText.length() != 0) {
+ this.taskList.addTask(taskText);
+ }
+ }
+
+ void removeTask() {
+ String task = this.taskTextFieldText();
+ if (task.length() != 0) {
+ this.taskList.removeTask(task);
+ }
+ }
+
+ void clearTasks() {
+ this.taskList.clearTasks();
+ }
+
+ void clearModel() {
+ this.taskListHolder.setValue(null);
+ }
+
+ void restoreModel() {
+ this.taskListHolder.setValue(this.taskList);
+ }
+
+ void addPriorityTask() {
+ Iterator<Task> tasks = this.taskList.tasks();
+ while (tasks.hasNext()) {
+ if (this.taskList.addPriorityTask(tasks.next())) {
+ return;
+ }
+ }
+ }
+
+ void removePriorityTask() {
+ Iterator<Task> pTasks = this.taskList.priorityTasks();
+ if (pTasks.hasNext()) {
+ this.taskList.removePriorityTask(pTasks.next());
+ }
+ }
+
+ void clearPriorityTasks() {
+ this.taskList.clearPriorityTasks();
+ }
+
+
+ // ********** TaskList **********
+
+ // note absence of validation...
+ public static class TaskList extends AbstractModel {
+ private final List<String> taskNames = new ArrayList<String>();
+ public static final String TASK_NAMES_LIST = "taskNames";
+ private final List<Task> tasks = new ArrayList<Task>();
+ public static final String TASKS_LIST = "tasks";
+ private final Collection<Task> priorityTasks = new HashSet<Task>();
+ public static final String PRIORITY_TASKS_COLLECTION = "priorityTasks";
+ public TaskList() {
+ super();
+ }
+ public ListIterator<String> taskNames() {
+ return this.taskNames.listIterator();
+ }
+ public ListIterator<Task> tasks() {
+ return this.tasks.listIterator();
+ }
+ public Iterator<Task> priorityTasks() {
+ return this.priorityTasks.iterator();
+ }
+ public Task addTask(String taskName) {
+ this.addItemToList(taskName, this.taskNames, TASK_NAMES_LIST);
+ Task task = new Task(taskName);
+ this.addItemToList(task, this.tasks, TASKS_LIST);
+ return task;
+ }
+ public void removeTask(String taskName) {
+ int index = this.taskNames.indexOf(taskName);
+ if (index != -1) {
+ this.removeItemFromList(index, this.taskNames, TASK_NAMES_LIST);
+ // assume the indexes match...
+ Task removedTask = this.removeItemFromList(index, this.tasks, TASKS_LIST);
+ this.removeItemFromCollection(removedTask, this.priorityTasks, PRIORITY_TASKS_COLLECTION);
+ }
+ }
+ public void clearTasks() {
+ this.clearCollection(this.priorityTasks, PRIORITY_TASKS_COLLECTION);
+ this.clearList(this.taskNames, TASK_NAMES_LIST);
+ this.clearList(this.tasks, TASKS_LIST);
+ }
+ public boolean addPriorityTask(Task task) {
+ return this.addItemToCollection(task, this.priorityTasks, PRIORITY_TASKS_COLLECTION);
+ }
+ public void removePriorityTask(Task task) {
+ this.removeItemFromCollection(task, this.priorityTasks, PRIORITY_TASKS_COLLECTION);
+ }
+ public void clearPriorityTasks() {
+ this.clearCollection(this.priorityTasks, PRIORITY_TASKS_COLLECTION);
+ }
+ public void setPriorityTasks(Iterable<Task> tasks) {
+ this.priorityTasks.clear();
+ CollectionTools.addAll(this.priorityTasks, tasks);
+ this.fireCollectionChanged(PRIORITY_TASKS_COLLECTION, this.priorityTasks);
+ }
+ }
+
+
+ // ********** Task **********
+
+ public static class Task extends AbstractModel implements Displayable {
+ private String name;
+ private int instanceCount;
+ private static int INSTANCE_COUNT = 1;
+ public Task(String name) {
+ this.name = name;
+ this.instanceCount = INSTANCE_COUNT++;
+ }
+ public String displayString() {
+ return this.name + ": " + this.instanceCount;
+ }
+ public int compareTo(Displayable o) {
+ return DEFAULT_COMPARATOR.compare(this, o);
+ }
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ Object old = this.name;
+ this.name = name;
+ this.firePropertyChanged(DISPLAY_STRING_PROPERTY, old, name);
+ }
+ @Override
+ public String toString() {
+ return this.displayString();
+ }
+ }
+
+ public interface Displayable extends Model, Comparable<Displayable> {
+
+ String displayString();
+ String DISPLAY_STRING_PROPERTY = "displayString";
+
+
+ // ********** helper implementations **********
+
+ Collator DEFAULT_COLLATOR = Collator.getInstance();
+
+ Comparator<Displayable> DEFAULT_COMPARATOR =
+ new Comparator<Displayable>() {
+ public int compare(Displayable d1, Displayable d2) {
+ // disallow duplicates based on object identity
+ if (d1 == d2) {
+ return 0;
+ }
+
+ // first compare display strings using the default collator
+ int result = DEFAULT_COLLATOR.compare(d1.displayString(), d2.displayString());
+ if (result != 0) {
+ return result;
+ }
+
+ // then compare using object-id
+ result = System.identityHashCode(d1) - System.identityHashCode(d2);
+ if (result != 0) {
+ return result;
+ }
+
+ // It's unlikely that we get to this point; but, just in case, we will return -1.
+ // Unfortunately, this introduces some mild unpredictability to the sort order
+ // (unless the objects are always passed into this method in the same order).
+ return -1; // if all else fails, indicate that o1 < o2
+ }
+ @Override
+ public String toString() {
+ return "Displayable.DEFAULT_COMPARATOR";
+ }
+ };
+
+ }
+}
diff --git a/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/TextFieldModelBindingUITest.java b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/TextFieldModelBindingUITest.java
new file mode 100644
index 0000000000..5f96336409
--- /dev/null
+++ b/common/tests/org.eclipse.jpt.common.ui.tests/src/org/eclipse/jpt/common/ui/tests/internal/utility/swt/TextFieldModelBindingUITest.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.tests.internal.utility.swt;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jpt.common.ui.internal.utility.swt.SWTTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.value.PropertyAspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
+import org.eclipse.jpt.utility.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Play around with a set of entry fields.
+ */
+@SuppressWarnings("nls")
+public class TextFieldModelBindingUITest
+ extends ApplicationWindow
+{
+ private final TestModel testModel;
+ private static final String DEFAULT_NAME = "Scooby Doo";
+ private final WritablePropertyValueModel<TestModel> testModelHolder;
+ private final WritablePropertyValueModel<String> nameHolder;
+ private final WritablePropertyValueModel<String> allCapsNameHolder;
+
+
+ public static void main(String[] args) throws Exception {
+ Window window = new TextFieldModelBindingUITest();
+ window.setBlockOnOpen(true);
+ window.open();
+ Display.getCurrent().dispose();
+ System.exit(0);
+ }
+
+ private TextFieldModelBindingUITest() {
+ super(null);
+ this.testModel = new TestModel(DEFAULT_NAME);
+ this.testModelHolder = new SimplePropertyValueModel<TestModel>(this.testModel);
+ this.nameHolder = this.buildNameHolder(this.testModelHolder);
+ this.allCapsNameHolder = this.buildAllCapsNameHolder(this.testModelHolder);
+ }
+
+ private WritablePropertyValueModel<String> buildNameHolder(PropertyValueModel<TestModel> vm) {
+ return new PropertyAspectAdapter<TestModel, String>(vm, TestModel.NAME_PROPERTY) {
+ @Override
+ protected String buildValue_() {
+ return this.subject.name();
+ }
+ @Override
+ protected void setValue_(String value) {
+ this.subject.setName(value);
+ }
+ };
+ }
+
+ private WritablePropertyValueModel<String> buildAllCapsNameHolder(PropertyValueModel<TestModel> vm) {
+ return new PropertyAspectAdapter<TestModel, String>(vm, TestModel.NAME_PROPERTY) {
+ @Override
+ protected String buildValue_() {
+ return this.subject.name().toUpperCase();
+ }
+ @Override
+ protected void setValue_(String value) {
+ // do nothing
+ }
+ };
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ ((Shell) parent).setText(this.getClass().getSimpleName());
+ parent.setSize(400, 100);
+ Composite mainPanel = new Composite(parent, SWT.NONE);
+ mainPanel.setLayout(new FormLayout());
+ Control textFieldPanel = this.buildTextFieldPanel(mainPanel);
+ this.buildControlPanel(mainPanel, textFieldPanel);
+ return mainPanel;
+ }
+
+ private Control buildTextFieldPanel(Composite parent) {
+ Composite panel = new Composite(parent, SWT.NONE);
+
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(0);
+ fd.bottom = new FormAttachment(100, -35);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildNameTextField(panel);
+ this.buildReadOnlyNameTextField(panel);
+ this.buildAllCapsNameTextField(panel);
+
+ return panel;
+ }
+
+ private void buildNameTextField(Composite parent) {
+ Text textField = new Text(parent, SWT.SINGLE);
+ SWTTools.bind(this.nameHolder, textField);
+ }
+
+ private void buildReadOnlyNameTextField(Composite parent) {
+ Text textField = new Text(parent, SWT.SINGLE);
+ textField.setEnabled(false);
+ SWTTools.bind(this.nameHolder, textField);
+ }
+
+ private void buildAllCapsNameTextField(Composite parent) {
+ Text textField = new Text(parent, SWT.SINGLE);
+ textField.setEnabled(false);
+ SWTTools.bind(this.allCapsNameHolder, textField);
+ }
+
+ private void buildControlPanel(Composite parent, Control checkBoxPanel) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ FormData fd = new FormData();
+ fd.top = new FormAttachment(checkBoxPanel);
+ fd.bottom = new FormAttachment(100);
+ fd.left = new FormAttachment(0);
+ fd.right = new FormAttachment(100);
+ panel.setLayoutData(fd);
+
+ panel.setLayout(new FillLayout());
+ this.buildResetNameButton(panel);
+ this.buildClearModelButton(panel);
+ this.buildRestoreModelButton(panel);
+ this.buildPrintModelButton(panel);
+ }
+
+ private void buildResetNameButton(Composite parent) {
+ this.buildResetNameACI().fill(parent);
+ }
+
+ private ActionContributionItem buildResetNameACI() {
+ Action action = new Action("reset name", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TextFieldModelBindingUITest.this.resetName();
+ }
+ };
+ action.setToolTipText("reset name");
+ return new ActionContributionItem(action);
+ }
+
+ void resetName() {
+ this.testModel.setName(DEFAULT_NAME);
+ }
+
+ private void buildClearModelButton(Composite parent) {
+ this.buildClearModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildClearModelACI() {
+ Action action = new Action("clear model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TextFieldModelBindingUITest.this.clearModel();
+ }
+ };
+ action.setToolTipText("clear model");
+ return new ActionContributionItem(action);
+ }
+
+ void clearModel() {
+ this.testModelHolder.setValue(null);
+ }
+
+ private void buildRestoreModelButton(Composite parent) {
+ this.buildRestoreModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildRestoreModelACI() {
+ Action action = new Action("restore model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TextFieldModelBindingUITest.this.restoreModel();
+ }
+ };
+ action.setToolTipText("restore model");
+ return new ActionContributionItem(action);
+ }
+
+ void restoreModel() {
+ this.testModelHolder.setValue(this.testModel);
+ }
+
+ private void buildPrintModelButton(Composite parent) {
+ this.buildPrintModelACI().fill(parent);
+ }
+
+ private ActionContributionItem buildPrintModelACI() {
+ Action action = new Action("print model", IAction.AS_PUSH_BUTTON) {
+ @Override
+ public void run() {
+ TextFieldModelBindingUITest.this.printModel();
+ }
+ };
+ action.setToolTipText("print model");
+ return new ActionContributionItem(action);
+ }
+
+ void printModel() {
+ System.out.println("name: " + this.testModel.name());
+ }
+
+
+ // ********** model class **********
+
+ class TestModel extends AbstractModel {
+ private String name;
+ public static final String NAME_PROPERTY = "name";
+
+ public TestModel(String name) {
+ this.name = name;
+ }
+ public String name() {
+ return this.name;
+ }
+ public void setName(String name) {
+ Object old = this.name;
+ this.name = name;
+ this.firePropertyChanged(NAME_PROPERTY, old, name);
+ }
+ @Override
+ public String toString() {
+ return "TestModel(" + this.name + ")";
+ }
+ }
+
+}

Back to the top