001 package org.springframework.richclient.samples.showcase.binding;
002
003 import org.springframework.binding.value.support.RefreshableValueHolder;
004 import org.springframework.binding.value.support.ValueHolder;
005 import org.springframework.richclient.dialog.TitledApplicationDialog;
006 import org.springframework.richclient.form.AbstractForm;
007 import org.springframework.richclient.form.Form;
008 import org.springframework.richclient.form.FormModelHelper;
009 import org.springframework.richclient.form.binding.swing.SwingBindingFactory;
010 import org.springframework.richclient.form.builder.TableFormBuilder;
011 import org.springframework.richclient.selection.binding.ListSelectionDialogBinder;
012 import org.springframework.richclient.selection.binding.support.LabelProvider;
013 import org.springframework.rules.closure.Closure;
014
015 import javax.swing.*;
016 import java.beans.PropertyChangeEvent;
017 import java.beans.PropertyChangeListener;
018 import java.util.*;
019
020 public class ListSelectionBindingDialog extends TitledApplicationDialog {
021
022 private RefreshableValueHolder refreshableTownValueHolder;
023
024 private List<Country> countries;
025
026 private Map<Country, List<Town>> towns;
027
028 private class Country {
029 private String name;
030
031 public Country(String name) {
032 this.name = name;
033 }
034
035 public String getName() {
036 return name;
037 }
038 }
039
040 private class Town {
041 private String name;
042
043 public Town(String name) {
044 this.name = name;
045 }
046
047 public String getName() {
048 return name;
049 }
050 }
051
052 protected void init() {
053 Country belgium = new Country("Belgium");
054 Country netherlands = new Country("Netherlands");
055 Country germany = new Country("Germany");
056 countries = new ArrayList<Country>();
057 countries.add(belgium);
058 countries.add(netherlands);
059 countries.add(germany);
060 towns = new HashMap<Country, List<Town>>();
061 List<Town> belgiumTowns = new ArrayList<Town>();
062 belgiumTowns.add(new Town("Ghent"));
063 belgiumTowns.add(new Town("Antwerp"));
064 towns.put(belgium, belgiumTowns);
065 List<Town> netherlandsTowns = new ArrayList<Town>();
066 netherlandsTowns.add(new Town("Eindhoven"));
067 netherlandsTowns.add(new Town("Amsterdam"));
068 towns.put(netherlands, netherlandsTowns);
069 List<Town> germanyTowns = new ArrayList<Town>();
070 germanyTowns.add(new Town("Dortmund"));
071 germanyTowns.add(new Town("Keulen"));
072 towns.put(germany, germanyTowns);
073 }
074
075 public List<Country> getCountries() {
076 return countries;
077 }
078
079 public List<Town> getTowns(Country country) {
080 return towns.get(country);
081 }
082
083 private class Selection {
084 private Country country;
085 private Town town;
086 private List<Town> towns = new ArrayList<Town>();
087
088 public void setCountry(Country country) {
089 this.country = country;
090 }
091
092 public Country getCountry() {
093 return country;
094 }
095
096 public void setTown(Town town) {
097 this.town = town;
098 }
099
100 public Town getTown() {
101 return town;
102 }
103
104 public List<Town> getTowns() {
105 return towns;
106 }
107
108 public void setTowns(List<Town> towns) {
109 this.towns = towns;
110 }
111 }
112
113 private class ListSelectionBindingForm extends AbstractForm {
114
115 public ListSelectionBindingForm() {
116 super(FormModelHelper.createFormModel(new Selection()));
117 }
118
119 protected JComponent createFormControl() {
120 SwingBindingFactory bf = new SwingBindingFactory(getFormModel());
121 TableFormBuilder formBuilder = new TableFormBuilder(bf);
122 formBuilder.row();
123
124 Map<String, Object> countryContext = new HashMap<String, Object>();
125 countryContext.put(ListSelectionDialogBinder.SELECTABLE_ITEMS_HOLDER_KEY, new ValueHolder(countries));
126 countryContext.put(ListSelectionDialogBinder.LABEL_PROVIDER_KEY, new LabelProvider() {
127 public String getLabel(Object item) {
128 Country country = (Country) item;
129 return country == null ? "" : country.getName();
130 }
131 });
132 countryContext.put(ListSelectionDialogBinder.FILTERED_KEY, Boolean.TRUE);
133 countryContext.put(ListSelectionDialogBinder.FILTER_PROPERTIES_KEY, new String[] { "name" });
134
135 // this works ... but unfortunately ListSelectionDialogBinder has no public constructor
136 // ListSelectionDialogBinder binder = new ListSelectionDialogBinder();
137 // Binding binding = binder.bind(getFormModel(), "country", countryContext);
138 // formBuilder.add(binding, "colSpan=2");
139
140 // this works if the binderSelectionStrategy is configured in richclient-application-context.xml
141 formBuilder.add(bf.createBinding("country", countryContext), "colSpan=2");
142
143 formBuilder.row();
144
145 this.addFormValueChangeListener("country", new ChangeCountryListener());
146
147 refreshableTownValueHolder = new RefreshableValueHolder(new Closure() {
148 public Object call(Object object) {
149 Country country = (Country) getValue("country");
150 List<Town> towns = getTowns(country);
151 if (towns == null) {
152 towns = Collections.EMPTY_LIST;
153 }
154 return towns;
155 }
156 }, true, false);
157 refreshableTownValueHolder.setValue(Collections.EMPTY_LIST);
158 formBuilder
159 .add(bf.createBoundComboBox("town", refreshableTownValueHolder, "name"), "colSpan=2 align=left");
160 formBuilder.row();
161
162 return formBuilder.getForm();
163 }
164 }
165
166 private class ChangeCountryListener implements PropertyChangeListener {
167 public ChangeCountryListener() {
168 }
169
170 public void propertyChange(final PropertyChangeEvent evt) {
171 refreshableTownValueHolder.refresh();
172 }
173 }
174
175 protected JComponent createTitledDialogContentPane() {
176 Form form = new ListSelectionBindingForm();
177 return form.getControl();
178 }
179
180 protected boolean onFinish() {
181 return true;
182 }
183
184 }