Java tutorial
/* * Copyright 2010, 2011 Renaud Brub * * This file is part of PIGE. * * PIGE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PIGE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PIGE. If not, see <http://www.gnu.org/licenses/>. */ package ca.qc.cegepoutaouais.tge.pige.client.ui.view; import ca.qc.cegepoutaouais.tge.pige.client.LoanStatus; import ca.qc.cegepoutaouais.tge.pige.client.services.UserServiceAsync; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.FrozenAccountException; import ca.qc.cegepoutaouais.tge.pige.client.ui.AppEvents; import ca.qc.cegepoutaouais.tge.pige.client.ui.AppWidgets; import ca.qc.cegepoutaouais.tge.pige.client.PIGE; import ca.qc.cegepoutaouais.tge.pige.client.PigeUtil; import ca.qc.cegepoutaouais.tge.pige.client.resources.Resources; import ca.qc.cegepoutaouais.tge.pige.client.services.ManagementServiceAsync; import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.AbstractCEVDialog.CEV; import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.ItemCEVDialog; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.ItemSelectorField; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.StatusBar; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Item; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Loan; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Tag; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.UserDetail; import com.extjs.gxt.ui.client.Registry; import com.extjs.gxt.ui.client.Style.LayoutRegion; import com.extjs.gxt.ui.client.core.Template; import com.extjs.gxt.ui.client.data.BaseFilterPagingLoadConfig; import com.extjs.gxt.ui.client.data.BasePagingLoader; import com.extjs.gxt.ui.client.data.BaseStringFilterConfig; import com.extjs.gxt.ui.client.data.BeanModel; import com.extjs.gxt.ui.client.data.BeanModelFactory; import com.extjs.gxt.ui.client.data.BeanModelLookup; import com.extjs.gxt.ui.client.data.BeanModelReader; import com.extjs.gxt.ui.client.data.FilterConfig; import com.extjs.gxt.ui.client.data.LoadConfig; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.data.PagingLoadConfig; import com.extjs.gxt.ui.client.data.PagingLoadResult; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.EventType; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.KeyListener; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.MenuEvent; import com.extjs.gxt.ui.client.event.RowEditorEvent; import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.mvc.AppEvent; import com.extjs.gxt.ui.client.mvc.Controller; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.util.Params; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.MessageBox; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction; import com.extjs.gxt.ui.client.widget.form.DateField; import com.extjs.gxt.ui.client.widget.form.NumberField; import com.extjs.gxt.ui.client.widget.form.SimpleComboBox; import com.extjs.gxt.ui.client.widget.grid.CellEditor; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnData; import com.extjs.gxt.ui.client.widget.grid.ColumnModel; import com.extjs.gxt.ui.client.widget.grid.EditorGrid.ClicksToEdit; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; import com.extjs.gxt.ui.client.widget.grid.RowEditor; import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData; import com.extjs.gxt.ui.client.widget.menu.AdapterMenuItem; import com.extjs.gxt.ui.client.widget.menu.DateMenu; import com.extjs.gxt.ui.client.widget.menu.HeaderMenuItem; import com.extjs.gxt.ui.client.widget.menu.Menu; import com.extjs.gxt.ui.client.widget.menu.MenuItem; import com.extjs.gxt.ui.client.widget.menu.SeparatorMenuItem; import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AbstractImagePrototype; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /** * Vue permettant l'usager d'effectuer des demandes d'emprunt. * * @author Renaud Brub */ public class NewLoanView extends BaseView { protected final String NEW_TAG_FLAG = "is-new"; protected final Integer MAX_LOAN_PER_REQUEST = 20; protected final Integer PAGE_SIZE = 50; protected RpcProxy<PagingLoadResult<UserDetail>> proxy = null; protected BasePagingLoader<PagingLoadResult<ModelData>> loader = null; protected BaseFilterPagingLoadConfig loadConfig = null; protected Grid<BeanModel> grid = null; protected ListStore<BeanModel> loanStore = new ListStore<BeanModel>(); protected Button addLoanBtn = null; protected Button saveLoanRequestBtn = null; protected final SimpleComboBox<String> tagCbox = new SimpleComboBox<String>(); SimpleComboBox<String> menuTagCbox = new SimpleComboBox<String>(); protected PagingToolBar pagingTB = null; protected final StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR); protected final ToolBar actionTB = new ToolBar(); //protected BeanModel lastCreatedModel = null; protected List<BeanModel> selectedLoans = null; protected final ItemSelectorField itemSelectorField = new ItemSelectorField(); protected String descTemplateStr = "<div class=\"pige-description-column {icon} \">" + "<span class=\"pige-description-column-text \">{desc}</span>" + "</div>"; public NewLoanView(Controller controller) { super(controller, messages.createLoan()); } @Override protected void handleEvent(AppEvent event) { super.handleEvent(event); EventType type = event.getType(); if (type == AppEvents.NEW_LOAN_VIEW_EVENT) { onUpdateTagList(event); onActivateView(); } } @Override protected void initialize() { super.initialize(); proxy = new RpcProxy<PagingLoadResult<UserDetail>>() { @Override protected void load(Object loadConfig, final AsyncCallback<PagingLoadResult<UserDetail>> callback) { statusBar.setBusyText(messages.loading()); UserServiceAsync rpcService = Registry.get(PIGE.USER_SERVICE); rpcService.getAllLoan((PagingLoadConfig) loadConfig, new AsyncCallback<PagingLoadResult<Loan>>() { @Override public void onSuccess(PagingLoadResult result) { statusBar.getStatus().clearStatus(messages.loadDone()); callback.onSuccess(result); } @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } }); } }; loadConfig = new BaseFilterPagingLoadConfig(); loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy, new BeanModelReader()) { @Override protected LoadConfig newLoadConfig() { return loadConfig; } }; loader.setRemoteSort(false); loanStore = new ListStore<BeanModel>(loader); pagingTB = new PagingToolBar(PAGE_SIZE); pagingTB.bind(loader); /* * TODO: * * VOIR LES MTHODES DES CELLEDITORS POUR AMLIORER LE COMPORTEMENT * DU ROWEDITOR. EX.: setCompleteEditOnEnter... */ // Note: Les CellEditors ne gnrent pas d'vnement de type EditorEvent // moins d'tre utiliss dans un EditorGrid. List<ColumnConfig> configs = new ArrayList<ColumnConfig>(); ColumnConfig quantityCC = new ColumnConfig(Loan.QUANTITY_REF, messages.quantity(), 50); NumberFormat nf = NumberFormat.getFormat(PIGE.QUANTITY_FORMAT); quantityCC.setNumberFormat(nf); NumberField numberField = new NumberField(); numberField.setPropertyEditorType(Integer.class); numberField.setFormat(nf); numberField.setMinValue(new Integer(0)); numberField.setAllowDecimals(Boolean.FALSE); numberField.setAllowNegative(Boolean.FALSE); numberField.setMaxLength(6); quantityCC.setEditor(new CellEditor(numberField)); ; ColumnConfig descriptionCC = new ColumnConfig(Loan.DESCRIPTION_REF, messages.description(), 300); itemSelectorField.setAllowBlank(Boolean.FALSE); CellEditor descCCEditor = new CellEditor(itemSelectorField); descriptionCC.setEditor(descCCEditor); final Template descTemplate = new Template(descTemplateStr); descTemplate.compile(); descriptionCC.setRenderer(new GridCellRenderer() { @Override public Object render(ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { Loan loan = (Loan) ((BeanModel) model).getBean(); Params p = new Params(); p.set("desc", model.get(property)); if (loan.getItemId() != null) { p.set("icon", "pige-icon-visible"); } else { p.set("icon", "pige-icon-hidden"); } return descTemplate.applyTemplate(p); } }); ColumnConfig termCC = new ColumnConfig(Loan.TERM_REF, messages.term(), 100); DateTimeFormat dtf = DateTimeFormat.getFormat(PIGE.TERM_DATE_FORMAT); termCC.setDateTimeFormat(dtf); DateField dateField = new DateField(); dateField.setMinValue(new Date()); dateField.setEditable(false); dateField.setFormatValue(true); dateField.getPropertyEditor().setFormat(dtf); termCC.setEditor(new CellEditor(dateField)); ColumnConfig tagCC = new ColumnConfig(Loan.TAG_REF, messages.tag(), 100); tagCbox.setTriggerAction(TriggerAction.ALL); tagCbox.setAllowBlank(Boolean.FALSE); tagCbox.setForceSelection(Boolean.FALSE); tagCbox.setEditable(Boolean.TRUE); CellEditor tagCellEditor = new CellEditor(tagCbox) { @Override public Object preProcessValue(Object value) { if (value == null) { return value; } ModelData model = tagCbox.findModel(value.toString()); if (model != null) { return model; } return new SimpleComboValueWrapper((String) value); } @Override public Object postProcessValue(Object value) { return tagCbox.getRawValue(); } }; tagCC.setEditor(tagCellEditor); configs.add(quantityCC); configs.add(descriptionCC); configs.add(termCC); configs.add(tagCC); ColumnModel cm = new ColumnModel(configs); final RowEditor<BeanModel> rowEditor = new RowEditor<BeanModel>() { @Override protected void createButtons() { super.createButtons(); saveBtn.setText(BaseView.messages.ok()); } // 1.5.0 // Empcher que l'diteur soit fermer accidentellement lorsque // l'utilisateur appuie sur la touche "Entre" dans un des champs... // Continuer l'action que si tous les champs requis sont valides. @Override protected void onEnter(ComponentEvent ce) { if (isValid()) { super.onEnter(ce); } } }; rowEditor.setClicksToEdit(ClicksToEdit.TWO); rowEditor.addListener(Events.AfterEdit, new Listener<RowEditorEvent>() { @Override public void handleEvent(RowEditorEvent event) { BeanModel model = loanStore.getAt(event.getRowIndex());//1.4.0 if (model != null) { setLoanItem(model); model.set(NEW_TAG_FLAG, Boolean.FALSE.toString()); loanStore.update(model); } } }); rowEditor.addListener(Events.CancelEdit, new Listener<RowEditorEvent>() { @Override public void handleEvent(RowEditorEvent event) { BeanModel model = loanStore.getAt(event.getRowIndex()); //1.4.0 if (model != null) { Boolean isNew = Boolean .parseBoolean((String) model.get(NEW_TAG_FLAG, Boolean.FALSE.toString())); if (isNew) { loanStore.remove(0); } } } }); // Permet de ractiver la barre de menu lorsque l'usager est en train // d'diter une range et qu'il appuie sur "Entr" ou "chap" pour // fermer l'diteur. Listener editorListener = new Listener<ComponentEvent>() { @Override public void handleEvent(ComponentEvent event) { actionTB.setEnabled(Boolean.TRUE); } }; Listener editorListener2 = new Listener<ComponentEvent>() { @Override public void handleEvent(ComponentEvent event) { actionTB.setEnabled(Boolean.FALSE); } }; rowEditor.addListener(Events.Hide, editorListener); rowEditor.addListener(Events.Show, editorListener2); grid = new Grid<BeanModel>(loanStore, cm); grid.setLoadMask(Boolean.FALSE); grid.setBorders(Boolean.FALSE); grid.setAutoExpandColumn(Loan.DESCRIPTION_REF); grid.getView().setAutoFill(Boolean.TRUE); grid.addPlugin(rowEditor); grid.setContextMenu(createContextMenu()); grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { selectedLoans = event.getSelection(); } }); addLoanBtn = new Button(messages.addLoan()); addLoanBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.addLoanIcon())); addLoanBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { Loan loan = new Loan(); loan.setQuantity(1); loan.setDescription(messages.description()); loan.setStartDate(new Date()); loan.setTerm(new Date());// La mme journe! loan.setStatus(LoanStatus.STATUS_PENDING); BeanModelFactory factory = BeanModelLookup.get().getFactory(Loan.class); BeanModel bm = factory.createModel(loan); bm.set(NEW_TAG_FLAG, Boolean.TRUE.toString()); //setLastCreatedLoan(bm); rowEditor.stopEditing(false); loanStore.insert(bm, 0); rowEditor.startEditing(loanStore.indexOf(bm), true); ColumnConfig cf = grid.getColumnModel().getColumnById(Loan.DESCRIPTION_REF); ItemSelectorField isf = (ItemSelectorField) cf.getEditor().getField(); isf.clear(); // Patch pour le bug #009 actionTB.setEnabled(Boolean.FALSE); } }); Button deleteLoanBtn = new Button(messages.deleteLoan()); deleteLoanBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.removeLoanIcon())); deleteLoanBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { if (!validateLoanSelection()) { return; } List<Loan> loans = new ArrayList(); for (int i = 0; i < selectedLoans.size(); ++i) { Loan l = (Loan) selectedLoans.get(i).getBean(); if (l.getStatus().equals(LoanStatus.STATUS_SAVED)) { loans.add(l); } } deleteSavedLoans(loans); for (BeanModel bm : selectedLoans) { loanStore.remove(bm); } } }); Button submitLoanRequest = new Button(messages.submitRequest()); submitLoanRequest.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.loansApprovalIcon())); submitLoanRequest.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { Set lr = buildLoanRequest(Boolean.FALSE); if (lr != null) { submitLoanRequest(lr, Boolean.FALSE); resetLoanRequest(); } } }); Button resetLoanRequest = new Button(messages.clearAll()); resetLoanRequest.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.emptyLoanIcon())); resetLoanRequest.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { List<Loan> loans = new ArrayList(); for (int i = 0; i < loanStore.getCount(); ++i) { Loan l = (Loan) loanStore.getAt(i).getBean(); if (l.getStatus().equals(LoanStatus.STATUS_SAVED)) { loans.add(l); } } deleteSavedLoans(loans); resetLoanRequest(); } }); saveLoanRequestBtn = new Button(messages.saveLoanRequest()); saveLoanRequestBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.saveIcon())); saveLoanRequestBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { Set lr = buildLoanRequest(Boolean.TRUE); if (lr != null) { submitLoanRequest(lr, Boolean.TRUE); } } }); actionTB.add(addLoanBtn); actionTB.add(PigeUtil.createVerticalSeparator()); actionTB.add(deleteLoanBtn); actionTB.add(PigeUtil.createVerticalSeparator()); actionTB.add(submitLoanRequest); actionTB.add(PigeUtil.createVerticalSeparator()); actionTB.add(saveLoanRequestBtn); actionTB.add(PigeUtil.createVerticalSeparator()); actionTB.add(resetLoanRequest); actionTB.add(PigeUtil.createVerticalSeparator()); contentPanel.setTopComponent(actionTB); contentPanel.setBottomComponent(pagingTB);// 1.2 BorderLayoutData data = new BorderLayoutData(LayoutRegion.NORTH, 1); contentPanel.add(grid, data); ContentPanel panel = Registry.get(AppWidgets.APP_CONTENT_PANEL); panel.add(contentPanel); panel.layout(); List<FilterConfig> filterConfigList = new ArrayList<FilterConfig>(); loadConfig.set(PIGE.FILTER_CONFIGS, filterConfigList); FilterConfig fc = new BaseStringFilterConfig(); fc.setField(Loan.STATUS_REF); fc.setValue(LoanStatus.STATUS_SAVED); filterConfigList.add(fc); } protected void onUpdateTagList(AppEvent event) { Set<Tag> tagSet = (Set) event.getData(PIGE.TAG_SET); PIGE.__assert(tagSet != null, "tagSet est null", getClass(), "onUpdateTagList()"); tagCbox.removeAll(); menuTagCbox.removeAll(); // Populer la liste avec les libells par dfaut. tagCbox.add(messages.forHome()); menuTagCbox.add(messages.forHome()); // Populer la liste avec les libells dfinis par l'usager. for (Tag t : tagSet) { tagCbox.add(t.getName()); menuTagCbox.add(t.getName()); } } protected ListStore getLoanStore() { return loanStore; } protected Set<Loan> buildLoanRequest(Boolean save) { List<BeanModel> models = loanStore.getModels(); if (models.size() <= 0) { MessageBox.info(messages.information(), messages.loanRequestIsEmpty(), null); return null; } Set<Loan> loanRequest = new HashSet(); Loan loan; for (BeanModel bm : models) { loan = (Loan) bm.getBean(); if (save) { loan.setStatus(LoanStatus.STATUS_SAVED); } else { loan.setStatus(LoanStatus.STATUS_PENDING); } loanRequest.add(loan); } return loanRequest; } protected void submitLoanRequest(Set<Loan> loanRequest, final Boolean save) { UserServiceAsync rpcService = Registry.get(PIGE.USER_SERVICE); rpcService.addLoans(loanRequest, new AsyncCallback() { @Override public void onSuccess(Object o) { StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR); if (save) { statusBar.setTimedText(messages.saveDone()); } else { statusBar.setTimedText(messages.loanRequestSent()); } loader.load(0, PAGE_SIZE); } @Override public void onFailure(Throwable caught) { if (caught instanceof FrozenAccountException) { MessageBox.alert(messages.warning(), messages.frozenAccountNotification(), null) .setIcon(MessageBox.WARNING); } else { PIGE.handleException(caught); } } }); } protected void resetLoanRequest() { loanStore.removeAll(); } protected void deleteSavedLoans(List<Loan> savedLoans) { UserServiceAsync rpcService = Registry.get(PIGE.USER_SERVICE); rpcService.deleteSavedLoans(savedLoans, new AsyncCallback() { @Override public void onSuccess(Object o) { } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } private Boolean validateLoanSelection() { if (selectedLoans != null && selectedLoans.size() > 0) { return Boolean.TRUE; } MessageBox.info(messages.information(), messages.noLoanSelected(), null); return Boolean.FALSE; } @Override protected void onActivateView() { super.onActivateView(); // 1.5.0 // L'utilisateur sera averti que son compte est gel ds que la vue // sera charg. UserServiceAsync rpcService = Registry.get(PIGE.USER_SERVICE); rpcService.isUserFrozen(new AsyncCallback<Boolean>() { @Override public void onSuccess(Boolean frozen) { if (frozen) { actionTB.setEnabled(Boolean.FALSE); MessageBox.alert(messages.warning(), messages.frozenAccountNotification(), null) .setIcon(MessageBox.WARNING); } else { actionTB.setEnabled(Boolean.TRUE); load(); } } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } protected void load() { loader.load(0, PAGE_SIZE); } protected void setLoanItem(BeanModel model) { if (model != null) { Loan loan = (Loan) model.getBean(); Item item = itemSelectorField.getItem(); if (item != null) { loan.setItemId(item.getId()); } } } public BeanModel getSelectedLoan() { return selectedLoans.get(0); } protected Menu createContextMenu() { Menu contextMenu = new Menu(); contextMenu.add(new HeaderMenuItem(messages.loanMenu())); MenuItem viewItemMenu = new MenuItem(messages.viewItem()); viewItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent e) { viewLoanItem(); } }); MenuItem unbindItemMenu = new MenuItem(messages.unbind()); unbindItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent e) { unbindItem(); } }); final DateMenu dateMenu = new DateMenu(); dateMenu.getDatePicker().addListener(Events.Select, new Listener<ComponentEvent>() { @Override public void handleEvent(ComponentEvent ce) { //String d = DateTimeFormat.getFormat(PIGE.TERM_DATE_FORMAT) //.format(dateMenu.getDatePicker().getValue()); changeLoanDate(dateMenu.getDate()); } }); MenuItem changeTermDateItemMenu = new MenuItem(messages.changeTermDate()); changeTermDateItemMenu.setSubMenu(dateMenu); menuTagCbox.setTriggerAction(TriggerAction.ALL); menuTagCbox.setAllowBlank(Boolean.FALSE); menuTagCbox.setForceSelection(Boolean.FALSE); menuTagCbox.setEditable(Boolean.TRUE); AdapterMenuItem tagMenuAdapter = new AdapterMenuItem(menuTagCbox); tagMenuAdapter.setManageFocus(true); tagMenuAdapter.setCanActivate(true); menuTagCbox.addSelectionChangedListener(new SelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent se) { String value = (String) se.getSelectedItem().get("value"); changeLoanTag(value); } }); menuTagCbox.addKeyListener(new KeyListener() { @Override public void componentKeyUp(ComponentEvent event) { super.componentKeyUp(event); if (event.getKeyCode() == KeyCodes.KEY_ENTER) { changeLoanTag(menuTagCbox.getRawValue()); } } }); contextMenu.add(viewItemMenu); contextMenu.add(unbindItemMenu); contextMenu.add(new SeparatorMenuItem()); contextMenu.add(changeTermDateItemMenu); contextMenu.add(tagMenuAdapter); contextMenu.addListener(Events.Show, new Listener() { @Override public void handleEvent(BaseEvent be) { menuTagCbox.clear(); } }); return contextMenu; } protected void unbindItem() { if (!validateLoanSelection()) { return; } Loan loan = (Loan) getSelectedLoan().getBean(); Integer itemId = loan.getItemId(); if (itemId == null) { MessageBox.info(messages.information(), messages.noAssociatedItem(), null); return; } doUnbindItem(loan); } protected void doUnbindItem(final Loan loan) { PIGE.__assert(loan != null, "loan == null", getClass(), "doUnbindItem"); loan.setItemId(null); if (!loan.getStatus().equals(LoanStatus.STATUS_SAVED)) { loanStore.update(getSelectedLoan()); return; } ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.updateLoans(Arrays.asList(loan), new AsyncCallback() { @Override public void onSuccess(Object o) { loanStore.update(getSelectedLoan()); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } protected void viewLoanItem() { if (!validateLoanSelection()) { return; } Loan loan = (Loan) getSelectedLoan().getBean(); Integer itemId = loan.getItemId(); if (itemId == null) { MessageBox.info(messages.information(), messages.noAssociatedItem(), null); return; } doViewLoanItem(itemId); } protected void doViewLoanItem(Integer itemId) { if (itemId == null) { return; } ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.getItemById(itemId, new AsyncCallback<Item>() { @Override public void onSuccess(Item item) { if (item != null) { ItemCEVDialog dialog = new ItemCEVDialog(CEV.VIEW); dialog.setData("item", item); dialog.showDialog(); } } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } protected void changeLoanDate(Date date) { if (!validateLoanSelection()) { return; } doChangeLoanData(selectedLoans, date); } /*protected void doChangeLoanDate(final List<BeanModel> models, Date date) { //PIGE.__assert(loan != null, "loan == null", getClass(), "doUnbindItem"); Loan loan; BeanModel bm; List<Loan> loans = new ArrayList(); Iterator<BeanModel> itr = new ArrayList(models).iterator(); while (itr.hasNext()) { bm = itr.next(); loan = (Loan) bm.getBean(); //loan.setTerm(DateTimeFormat.getFormat(PIGE.TERM_DATE_FORMAT) // .parse(date)); loan.setTerm(date); if (!loan.getStatus().equals(LoanStatus.STATUS_SAVED)) { loanStore.update(bm); itr.remove(); } else { loans.add(loan); } } ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.updateLoans(loans, new AsyncCallback() { @Override public void onSuccess(Object o) { for (BeanModel bm : models) { loanStore.update(bm); } } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } */ protected void changeLoanTag(String tag) { if (!validateLoanSelection()) { return; } doChangeLoanData(selectedLoans, tag); } protected void doChangeLoanData(final List<BeanModel> models, Object value) { Loan loan; BeanModel bm; List<Loan> loans = new ArrayList(); Iterator<BeanModel> itr = new ArrayList(models).iterator(); while (itr.hasNext()) { bm = itr.next(); loan = (Loan) bm.getBean(); if (value instanceof String) { loan.setTag((String) value); } else if (value instanceof Date) { loan.setTerm((Date) value); } else { PIGE.__assert(false, "value n'est pas une date ou une string", getClass(), "doChangeLoanData"); } if (!loan.getStatus().equals(LoanStatus.STATUS_SAVED)) { loanStore.update(bm); itr.remove(); } else { loans.add(loan); } } if (loans.size() <= 0) { return; } ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.updateLoans(loans, new AsyncCallback() { @Override public void onSuccess(Object o) { for (BeanModel bm : models) { loanStore.update(bm); } } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } }