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 }