View difference between Paste ID: smkRkpAt and t8FN8DYs
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
}