1 /******************************************************************************* 2 * Copyright (c) 2009, 2018 Matthew Hall and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Matthew Hall - initial API and implementation (bug 175735) 13 * Matthew Hall - bugs 262407, 260337 14 ******************************************************************************/ 15 16 package org.eclipse.jface.examples.databinding.snippets; 17 18 import java.beans.PropertyChangeListener; 19 import java.beans.PropertyChangeSupport; 20 import java.util.ArrayList; 21 import java.util.List; 22 23 import org.eclipse.core.databinding.beans.typed.BeanProperties; 24 import org.eclipse.core.databinding.observable.Realm; 25 import org.eclipse.core.databinding.property.list.IListProperty; 26 import org.eclipse.core.databinding.property.list.MultiListProperty; 27 import org.eclipse.jface.databinding.swt.DisplayRealm; 28 import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider; 29 import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; 30 import org.eclipse.jface.viewers.TreeViewer; 31 import org.eclipse.swt.SWT; 32 import org.eclipse.swt.graphics.GC; 33 import org.eclipse.swt.graphics.Image; 34 import org.eclipse.swt.layout.FillLayout; 35 import org.eclipse.swt.layout.GridLayout; 36 import org.eclipse.swt.widgets.Display; 37 import org.eclipse.swt.widgets.Shell; 38 39 public class Snippet029TreeViewerMultiListProperty { 40 private TreeViewer viewer; 41 main(String[] args)42 public static void main(String[] args) { 43 final Display display = Display.getDefault(); 44 45 Realm.runWithDefault(DisplayRealm.getRealm(display), () -> { 46 Shell shell = new Snippet029TreeViewerMultiListProperty().createShell(); 47 48 while (!shell.isDisposed()) { 49 if (!display.readAndDispatch()) { 50 display.sleep(); 51 } 52 } 53 }); 54 55 display.dispose(); 56 } 57 createShell()58 protected Shell createShell() { 59 Shell shell = new Shell(); 60 shell.setSize(509, 375); 61 shell.setText("Snippet029TreeViewerMultiListProperty.java"); 62 final GridLayout gridLayout = new GridLayout(); 63 gridLayout.makeColumnsEqualWidth = true; 64 gridLayout.numColumns = 4; 65 shell.setLayout(new FillLayout()); 66 67 viewer = new TreeViewer(shell, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER); 68 69 bindUI(); 70 71 shell.open(); 72 return shell; 73 } 74 75 /** Helper class for implementing JavaBeans support. */ 76 public static abstract class AbstractModelObject { 77 private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); 78 addPropertyChangeListener(PropertyChangeListener listener)79 public void addPropertyChangeListener(PropertyChangeListener listener) { 80 propertyChangeSupport.addPropertyChangeListener(listener); 81 } 82 addPropertyChangeListener(String propertyName, PropertyChangeListener listener)83 public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { 84 propertyChangeSupport.addPropertyChangeListener(propertyName, listener); 85 } 86 removePropertyChangeListener(PropertyChangeListener listener)87 public void removePropertyChangeListener(PropertyChangeListener listener) { 88 propertyChangeSupport.removePropertyChangeListener(listener); 89 } 90 removePropertyChangeListener(String propertyName, PropertyChangeListener listener)91 public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { 92 propertyChangeSupport.removePropertyChangeListener(propertyName, listener); 93 } 94 firePropertyChange(String propertyName, Object oldValue, Object newValue)95 protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { 96 propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); 97 } 98 } 99 100 public static class Catalog extends AbstractModelObject { 101 private String name; 102 private List<Catalog> catalogs = new ArrayList<>(); 103 private List<CatalogItem> items = new ArrayList<>(); 104 Catalog(String name)105 public Catalog(String name) { 106 this.name = name; 107 } 108 getName()109 public String getName() { 110 return name; 111 } 112 setName(String name)113 public void setName(String name) { 114 firePropertyChange("name", this.name, this.name = name); 115 } 116 getCatalogs()117 public List<Catalog> getCatalogs() { 118 return catalogs; 119 } 120 setCatalogs(List<Catalog> catalogs)121 public void setCatalogs(List<Catalog> catalogs) { 122 firePropertyChange("catalogs", this.catalogs, this.catalogs = catalogs); 123 } 124 getItems()125 public List<CatalogItem> getItems() { 126 return items; 127 } 128 setItems(List<CatalogItem> items)129 public void setItems(List<CatalogItem> items) { 130 firePropertyChange("items", this.items, this.items = items); 131 } 132 } 133 134 public static class CatalogItem extends AbstractModelObject { 135 private String name; 136 CatalogItem(String name)137 public CatalogItem(String name) { 138 this.name = name; 139 } 140 getName()141 public String getName() { 142 return name; 143 } 144 setName(String name)145 public void setName(String name) { 146 firePropertyChange("name", this.name, this.name = name); 147 } 148 } 149 bindUI()150 private void bindUI() { 151 List<CatalogItem> items; 152 153 Catalog fruits = new Catalog("Fruits"); 154 items = new ArrayList<>(); 155 items.add(new CatalogItem("Apple")); 156 items.add(new CatalogItem("Orange")); 157 fruits.setItems(items); 158 159 Catalog vegetables = new Catalog("Vegetables"); 160 items = new ArrayList<>(); 161 items.add(new CatalogItem("Peas")); 162 items.add(new CatalogItem("Carrots")); 163 items.add(new CatalogItem("Potatoes")); 164 vegetables.setItems(items); 165 166 Catalog foods = new Catalog("Foods"); 167 List<Catalog> catalogs = new ArrayList<>(); 168 catalogs.add(fruits); 169 catalogs.add(vegetables); 170 foods.setCatalogs(catalogs); 171 172 items = new ArrayList<>(); 173 items.add(new CatalogItem("Own Hand")); 174 foods.setItems(items); 175 176 Catalog catalog = new Catalog("Main Catalog"); 177 catalogs = new ArrayList<>(); 178 catalogs.add(foods); 179 catalog.setCatalogs(catalogs); 180 181 IListProperty<AbstractModelObject, AbstractModelObject> childrenProperty = new MultiListProperty<>( 182 BeanProperties.list("catalogs"), BeanProperties.list("items")); 183 184 ObservableListTreeContentProvider<AbstractModelObject> contentProvider = new ObservableListTreeContentProvider<>( 185 childrenProperty.listFactory(), null); 186 viewer.setContentProvider(contentProvider); 187 188 ObservableMapLabelProvider labelProvider = new ObservableMapLabelProvider( 189 BeanProperties.value("name").observeDetail(contentProvider.getKnownElements())) { 190 Image catalogImage = createCatalogImage(); 191 Image catalogItemImage = createCatalogItemImage(); 192 193 @Override 194 public Image getImage(Object element) { 195 if (element instanceof Catalog) { 196 return catalogImage; 197 } 198 if (element instanceof CatalogItem) { 199 return catalogItemImage; 200 } 201 return super.getImage(element); 202 } 203 204 @Override 205 public void dispose() { 206 catalogImage.dispose(); 207 catalogItemImage.dispose(); 208 super.dispose(); 209 } 210 211 private Image createCatalogImage() { 212 Display display = Display.getCurrent(); 213 Image catalogImage = new Image(display, 12, 12); 214 GC gc = new GC(catalogImage); 215 gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN)); 216 gc.fillArc(1, 1, 10, 10, 0, 360); 217 gc.dispose(); 218 return catalogImage; 219 } 220 221 private Image createCatalogItemImage() { 222 Display display = Display.getCurrent(); 223 Image catalogImage = new Image(display, 12, 12); 224 GC gc = new GC(catalogImage); 225 gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN)); 226 gc.fillPolygon(new int[] { 1, 10, 5, 1, 6, 1, 10, 10, 1, 10 }); 227 gc.dispose(); 228 return catalogImage; 229 } 230 }; 231 viewer.setLabelProvider(labelProvider); 232 233 viewer.setInput(catalog); 234 } 235 } 236