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.dialog; import ca.qc.cegepoutaouais.tge.pige.client.ui.AppWidgets; import ca.qc.cegepoutaouais.tge.pige.client.GenericUtil; import ca.qc.cegepoutaouais.tge.pige.client.PigeMessages; import ca.qc.cegepoutaouais.tge.pige.client.services.LoginServiceAsync; import ca.qc.cegepoutaouais.tge.pige.client.services.UserServiceAsync; import ca.qc.cegepoutaouais.tge.pige.client.PIGE; import ca.qc.cegepoutaouais.tge.pige.client.resources.Resources; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.StatusBar; 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.SelectionMode; import com.extjs.gxt.ui.client.core.Template; 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.event.ButtonEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.KeyListener; import com.extjs.gxt.ui.client.event.MenuEvent; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.util.Params; import com.extjs.gxt.ui.client.widget.Dialog; import com.extjs.gxt.ui.client.widget.Html; import com.extjs.gxt.ui.client.widget.Label; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.TabItem; import com.extjs.gxt.ui.client.widget.TabPanel; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.form.FormPanel; import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign; import com.extjs.gxt.ui.client.widget.form.LabelField; import com.extjs.gxt.ui.client.widget.form.ListField; import com.extjs.gxt.ui.client.widget.form.TextField; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import com.extjs.gxt.ui.client.widget.layout.FormData; import com.extjs.gxt.ui.client.widget.layout.FormLayout; 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.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AbstractImagePrototype; import com.google.gwt.user.client.ui.FlexTable; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Bote de dialogue donnant de l'information sur le compte de l'usager et * permet galement la modification de certains paramtres du compte. * * @author Renaud Brub */ public class MyAccountDialog extends Dialog { final PigeMessages messages = PIGE.messages; private TabPanel tabPanel = null; private TextField<String> newEmailTF = null; private TextField<String> oldPwdTF = null; private TextField<String> newPwdTF = null; private TextField<String> confirmNewPwdTF = null; private TextField<String> addTagTF = null; private Button addTagBtn = null; private ListField<BeanModel> tagLst = null; private ListStore<BeanModel> tagStore = null; private BeanModelFactory tagFactory = null; private Button updateBtn = null; private Button closeBtn = null; private Boolean tagListDirty = false; private String infoStrTemplate = null; private Template infoTemplate = null; private String statsStrTemplate = null; private Template statsTemplate = null; private TextField<String> totalLoansCountTF = null; public MyAccountDialog() { setupUI(); } private void setupUI() { setLayout(new FitLayout()); setModal(true); setDraggable(true); setCollapsible(false); setClosable(true); setAutoHide(false); setResizable(false); setBodyStyle("padding: 3px"); setWidth(500); setHeight(450); setButtons(""); setHeadingText(messages.myAccount()); tabPanel = new TabPanel(); createGeneralTab(); createTagManagementTab(); createStatsPanel(); add(tabPanel); infoStrTemplate = "<div style='padding-left: 7px; padding-bottom:5px;'>" + "<table style='width: 100%;'><tr>" + "<td style='{left_title_style}'>{lastname_title}:</td><td style='{value_style}'>{lastname_value}</td>" + "<td style='{right_title_style}'>{firstname_title}:</td><td style='{value_style}'>{firstname_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{identifier_title}:</td><td style='{value_style}'>{identifier_value}</td>" + "<td style='{right_title_style}'>{role_title}:</td><td style='{value_style}'>{role_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loanNo_title}:</td><td style='{value_style}'>{loanNo_value}</td>" + "</tr></tr>" + "<td style='{left_title_style}'>{email_title}:</td><td style='{value_style}' colspan='3'>{email_value}</td>" + "</tr></table></div>"; infoTemplate = new Template(infoStrTemplate); infoTemplate.compile(); statsStrTemplate = "<div style='padding-left: 7px; padding-bottom:5px;'>" + "<table style='width: 100%;'><tr>" + "<td style='{left_title_style}'>{loans_total_title}:</td><td style='{value_style}'>{loans_total_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_inPossession_title}:</td><td style='{value_style}'>{loans_inPossession_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_lent_title}:</td><td style='{value_style}'>{loans_lent_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_late_title}:</td><td style='{value_style}'>{loans_late_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_returned_title}:</td><td style='{value_style}'>{loans_returned_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_postponed_title}:</td><td style='{value_style}'>{loans_postponed_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_refused_title}:</td><td style='{value_style}'>{loans_refused_value}</td>" + "</tr><tr>" + "<td style='{left_title_style}'>{loans_saved_title}:</td><td style='{value_style}'>{loans_saved_value}</td>" + "</tr></table></div>"; statsTemplate = new Template(statsStrTemplate); statsTemplate.compile(); } @Override protected void createButtons() { super.createButtons(); updateBtn = new Button(messages.update()); updateBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.saveIcon())); updateBtn.setEnabled(Boolean.FALSE); updateBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { update(); } }); closeBtn = new Button(messages.close()); closeBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { hide(); } }); addButton(updateBtn); addButton(closeBtn); } private void createGeneralTab() { TabItem tabItem = new TabItem(messages.general()); tabItem.setStyleAttribute("padding", "3px"); LabelField infoTitleLbl = new LabelField(messages.information()); infoTitleLbl.addStyleName("pige-section-title"); tabItem.add(infoTitleLbl); final Html infoTxt = new Html(); tabItem.add(infoTxt); LoginServiceAsync rpcService = (LoginServiceAsync) Registry.get(PIGE.LOGIN_SERVICE); rpcService.getLastSessionUser((String) Registry.get(PIGE.SESSION_COOKIE), new AsyncCallback<UserDetail>() { @Override public void onSuccess(UserDetail userDetail) { Params p = new Params(); p.set("lastname_title", messages.lastname()); p.set("lastname_value", userDetail.getLastname()); p.set("firstname_title", messages.firstname()); p.set("firstname_value", userDetail.getFirstname()); p.set("identifier_title", messages.identifier()); p.set("identifier_value", userDetail.getIdentifier()); p.set("loanNo_title", messages.loanNo()); p.set("loanNo_value", userDetail.getLoanNo()); p.set("email_title", messages.email()); p.set("email_value", userDetail.getEmail()); p.set("role_title", messages.role()); p.set("role_value", userDetail.getRole().getName()); p.set("left_title_style", "text-align: right; width: 70px;"); p.set("right_title_style", "text-align: right; width: 70px;"); p.set("value_style", "color: blue; padding-left: 3px; width: 120px;"); infoTxt.setHtml(infoTemplate.applyTemplate(p)); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); KeyListener keyListener = new KeyListener() { @Override public void componentKeyUp(ComponentEvent event) { validate(); } }; LabelField changeEmailLbl = new LabelField(messages.changeYourEmailTitle()); changeEmailLbl.addStyleName("pige-section-title"); tabItem.add(changeEmailLbl); FormPanel changeEmailFormPanel = new FormPanel(); changeEmailFormPanel.setHeaderVisible(false); changeEmailFormPanel.setBodyBorder(false); changeEmailFormPanel.setLabelWidth(175); FormData formData = new FormData("95%"); FormLayout formLayout = new FormLayout(LabelAlign.LEFT); LayoutContainer changeEmailPanel = new LayoutContainer(); changeEmailPanel.setLayout(formLayout); newEmailTF = new TextField<String>(); newEmailTF.setFieldLabel(messages.newEmail()); newEmailTF.setRegex(GenericUtil.EMAIL_REGEX); newEmailTF.getMessages().setRegexText(messages.emailFormatIsIncorrect()); newEmailTF.addKeyListener(keyListener); changeEmailPanel.add(newEmailTF, formData); changeEmailFormPanel.add(changeEmailPanel); tabItem.add(changeEmailFormPanel); LabelField changePwdLbl = new LabelField(messages.changeYourPasswordTitle()); changePwdLbl.addStyleName("pige-section-title"); tabItem.add(changePwdLbl); FormPanel changePwdFormPanel = new FormPanel(); changePwdFormPanel.setHeaderVisible(false); changePwdFormPanel.setBodyBorder(false); changePwdFormPanel.setLabelWidth(175); formData = new FormData("95%"); formLayout = new FormLayout(LabelAlign.LEFT); LayoutContainer changePwdPanel = new LayoutContainer(); changePwdPanel.setLayout(formLayout); oldPwdTF = new TextField<String>(); oldPwdTF.setFieldLabel(messages.oldPassword()); oldPwdTF.setRegex(GenericUtil.PASSWORD_REGEX); oldPwdTF.getMessages().setRegexText(messages.passwordFormatIsIncorrect()); oldPwdTF.setPassword(true); oldPwdTF.addKeyListener(keyListener); newPwdTF = new TextField<String>(); newPwdTF.setFieldLabel(messages.newPassword()); newPwdTF.setRegex(GenericUtil.PASSWORD_REGEX); newPwdTF.getMessages().setRegexText(messages.passwordFormatIsIncorrect()); newPwdTF.setPassword(true); newPwdTF.addKeyListener(keyListener); confirmNewPwdTF = new TextField<String>(); confirmNewPwdTF.setFieldLabel(messages.confirmNewPassword()); confirmNewPwdTF.setRegex(GenericUtil.PASSWORD_REGEX); confirmNewPwdTF.getMessages().setRegexText(messages.passwordFormatIsIncorrect()); confirmNewPwdTF.setPassword(true); confirmNewPwdTF.addKeyListener(keyListener); changePwdPanel.add(oldPwdTF, formData); changePwdPanel.add(newPwdTF, formData); changePwdPanel.add(confirmNewPwdTF, formData); changePwdFormPanel.add(changePwdPanel); tabItem.add(changePwdFormPanel); tabPanel.add(tabItem); setFocusWidget(oldPwdTF); } private void createTagManagementTab() { TabItem tabItem = new TabItem(messages.myTags()); tabItem.setStyleAttribute("padding", "3px"); tabPanel.add(tabItem); tagFactory = BeanModelLookup.get().getFactory(Tag.class); tagStore = new ListStore<BeanModel>(); addTagTF = new TextField<String>(); addTagTF.setWidth(362); addTagTF.addKeyListener(new KeyListener() { @Override public void componentKeyUp(ComponentEvent event) { if (event.getKeyCode() == KeyCodes.KEY_ENTER) { addNewTag(); } } }); addTagBtn = new Button(messages.add()); addTagBtn.setWidth("100px"); addTagBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.addIcon())); addTagBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { addNewTag(); } }); tagLst = new ListField(); tagLst.setHeight(300); tagLst.setWidth(466); tagLst.setStore(tagStore); tagLst.getListView().getSelectionModel().setSelectionMode(SelectionMode.SINGLE); tagLst.setDisplayField("name"); tagLst.addKeyListener(new KeyListener() { @Override public void componentKeyUp(ComponentEvent event) { if (event.getKeyCode() == KeyCodes.KEY_DELETE) { deleteTag(); } } }); Menu contextMenu = new Menu(); contextMenu.add(new HeaderMenuItem(messages.tagMenu())); MenuItem deleteTagBtn = new MenuItem(messages.delete()); deleteTagBtn.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent event) { deleteTag(); } }); contextMenu.add(deleteTagBtn); tagLst.setContextMenu(contextMenu); UserServiceAsync rpcService = Registry.get(PIGE.USER_SERVICE); rpcService.getAllTag(new AsyncCallback<Set<Tag>>() { @Override public void onSuccess(Set<Tag> tagSet) { for (Tag t : tagSet) { tagStore.add(tagFactory.createModel(t)); } } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); FlexTable table = new FlexTable(); table.setWidget(0, 0, addTagTF); table.setWidget(0, 1, addTagBtn); table.setWidget(1, 0, tagLst); table.getFlexCellFormatter().setColSpan(1, 0, 2); table.setWidth("466px"); table.getFlexCellFormatter().setWidth(0, 0, "100%"); tabItem.add(table); } // 1.5.0 private void createStatsPanel() { TabItem tabItem = new TabItem(messages.statistics()); tabItem.setStyleAttribute("padding", "3px"); tabPanel.add(tabItem); final Html statsTxt = new Html(); tabItem.add(statsTxt); UserServiceAsync rpcService = (UserServiceAsync) Registry.get(PIGE.USER_SERVICE); rpcService.getUserStats(new AsyncCallback<Map<String, Long>>() { @Override public void onSuccess(Map<String, Long> stats) { Params p = new Params(); p.set("loans_total_title", messages.totalLoans()); p.set("loans_total_value", stats.get("loans.total").toString()); p.set("loans_inPossession_title", messages.loansInPossession()); p.set("loans_inPossession_value", stats.get("loans.inPossession").toString()); p.set("loans_lent_title", messages.loansLent()); p.set("loans_lent_value", stats.get("loans.lent").toString()); p.set("loans_late_title", messages.loansLate()); p.set("loans_late_value", stats.get("loans.late").toString()); p.set("loans_returned_title", messages.loansReturned()); p.set("loans_returned_value", stats.get("loans.returned").toString()); p.set("loans_postponed_title", messages.loansPostponed()); p.set("loans_postponed_value", stats.get("loans.postponed").toString()); p.set("loans_refused_title", messages.loansRefused()); p.set("loans_refused_value", stats.get("loans.refused").toString()); p.set("loans_saved_title", messages.loansSaved()); p.set("loans_saved_value", stats.get("loans.saved").toString()); p.set("left_title_style", "text-align: right; width: 100px;"); p.set("value_style", "color: blue; padding-left: 3px; width: 70px;"); statsTxt.setHtml(statsTemplate.applyTemplate(p)); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } private void setTagListDirty(Boolean b) { this.tagListDirty = b; } private Boolean isTagListDirty() { return this.tagListDirty; } private void addNewTag() { String newCat = addTagTF.getValue(); if (newCat != null & !newCat.isEmpty()) { Tag tag = new Tag(newCat); BeanModel bean = tagFactory.createModel(tag); tagStore.add(bean); addTagTF.clear(); setTagListDirty(Boolean.TRUE); validate(); } } private void deleteTag() { List<BeanModel> selection = tagLst.getSelection(); BeanModel bm; if (selection.size() > 0) { bm = selection.get(0); tagStore.remove(bm); setTagListDirty(Boolean.TRUE); validate(); } } private void clearFields() { newEmailTF.clear(); oldPwdTF.clear(); newPwdTF.clear(); confirmNewPwdTF.clear(); } private Boolean hasValue(TextField<String> field) { return field.getValue() != null && !field.getValue().isEmpty(); } private Boolean isPasswordChanging() { return hasValue(oldPwdTF) || hasValue(newPwdTF) || hasValue(confirmNewPwdTF); } private Boolean isEmailChanging() { return hasValue(newEmailTF); } private Boolean isValid() { Boolean isValid = Boolean.TRUE; confirmNewPwdTF.clearInvalid(); if (isPasswordChanging()) { isValid &= (hasValue(oldPwdTF) && hasValue(newPwdTF) && hasValue(confirmNewPwdTF) && oldPwdTF.validate() && newPwdTF.validate() && confirmNewPwdTF.validate()); String newPwd = newPwdTF.getValue(); newPwd = (newPwd == null ? new String() : newPwd); String cNewPwd = confirmNewPwdTF.getValue(); cNewPwd = (cNewPwd == null ? new String() : cNewPwd); if (!newPwd.equals(cNewPwd)) { confirmNewPwdTF.forceInvalid(messages.passwordsMismatch()); isValid = Boolean.FALSE; } } if (isEmailChanging()) { isValid = newEmailTF.validate(); } return isValid; } private void validate() { updateBtn.setEnabled(isValid() || isTagListDirty()); } private void update() { if (isValid()) { if (isPasswordChanging()) { updatePassword(); } if (isEmailChanging()) { updateEmail(); } } if (isTagListDirty()) { updateTag(); } } private void updateEmail() { UserServiceAsync rpcService = (UserServiceAsync) Registry.get(PIGE.USER_SERVICE); rpcService.updateEmail(newEmailTF.getValue(), new AsyncCallback() { @Override public void onSuccess(Object o) { clearFields(); StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR); statusBar.setTimedText(messages.accountUpdatedSuccessfully()); validate(); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } private void updateTag() { List<BeanModel> tagList = tagStore.getModels(); Set<Tag> tagSet = new HashSet(); for (BeanModel bm : tagList) { tagSet.add((Tag) bm.getBean()); } UserServiceAsync rpcService = Registry.get(PIGE.USER_SERVICE); rpcService.updateTags(tagSet, new AsyncCallback() { @Override public void onSuccess(Object o) { StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR); statusBar.setTimedText(messages.accountUpdatedSuccessfully()); setTagListDirty(Boolean.FALSE); validate(); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } private void updatePassword() { String oldPwd = oldPwdTF.getValue(); String newPwd = newPwdTF.getValue(); String confirmNewPwd = confirmNewPwdTF.getValue(); UserServiceAsync rpcService = (UserServiceAsync) Registry.get(PIGE.USER_SERVICE); rpcService.changePassword(oldPwd, newPwd, confirmNewPwd, new AsyncCallback() { @Override public void onSuccess(Object o) { clearFields(); setFocusWidget(oldPwdTF); StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR); statusBar.setTimedText(messages.accountUpdatedSuccessfully()); validate(); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } }