Subversion Repositories eFlore/Applications.cel

Rev

Rev 5 | Rev 59 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 aperonnet 1
package org.tela_botanica.client.vues;
2
 
56 david 3
 
4
import org.tela_botanica.client.interfaces.ListePaginable;
2 aperonnet 5
import org.tela_botanica.client.interfaces.Rafraichissable;
6
 
7
import com.gwtext.client.core.EventCallback;
8
import com.gwtext.client.core.EventObject;
9
import com.gwtext.client.core.Template;
10
import com.gwtext.client.data.Record;
11
import com.gwtext.client.data.SimpleStore;
12
import com.gwtext.client.data.Store;
13
import com.gwtext.client.widgets.Button;
14
import com.gwtext.client.widgets.Toolbar;
15
import com.gwtext.client.widgets.ToolbarButton;
16
import com.gwtext.client.widgets.ToolbarTextItem;
17
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
18
import com.gwtext.client.widgets.form.ComboBox;
19
import com.gwtext.client.widgets.form.Field;
20
import com.gwtext.client.widgets.form.TextField;
21
import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter;
22
import com.gwtext.client.widgets.form.event.TextFieldListenerAdapter;
23
 
24
/**
5 aperonnet 25
 * Barre de pagination asynchrone avec filtrage des touches et accès directs et
26
 * séquentiels à une page
27
 *
2 aperonnet 28
 * @author aurelien
5 aperonnet 29
 *
2 aperonnet 30
 */
