SHOW:
|
|
- or go back to the newest paste.
1 | package es.inaer.taller.client; | |
2 | ||
3 | import java.util.ArrayList; | |
4 | import java.util.Arrays; | |
5 | import java.util.Date; | |
6 | import java.util.List; | |
7 | ||
8 | import com.google.gwt.cell.client.DateCell; | |
9 | import com.google.gwt.core.client.EntryPoint; | |
10 | import com.google.gwt.core.client.GWT; | |
11 | import com.google.gwt.editor.client.Editor; | |
12 | import com.google.gwt.editor.client.Editor.Path; | |
13 | import com.google.gwt.editor.client.EditorError; | |
14 | import com.google.gwt.editor.client.SimpleBeanEditorDriver; | |
15 | import com.google.gwt.i18n.client.DateTimeFormat; | |
16 | import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; | |
17 | import com.google.gwt.safehtml.shared.SafeHtml; | |
18 | import com.google.gwt.user.client.Window; | |
19 | import com.google.gwt.user.client.Window.ClosingEvent; | |
20 | import com.google.gwt.user.client.Window.ClosingHandler; | |
21 | import com.google.gwt.user.client.ui.IsWidget; | |
22 | import com.google.gwt.user.client.ui.RootPanel; | |
23 | import com.google.gwt.user.client.ui.Widget; | |
24 | import com.google.web.bindery.autobean.shared.AutoBean; | |
25 | import com.google.web.bindery.autobean.shared.AutoBeanFactory; | |
26 | import com.sencha.gxt.core.client.ValueProvider; | |
27 | import com.sencha.gxt.core.client.XTemplates; | |
28 | import com.sencha.gxt.core.client.util.Margins; | |
29 | import com.sencha.gxt.data.client.editor.ListStoreEditor; | |
30 | import com.sencha.gxt.data.shared.LabelProvider; | |
31 | import com.sencha.gxt.data.shared.ListStore; | |
32 | import com.sencha.gxt.data.shared.ModelKeyProvider; | |
33 | import com.sencha.gxt.data.shared.PropertyAccess; | |
34 | import com.sencha.gxt.widget.core.client.ContentPanel; | |
35 | import com.sencha.gxt.widget.core.client.FramedPanel; | |
36 | import com.sencha.gxt.widget.core.client.box.MessageBox; | |
37 | import com.sencha.gxt.widget.core.client.button.TextButton; | |
38 | import com.sencha.gxt.widget.core.client.container.FlowLayoutContainer; | |
39 | import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer; | |
40 | import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData; | |
41 | import com.sencha.gxt.widget.core.client.event.SelectEvent; | |
42 | import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler; | |
43 | import com.sencha.gxt.widget.core.client.form.ComboBox; | |
44 | import com.sencha.gxt.widget.core.client.form.DateField; | |
45 | import com.sencha.gxt.widget.core.client.form.DateTimePropertyEditor; | |
46 | import com.sencha.gxt.widget.core.client.form.FieldLabel; | |
47 | import com.sencha.gxt.widget.core.client.form.TextField; | |
48 | import com.sencha.gxt.widget.core.client.form.validator.AbstractValidator; | |
49 | import com.sencha.gxt.widget.core.client.grid.ColumnConfig; | |
50 | import com.sencha.gxt.widget.core.client.grid.ColumnModel; | |
51 | import com.sencha.gxt.widget.core.client.grid.Grid; | |
52 | import com.sencha.gxt.widget.core.client.grid.editing.ClicksToEdit; | |
53 | import com.sencha.gxt.widget.core.client.grid.editing.GridInlineEditing; | |
54 | import com.sencha.gxt.widget.core.client.toolbar.ToolBar; | |
55 | ||
56 | // Proof of concept using some new feature of GWT2.4 + GXT3.0RC | |
57 | public class Taller implements EntryPoint { | |
58 | ||
59 | public interface Person { | |
60 | int getId(); | |
61 | void setId(int value); | |
62 | ||
63 | String getName(); | |
64 | void setName(String value); | |
65 | ||
66 | Date getBirthDate(); | |
67 | void setBirthDate(Date value); | |
68 | ||
69 | Person getBoss(); | |
70 | void setBoss(Person value); | |
71 | ||
72 | List<Person> getCollegues(); | |
73 | void setCollegues(List<Person> value); | |
74 | } | |
75 | ||
76 | interface BeanFactory extends AutoBeanFactory { | |
77 | BeanFactory INSTANCE = GWT.create(BeanFactory.class); | |
78 | AutoBean<Person> person(); | |
79 | } | |
80 | ||
81 | public interface PersonPropertyAccess extends PropertyAccess<Person> { | |
82 | PersonPropertyAccess INSTANCE = GWT.create(PersonPropertyAccess.class); | |
83 | ||
84 | @Path("name") | |
85 | LabelProvider<Person> label(); | |
86 | ||
87 | @Path("id") | |
88 | ModelKeyProvider<Person> key(); | |
89 | ||
90 | ValueProvider<Person, String> name(); | |
91 | ||
92 | ValueProvider<Person, Date> birthDate(); | |
93 | ||
94 | // exception throw if boss is null :-/ | |
95 | //@Path("boss.name") | |
96 | //ValueProvider<Person, String> bossName(); | |
97 | } | |
98 | ||
99 | /*** | |
100 | * Field that shows a grid with all person instances in the Store | |
101 | * and allows to add, remove or edit some person properties. | |
102 | */ | |
103 | public class PersonListField extends ContentPanel { | |
104 | ||
105 | // new Person objects added on editing time will have negative id numbers | |
106 | int fakePersonId = -1; | |
107 | ||
108 | public PersonListField(final ListStore<Person> personStore) { | |
109 | VerticalLayoutContainer vlc = new VerticalLayoutContainer(); | |
110 | ToolBar toolbar = new ToolBar(); | |
111 | ||
112 | TextButton addButton = new TextButton("Add"); | |
113 | toolbar.add(addButton); | |
114 | ||
115 | TextButton deleteButton = new TextButton("Delete"); | |
116 | toolbar.add(deleteButton); | |
117 | ||
118 | vlc.add(toolbar, new VerticalLayoutData(1, -1)); | |
119 | ||
120 | ArrayList<ColumnConfig<Person, ?>> colConfigs = new ArrayList<ColumnConfig<Person, ?>>(); | |
121 | ||
122 | ColumnConfig<Person, String> nameCol = new ColumnConfig<Person, String>(PersonPropertyAccess.INSTANCE.name(), 100, "Name"); | |
123 | ColumnConfig<Person, Date> birthDateCol = new ColumnConfig<Person, Date>(PersonPropertyAccess.INSTANCE.birthDate(), 100, "Birthdate"); | |
124 | birthDateCol.setCell(new DateCell(DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT))); | |
125 | ||
126 | ||
127 | colConfigs.add(nameCol); | |
128 | colConfigs.add(birthDateCol); | |
129 | ||
130 | ColumnModel<Person> columModel = new ColumnModel<Person>(colConfigs); | |
131 | ||
132 | final Grid<Person> grid = new Grid<Person>(personStore, columModel); | |
133 | grid.getView().setForceFit(true); | |
134 | ||
135 | GridInlineEditing<Person> inlineEditor = new GridInlineEditing<Person>(grid); | |
136 | inlineEditor.setClicksToEdit(ClicksToEdit.TWO); | |
137 | TextField nameTextField = new TextField(); | |
138 | inlineEditor.addEditor(nameCol, nameTextField); | |
139 | inlineEditor.addEditor(birthDateCol, new DateField(new DateTimePropertyEditor( | |
140 | DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT)))); | |
141 | ||
142 | vlc.add(grid, new VerticalLayoutData(1, 1)); | |
143 | add(vlc); | |
144 | ||
145 | addButton.addSelectHandler(new SelectHandler() { | |
146 | @Override | |
147 | public void onSelect(SelectEvent event) { | |
148 | Person p = createPerson(fakePersonId--, "New Name", null , null); | |
149 | personStore.add(p); | |
150 | } | |
151 | }); | |
152 | ||
153 | deleteButton.addSelectHandler(new SelectHandler() { | |
154 | @Override | |
155 | public void onSelect(SelectEvent event) { | |
156 | List<Person> selectedItems = grid.getSelectionModel().getSelectedItems(); | |
157 | for (Person person: selectedItems) { | |
158 | personStore.remove(person); | |
159 | } | |
160 | } | |
161 | }); | |
162 | } | |
163 | } | |
164 | ||
165 | public class PersonEditor implements IsWidget, Editor<Person> { | |
166 | ||
167 | FramedPanel fp; | |
168 | FlowLayoutContainer panel; | |
169 | ||
170 | TextField name = new TextField(); | |
171 | DateField birthDate = new DateField(); | |
172 | ||
173 | ListStore<Person> bossStore = new ListStore<Person>(PersonPropertyAccess.INSTANCE.key()); | |
174 | ComboBox<Person> boss = new ComboBox<Person>(bossStore, PersonPropertyAccess.INSTANCE.label()); | |
175 | ||
176 | ListStore<Person> collegueStore = new ListStore<Person>(PersonPropertyAccess.INSTANCE.key()); | |
177 | ListStoreEditor<Person> collegues = new ListStoreEditor<Person>(collegueStore); | |
178 | ||
179 | public PersonEditor(List<Person> bossList) { | |
180 | fp = new FramedPanel(); | |
181 | fp.setHeadingText("Person"); | |
182 | ||
183 | panel = new FlowLayoutContainer(); | |
184 | ||
185 | name.setAllowBlank(false); | |
186 | name.addValidator(new StartWithEValidator()); | |
187 | panel.add(new FieldLabel(name, "Name")); | |
188 | ||
189 | panel.add(new FieldLabel(birthDate, "Birth date")); | |
190 | ||
191 | panel.add(new FieldLabel(boss, "Boss")); | |
192 | boss.setForceSelection(true); | |
193 | bossStore.addAll(bossList); | |
194 | ||
195 | PersonListField colleguesField = new PersonListField(collegueStore); | |
196 | colleguesField.setHeadingText("Collegues"); | |
197 | colleguesField.setHeight(300); | |
198 | ||
199 | panel.add(colleguesField); | |
200 | fp.add(panel); | |
201 | } | |
202 | ||
203 | @Override | |
204 | public Widget asWidget() { | |
205 | return fp; | |
206 | } | |
207 | } | |
208 | ||
209 | public interface PersonDriver extends SimpleBeanEditorDriver<Person, PersonEditor> {} | |
210 | ||
211 | public interface PersonTemplate extends XTemplates { | |
212 | PersonTemplate INSTANCE = GWT.create(PersonTemplate.class); | |
213 | ||
214 | - | @XTemplate(source = "template.html") |
214 | + | @XTemplate("<p>Name: <b>{name}</b></p><tpl if=\"birthDate != null\"><p>Date of birth: <b>{birthDate:date(\"d/M/yy\")}</b></p></tpl><tpl if=\"boss != null\"><p>Boss's name: <b>{boss.name}</b></p></tpl><p>Collegues:</p><tpl for=\"collegues\">{#}. {name}<br></tpl>") |
215 | public SafeHtml render(Person person); | |
216 | } | |
217 | ||
218 | class StartWithEValidator extends | |
219 | AbstractValidator<String> { | |
220 | @Override | |
221 | public List<EditorError> validate(Editor<String> editor, | |
222 | String value) { | |
223 | if (value.charAt(0) != 'E') { | |
224 | return createError(editor, "Must start with letter E", value); | |
225 | } | |
226 | ||
227 | return null; | |
228 | } | |
229 | } | |
230 | ||
231 | Person createPerson(int id, String name, Date birthDate, Person boss) { | |
232 | Person p = BeanFactory.INSTANCE.person().as(); | |
233 | p.setId(id); | |
234 | p.setName(name); | |
235 | p.setBirthDate(birthDate); | |
236 | p.setBoss(boss); | |
237 | return p; | |
238 | } | |
239 | ||
240 | public void onModuleLoad() { | |
241 | // setup data model | |
242 | Person romain = createPerson(3, "Romain", null, null); | |
243 | Person andres = createPerson(2, "Andres", null, romain); | |
244 | final Person edu = createPerson(1, "Edu", null, andres); | |
245 | Person juan = createPerson(4, "Juan", null, andres); | |
246 | Person paco = createPerson(5, "Paco", null, andres); | |
247 | edu.setCollegues(new ArrayList<Person>(Arrays.asList(andres, paco, juan))); | |
248 | ||
249 | ArrayList<Person> bossList = new ArrayList<Person>(); | |
250 | bossList.add(andres); | |
251 | bossList.add(romain); | |
252 | ||
253 | VerticalLayoutContainer panel = new VerticalLayoutContainer(); | |
254 | PersonEditor personEditor = new PersonEditor(bossList); | |
255 | panel.add(personEditor, new VerticalLayoutData(1, 0.9f, new Margins(2))); | |
256 | ||
257 | TextButton saveButton = new TextButton("Save"); | |
258 | panel.add(saveButton, new VerticalLayoutData(-1, 0.05f, new Margins(2))); | |
259 | ||
260 | TextButton isDirtyButton = new TextButton("is dirty?"); | |
261 | panel.add(isDirtyButton, new VerticalLayoutData(-1, 0.05f, new Margins(2))); | |
262 | ||
263 | panel.setHeight(500); | |
264 | panel.setWidth(300); | |
265 | ||
266 | RootPanel.get().add(panel); | |
267 | ||
268 | final PersonDriver personDriver = GWT.create(PersonDriver.class); | |
269 | ||
270 | personDriver.initialize(personEditor); | |
271 | ||
272 | personDriver.edit(edu); | |
273 | ||
274 | saveButton.addSelectHandler(new SelectHandler() { | |
275 | ||
276 | @Override | |
277 | public void onSelect(SelectEvent event) { | |
278 | // in this point we should evaluate if the list editor needs | |
279 | // to check if all columns has data by example because this is not | |
280 | // check by the Editor framework workflow. | |
281 | personDriver.flush(); | |
282 | if (!personDriver.hasErrors()){ | |
283 | MessageBox mb = new MessageBox("View of edited Person", PersonTemplate.INSTANCE.render(edu).asString()); | |
284 | mb.show(); | |
285 | } else { | |
286 | ||
287 | } | |
288 | } | |
289 | }); | |
290 | ||
291 | isDirtyButton.addSelectHandler(new SelectHandler() { | |
292 | @Override | |
293 | public void onSelect(SelectEvent event) { | |
294 | Window.alert("isDirty = " + personDriver.isDirty()); | |
295 | } | |
296 | }); | |
297 | ||
298 | Window.addWindowClosingHandler(new ClosingHandler() { | |
299 | public void onWindowClosing(ClosingEvent event) { | |
300 | if (personDriver.isDirty()) { | |
301 | event.setMessage("There are unsaved editor changes."); | |
302 | } | |
303 | } | |
304 | }); | |
305 | } | |
306 | } |