31
public class pageToolBarVue extends Toolbar implements Rafraichissable {
5 aperonnet 32
 
2 aperonnet 33
	/**
34
	 * Instance du médiateur à qui on notifie les évnènements
35
	 */
56 david 36
	private ListePaginable listePaginable = null;
5 aperonnet 37
 
2 aperonnet 38
	/**
39
	 * Bouton précédent
40
	 */
5 aperonnet 41
	private ToolbarButton prevPage = new ToolbarButton();
2 aperonnet 42
	/**
43
	 * Bouton suivant
44
	 */
5 aperonnet 45
	private ToolbarButton suivPage = new ToolbarButton();
2 aperonnet 46
	/**
5 aperonnet 47
	 * Numéro de la page courante (attention, commence à zéro pour des raisons
48
	 * pratiques)
2 aperonnet 49
	 */
5 aperonnet 50
	private int pageCourante = 0;
2 aperonnet 51
	/**
52
	 * Nombre de page total
53
	 */
5 aperonnet 54
	private int pageTotale = 1;
2 aperonnet 55
	/**
56
	 * Nombre d'élements total
57
	 */
5 aperonnet 58
	private int nbElement = 0;
2 aperonnet 59
	/**
60
	 * Nombre d'élément par page
61
	 */
5 aperonnet 62
	private int taillePage = 0;
2 aperonnet 63
	/**
64
	 * Texte statique de la toolbar 1
65
	 */
5 aperonnet 66
	private ToolbarTextItem page = new ToolbarTextItem("Page ");
2 aperonnet 67
	/**
68
	 * Affichage de la page courante
69
	 */
5 aperonnet 70
	private TextField champPage = new TextField("" + (pageCourante + 1));
2 aperonnet 71
	/**
72
	 * Affichage de "sur pageTotale "
73
	 */
5 aperonnet 74
	private ToolbarTextItem surTotalPage = new ToolbarTextItem(" sur "
75
			+ pageTotale);
2 aperonnet 76
	/**
77
	 * Texte statique de la toolbar 2
78
	 */
5 aperonnet 79
	private ToolbarTextItem afficherNbElem = new ToolbarTextItem("Afficher ");
2 aperonnet 80
	/**
5 aperonnet 81
	 * Combobox permettant de selectionner le nombre d'élements à afficher par
82
	 * page et donc de changer la variable taillePage
2 aperonnet 83
	 */
5 aperonnet 84
	private ComboBox selecteurTaillePage = new ComboBox();
2 aperonnet 85
	/**
86
	 * Texte statique de la toolbar 3
87
	 */
5 aperonnet 88
	private ToolbarTextItem nbElemParPage = new ToolbarTextItem(
89
			" images par page ");
2 aperonnet 90
	/**
91
	 * Affiche l'intervalle des éléments contenus dans la page
92
	 */
5 aperonnet 93
	private ToolbarTextItem intervalleElements = new ToolbarTextItem("Images "
94
			+ pageCourante * taillePage + " sur " + nbElement);
2 aperonnet 95
 
96
	/**
56 david 97
	 * retourne la liste associé à la barre
2 aperonnet 98
	 */
56 david 99
 
100
	public ListePaginable getlistePaginable() {
101
		return listePaginable;
2 aperonnet 102
	}
5 aperonnet 103
 
104
	/***************************************************************************
2 aperonnet 105
	 * constructeur sans argument (privé car ne doit pas être utilisé)
106
	 */
107
	@SuppressWarnings("unused")
5 aperonnet 108
	private pageToolBarVue() {
109
		super();
2 aperonnet 110
	}
5 aperonnet 111
 
2 aperonnet 112
	/**
113
	 * constructeur avec paramètres
5 aperonnet 114
	 *
115
	 * @param im
116
	 *            le médiateur à associer à la barre
2 aperonnet 117
	 */
56 david 118
	public pageToolBarVue(ListePaginable lst) {
5 aperonnet 119
		super();
120
 
56 david 121
		listePaginable = lst;
5 aperonnet 122
 
123
		// on dispose un peu de texte et quelques espaces pour séparer les
124
		// éléments
125
		addButton(prevPage);
126
		addSpacer();
127
		addItem(page);
128
		addField(champPage);
129
		addItem(surTotalPage);
130
		addSpacer();
131
		addButton(suivPage);
132
 
133
		champPage.setWidth(30);
134
 
135
		addSpacer();
136
		addItem(afficherNbElem);
137
 
138
		prevPage.setIcon("page_prev.png");
139
		suivPage.setIcon("page_suiv.png");
140
 
2 aperonnet 141
		// le store contient les valeur possibles pour les tailles de page
5 aperonnet 142
		final Store store = new SimpleStore(new String[] { "nb_page" },
143
				getNbPages());
144
		store.load();
145
 
146
		// le template definit ce que l'on affiche pour chaque element du store
147
		// dans la combobox
148
		final Template tp = new Template("<div class=\"x-combo-list-item\">"
149
				+ "{nb_page}" + "<div class=\"x-clear\"></div></div>");
2 aperonnet 150
		tp.compile();
5 aperonnet 151
 
152
		selecteurTaillePage.setTpl(tp);
153
		selecteurTaillePage.setStore(store);
154
		selecteurTaillePage.setWidth(40);
155
		selecteurTaillePage.setEditable(false);
156
		addField(selecteurTaillePage);
157
		selecteurTaillePage.setValue("50");
158
		selecteurTaillePage.setWidth(50);
159
		addItem(nbElemParPage);
160
 
161
		// on remplit l'espace pour que l'intervalle d'élement se place à droite
162
		// de la barre
163
		addFill();
164
		addItem(intervalleElements);
165
		addSpacer();
166
 
2 aperonnet 167
		// on ajoute les différents listeners
5 aperonnet 168
		ajouterListeners();
2 aperonnet 169
	}
5 aperonnet 170
 
2 aperonnet 171
	/**
5 aperonnet 172
	 * ajoute les différents listeners nécessaires au bon fonctionnement des
173
	 * éléments de la barre de pagination
2 aperonnet 174
	 */
5 aperonnet 175
	private void ajouterListeners() {
176
		// boutons suivants et précédents
2 aperonnet 177
		prevPage.addListener(new ButtonListenerAdapter() {
178
 
179
			public void onClick(Button button, EventObject e) {
5 aperonnet 180
 
2 aperonnet 181
				// si la page courante n'est pas la première
5 aperonnet 182
				if (pageCourante > 0) {
2 aperonnet 183
					// on décrémente la page courante de 1
5 aperonnet 184
					pageCourante--;
2 aperonnet 185
					// on rafraichit l'affichage
5 aperonnet 186
					rafraichirNumeroPage();
2 aperonnet 187
					// et on notifie le médiateur de l'évenement
56 david 188
					listePaginable.changerNumeroPage(pageCourante);
5 aperonnet 189
 
2 aperonnet 190
				}
191
			}
5 aperonnet 192
		});
193
 
2 aperonnet 194
		suivPage.addListener(new ButtonListenerAdapter() {
5 aperonnet 195
 
2 aperonnet 196
			public void onClick(Button button, EventObject e) {
5 aperonnet 197
 
2 aperonnet 198
				// si la page courante n'est pas la dernière
5 aperonnet 199
				if (pageCourante < pageTotale - 1) {
2 aperonnet 200
					// on incrémente la page courante de 1
5 aperonnet 201
					pageCourante++;
2 aperonnet 202
					// on rafraichit l'affichage
5 aperonnet 203
					rafraichirNumeroPage();
2 aperonnet 204
					// et on notifie le médiateur de l'évenement
56 david 205
					listePaginable.changerNumeroPage(pageCourante);
5 aperonnet 206
 
207
				}
2 aperonnet 208
			}
5 aperonnet 209
		});
210
 
2 aperonnet 211
		champPage.addListener(new TextFieldListenerAdapter() {
212
 
213
			public void onSpecialKey(Field field, EventObject e) {
5 aperonnet 214
 
2 aperonnet 215
				// on teste si la touche entrée a été pressée
5 aperonnet 216
				if (e.getKey() == EventObject.ENTER) {
217
					int nouvellePage = pageCourante;
2 aperonnet 218
					// on teste avec parseInt si la valeur entrée est un entier
5 aperonnet 219
					try {
220
						nouvellePage = Integer
221
								.parseInt(champPage.getRawValue());
222
					}
223
					// si ce n'est pas le cas alors on remet le numéro de page
224
					// correct
225
					catch (NumberFormatException nfe) {
226
						rafraichirNumeroPage();
227
						champPage.focus(true);
228
						return;
229
					}
2 aperonnet 230
 
5 aperonnet 231
					// si la conversion reussit on verifie s'il est nécessaire
232
					// de changer de page
233
					// et si la nouvelle est comprise dans l'intervalle des
234
					// pages existantes (0..pageTotale)
235
					if (nouvellePage != pageCourante + 1 && nouvellePage > 0
236
							&& nouvellePage <= pageTotale) {
237
						// le cas échéant, on charge la nouvelle page et on
238
						// notifie le médiateur
239
						changerPageCourante(nouvellePage - 1);
56 david 240
						listePaginable.changerNumeroPage(pageCourante);
5 aperonnet 241
 
242
					} else {
243
						// sinon on reaffiche l'ancien numero de page sans rien
244
						// changer
245
						rafraichirNumeroPage();
246
						champPage.focus(true);
2 aperonnet 247
					}
248
				}
249
			}
5 aperonnet 250
 
2 aperonnet 251
			public void onFocus(Field field) {
5 aperonnet 252
 
253
				champPage.focus(true);
2 aperonnet 254
			}
5 aperonnet 255
 
2 aperonnet 256
		});
5 aperonnet 257
 
258
		// pour éviter de se compliquer la vie, on filtre tous les charactères
259
		// non numériques
2 aperonnet 260
		champPage.addKeyPressListener(new EventCallback() {
261
 
262
			public void execute(EventObject e) {
5 aperonnet 263
 
2 aperonnet 264
				// si c'est un numerique
5 aperonnet 265
				if (Character.isDigit((char) e.getCharCode())) {
2 aperonnet 266
					// on laisse passer
5 aperonnet 267
					return;
2 aperonnet 268
				}
5 aperonnet 269
 
2 aperonnet 270
				// si c'est la touche entrée ou backspace (valider ou effacer)
5 aperonnet 271
				if (e.getKey() == EventObject.ENTER
272
						|| e.getKey() == EventObject.BACKSPACE) {
2 aperonnet 273
					// on laisse passer
5 aperonnet 274
					return;
275
				} else {
276
					// sinon on remet le numero de page correct et on annule
277
					// l'évenement
278
					rafraichirNumeroPage();
279
					e.stopEvent();
2 aperonnet 280
				}
281
			}
5 aperonnet 282
 
283
		});
284
 
285
		// listener pour la selection dans la combobox
2 aperonnet 286
		selecteurTaillePage.addListener(new ComboBoxListenerAdapter() {
5 aperonnet 287
 
2 aperonnet 288
			public void onSelect(ComboBox comboBox, Record record, int index) {
5 aperonnet 289
 
290
				String nouvelleTaillePageString = comboBox.getStore()
291
						.getRecordAt(index).getAsString("nb_page");
292
				int nouvelleTaillePage = Integer
293
						.parseInt(nouvelleTaillePageString);
294
 
2 aperonnet 295
				// si la taille de page est différente de l'ancienne
5 aperonnet 296
				if (nouvelleTaillePage != taillePage) {
2 aperonnet 297
					// on la change
5 aperonnet 298
					changerTaillePage(nouvelleTaillePage);
2 aperonnet 299
				}
300
				// et on met la valeur à jour dans la combobox
5 aperonnet 301
				comboBox.setValue(nouvelleTaillePageString);
2 aperonnet 302
			}
5 aperonnet 303
 
304
		});
2 aperonnet 305
	}
5 aperonnet 306
 
2 aperonnet 307
	/**
5 aperonnet 308
	 * Met à jour les affichage sur les numéros de pages et d'intervalle
309
	 * d'éléments à partir des variables de classes
2 aperonnet 310
	 */
5 aperonnet 311
	public void rafraichirNumeroPage() {
312
		surTotalPage.setText(" sur " + pageTotale);
313
 
314
		if (nbElement == 0) {
315
			champPage.setValue("" + (0));
316
			// on met simplement à jour l'intervalle qui contient toujours le
317
			// même nombre d'éléments
318
			intervalleElements.setText("Images 0 - 0 sur 0");
319
		} else {
320
			champPage.setValue("" + (pageCourante + 1));
321
 
322
			// si la page n'est pas la dernière
323
			if (pageCourante + 1 != pageTotale) {
324
				// sauf pour la dernière page qui contient souvent moins
325
				// d'élements que le nombre d'élements par page
326
				intervalleElements.setText("Images " + pageCourante
327
						* taillePage + " - " + (pageCourante + 1) * taillePage
328
						+ " sur " + nbElement);
329
			} else {
330
				// on met simplement à jour l'intervalle qui contient toujours
331
				// le même nombre d'éléments
332
				intervalleElements.setText("Images " + pageCourante
333
						* taillePage + " - " + nbElement + " sur " + nbElement);
334
			}
2 aperonnet 335
		}
336
	}
5 aperonnet 337
 
2 aperonnet 338
	/**
5 aperonnet 339
	 * Met à jour la page en cours
340
	 *
341
	 * @param nouvellePageCourante
342
	 *            la nouvelle page en cours
2 aperonnet 343
	 */
5 aperonnet 344
	public void changerPageCourante(int nouvellePageCourante) {
345
		pageCourante = nouvellePageCourante;
2 aperonnet 346
	}
5 aperonnet 347
 
2 aperonnet 348
	/**
349
	 * Methode héritée de l'interface rafraichissable
350
	 */
351
	public void rafraichir(Object nouvelleDonnees,
352
			boolean repandreRaffraichissement) {
5 aperonnet 353
 
2 aperonnet 354
		// si on reçoit un tableau de int
5 aperonnet 355
		if (nouvelleDonnees instanceof int[]) {
356
			int[] page = (int[]) nouvelleDonnees;
357
			// le premier élement est le nombre de pages totales
358
			pageTotale = page[0];
2 aperonnet 359
			// le second la page en cours
5 aperonnet 360
			pageCourante = page[1];
2 aperonnet 361
			// le troisième la taille de la page
5 aperonnet 362
			taillePage = page[2];
2 aperonnet 363
			// et le dernier le nombre total d'éléments
5 aperonnet 364
			nbElement = page[3];
365
 
366
			// si la page courante dépasse la page totale (cas normalement
367
			// improbable car géré en amont)
368
			// on met le numéro de page à la page courante -1 (car la page
369
			// courante est comptée à partir
2 aperonnet 370
			// de zéro)
5 aperonnet 371
			if (pageCourante >= pageTotale && pageCourante != 0) {
372
				pageCourante = pageTotale - 1;
2 aperonnet 373
				// le cas échéant on en notifie le médiateur
56 david 374
				listePaginable.changerNumeroPage(pageCourante);
2 aperonnet 375
			}
376
		}
5 aperonnet 377
 
378
		// enfin on rafraichit les informations affichées à partir des nouvelles
379
		// variables de classes mises à jour
380
		rafraichirNumeroPage();
2 aperonnet 381
	}
5 aperonnet 382
 
2 aperonnet 383
	/**
384
	 * Renvoie les différents intervalles de pages possibles
5 aperonnet 385
	 *
386
	 * @return un tableau de tableau de string qui contient les différentes
387
	 *         taille de pages
2 aperonnet 388
	 */
5 aperonnet 389
	public String[][] getNbPages() {
390
		String[][] pages = { { "200" }, { "100" }, { "50" }, { "20" }, { "10" } };
391
 
392
		return pages;
2 aperonnet 393
	}
394
 
395
	/**
5 aperonnet 396
	 * Envoie au médiateur une demande pour modifier la taille de la page (qui
397
	 * va à son tour faire les modifications nécessaires)
398
	 *
399
	 * @param nouvelleTaillePage
400
	 *            la nouvelle taille de page (élement appartenant au tableau
401
	 *            renvoyé par getNbPages())
2 aperonnet 402
	 */
403
	public void changerTaillePage(int nouvelleTaillePage) {
5 aperonnet 404
 
56 david 405
		listePaginable.changerTaillePage(nouvelleTaillePage);
5 aperonnet 406
 
2 aperonnet 407
	}
5 aperonnet 408
 
2 aperonnet 409
	/**
5 aperonnet 410
	 * Selectionne la valeur correspond à celle passée en paramètre dans la
411
	 * combobox (si elle existe)
412
	 *
413
	 * @param nouvelleTaillePage
414
	 *            la nouvelle taille de page
2 aperonnet 415
	 */
416
	public void selectionnerTaillePage(int nouvelleTaillePage) {
5 aperonnet 417
 
418
		selecteurTaillePage.setValue("" + nouvelleTaillePage);
2 aperonnet 419
	}
5 aperonnet 420
 
2 aperonnet 421
}