Java tutorial
/* Copyright 2010 Jeremie Gottero This file is part of Fallen Galaxy. Fallen Galaxy is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fallen Galaxy 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Fallen Galaxy. If not, see <http://www.gnu.org/licenses/>. */ package fr.fg.client.core; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.WindowResizeListener; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; import fr.fg.client.ajax.Action; import fr.fg.client.ajax.ActionCallback; import fr.fg.client.ajax.ActionCallbackAdapter; import fr.fg.client.core.settings.Settings; import fr.fg.client.core.tactics.TacticsTools; import fr.fg.client.data.AnswerData; import fr.fg.client.data.MessageBoxData; import fr.fg.client.data.MessageData; import fr.fg.client.data.TreatyData; import fr.fg.client.i18n.StaticMessages; import fr.fg.client.openjwt.OpenJWT; import fr.fg.client.openjwt.core.Config; import fr.fg.client.openjwt.ui.JSButton; import fr.fg.client.openjwt.ui.JSDialog; import fr.fg.client.openjwt.ui.JSLabel; import fr.fg.client.openjwt.ui.JSList; import fr.fg.client.openjwt.ui.JSOptionPane; import fr.fg.client.openjwt.ui.JSRowLayout; import fr.fg.client.openjwt.ui.JSScrollPane; import fr.fg.client.openjwt.ui.JSTabbedPane; import fr.fg.client.openjwt.ui.OptionPaneListener; import fr.fg.client.openjwt.ui.SelectionListener; public class Messenger extends JSDialog implements SelectionListener, ClickListener, ActionCallback, WindowResizeListener { // ------------------------------------------------------- CONSTANTES -- // private final static int MESSAGES_PER_PAGE = 25; private final static int FOLDER_INBOX = 0, FOLDER_SENT = 1, FOLDER_ARCHIVES = 2; private final static int HIGH_RES_EXTRA_WIDTH = 180, HIGH_RES_EXTRA_HEIGHT = 140; // -------------------------------------------------------- ATTRIBUTS -- // private int currentClientWidth; private boolean highres; private JSTabbedPane foldersPane; private JSButton writeBt, answerBt, deleteBt, bookmarkBt, previousPageBt, nextPageBt, closeBt, forwardBt; private JSList messagesList; private JSScrollPane messageScrollPane; private HTMLPanel messagePanel; private JSLabel pageLabel, separator; private JSRowLayout layout; private int currentFolder, currentPage; private long lastUpdate; private int unreadMessages; private HTMLPanel horizontalSeparator; private Action downloadAction; private ArrayList<MessageData> inboxMessages, sentboxMessages, bookmarkedMessages; // ---------------------------------------------------- CONSTRUCTEURS -- // public Messenger() { super("<img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" class=\"iconMessages\"/> " + "Messages", false, true, true); StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); // Date du dernier tlchargement des messages lastUpdate = 0; unreadMessages = 0; currentClientWidth = OpenJWT.getClientWidth(); highres = currentClientWidth > 1024; currentFolder = FOLDER_INBOX; currentPage = 0; inboxMessages = new ArrayList<MessageData>(); sentboxMessages = new ArrayList<MessageData>(); bookmarkedMessages = new ArrayList<MessageData>(); // Choix de la boite ArrayList<String> folders = new ArrayList<String>(); folders.add("<img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" class=\"tabIcon iconMsgInbox\"/> " + messages.inbox()); folders.add("<img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" class=\"tabIcon iconMsgSent\"/> " + messages.sentbox()); folders.add("<img src=\"" + Config.getMediaUrl() + "images/misc/blank.gif\" class=\"tabIcon iconMsgArchives\"/> " + messages.archives()); foldersPane = new JSTabbedPane(); foldersPane.setPixelWidth(550 + (highres ? HIGH_RES_EXTRA_WIDTH : 0)); foldersPane.addTabs(folders); foldersPane.addSelectionListener(this); // Boutons de la barre d'outils writeBt = new JSButton(messages.write()); writeBt.setPixelWidth(180); writeBt.addClickListener(this); deleteBt = new JSButton(messages.delete()); deleteBt.setPixelWidth(100); deleteBt.addClickListener(this); deleteBt.setVisible(false); answerBt = new JSButton(messages.answer()); answerBt.setPixelWidth(100); answerBt.addClickListener(this); answerBt.setVisible(false); bookmarkBt = new JSButton(messages.bookmark()); bookmarkBt.setPixelWidth(100); bookmarkBt.addClickListener(this); bookmarkBt.setVisible(false); closeBt = new JSButton(messages.close()); closeBt.setPixelWidth(100); closeBt.addClickListener(this); closeBt.setVisible(false); forwardBt = new JSButton("Transfrer"); forwardBt.setPixelWidth(100); forwardBt.addClickListener(this); forwardBt.setVisible(false); // Pages suivante / prcdente previousPageBt = new JSButton(); previousPageBt.setPixelWidth(31); previousPageBt.addStyleName("iconLeft"); previousPageBt.addClickListener(this); previousPageBt.setVisible(false); nextPageBt = new JSButton(); nextPageBt.setPixelWidth(31); nextPageBt.addStyleName("iconRight"); nextPageBt.addClickListener(this); nextPageBt.setVisible(false); pageLabel = new JSLabel(); pageLabel.setPixelWidth(60); pageLabel.setAlignment(JSLabel.ALIGN_CENTER); separator = new JSLabel(); separator.setPixelWidth(248 + (highres ? HIGH_RES_EXTRA_WIDTH : 0)); // Liste des messages messagesList = new JSList(); messagesList.setPixelSize(550 + (highres ? HIGH_RES_EXTRA_WIDTH : 0), 280 + (highres ? HIGH_RES_EXTRA_HEIGHT : 0)); messagesList.addStyleName("messages"); messagesList.addSelectionListener(this); // Contenu d'un message messagePanel = new HTMLPanel(""); OpenJWT.setElementFloat(messagePanel.getElement(), "left"); messageScrollPane = new JSScrollPane(); messageScrollPane.setView(messagePanel); messageScrollPane.setPixelSize(550 + (highres ? HIGH_RES_EXTRA_WIDTH : 0), 182 + (highres ? HIGH_RES_EXTRA_HEIGHT / 2 : 0)); messageScrollPane.setVisible(false); horizontalSeparator = new HTMLPanel(""); horizontalSeparator.addStyleName("horizontalSeparator"); horizontalSeparator.setWidth(550 + (highres ? HIGH_RES_EXTRA_WIDTH : 0) + "px"); horizontalSeparator.setVisible(false); OpenJWT.setElementFloat(horizontalSeparator.getElement(), "left"); // Mise en forme des composants layout = new JSRowLayout(); layout.addComponent(foldersPane); layout.addRowSeparator(3); layout.addComponent(writeBt); layout.addComponent(separator); layout.addComponent(previousPageBt); layout.addComponent(pageLabel); layout.addComponent(nextPageBt); layout.addRowSeparator(1); layout.addComponent(messagesList); layout.addRowSeparator(1); layout.addComponent(horizontalSeparator); layout.addRowSeparator(1); layout.addComponent(messageScrollPane); layout.addRow(); layout.addComponent(answerBt); layout.addComponent(forwardBt); layout.addComponent(deleteBt); layout.addComponent(bookmarkBt); layout.addComponent(closeBt); setComponent(layout); centerOnScreen(); Window.addWindowResizeListener(this); } // --------------------------------------------------------- METHODES -- // public void setVisible(boolean visible) { super.setVisible(visible); if (visible) { if (downloadAction != null && downloadAction.isPending()) return; HashMap<String, String> params = new HashMap<String, String>(); params.put("update", String.valueOf(lastUpdate)); downloadAction = new Action("messages/get", params, this); } } public void selectionChanged(Widget sender, int newValue, int oldValue) { StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); if (sender == foldersPane) { messagesList.setSelectedIndex(-1); currentFolder = newValue; currentPage = 0; updateUI(); } else if (sender == messagesList) { if (newValue != -1) { // Affiche le contenu du message MessageData currentMessage = getSelectedMessage(); String date = DateTimeFormat.getFormat(messages.dateTimeFormat()) .format(new Date((long) (1000 * currentMessage.getDate()))); messagePanel.getElement().setInnerHTML("<div style=\"padding: 3px;\">" + "<div class=\"messageHeader\">" + (currentMessage.hasTargetPlayer() ? "<span class=\"owner-" + TreatyData.getPact(currentMessage.getTreaty()) + "\">" + (currentMessage.hasAllyTag() ? "<span unselectable=\"on\" class=\"allyTag\">[" + currentMessage.getAllyTag() + "]</span> " : "") + currentMessage.getTargetPlayer() + "</span> - " : "") + currentMessage.getTitle() + "</div>" + "<div style=\"padding: 5px 0;\">" + TacticsTools.parseTacticsLinks(Utilities.parseUrlAndSmilies(currentMessage.getContent())) + "</div>" + "<div class=\"small messageDate\">Envoy le " + date + "</div></div>"); horizontalSeparator.setVisible(true); messagesList.setPixelSize(550 + (highres ? HIGH_RES_EXTRA_WIDTH : 0), 70 + (highres ? HIGH_RES_EXTRA_HEIGHT / 2 : 0)); messageScrollPane.setVisible(true); deleteBt.setVisible(true); answerBt.setVisible(currentMessage.hasTargetPlayer()); bookmarkBt.setVisible( Settings.isPremium() && currentFolder == FOLDER_INBOX && !currentMessage.isBookmark()); forwardBt.setVisible(true); closeBt.setVisible(true); // Marque le message comme lu si ce n'est pas le cas if (!currentMessage.isRead()) { currentMessage.setRead(true); messagesList.setItemAt(new MessageUI(currentMessage), newValue); unreadMessages--; if (unreadMessages == 0) Client.getInstance().getToolBar().blinkMessages(false); HashMap<String, String> params = new HashMap<String, String>(); params.put("id", String.valueOf(currentMessage.getId())); new Action("messages/setread", params); } } else { horizontalSeparator.setVisible(false); messagesList.setPixelSize(550 + (highres ? HIGH_RES_EXTRA_WIDTH : 0), 280 + (highres ? HIGH_RES_EXTRA_HEIGHT : 0)); messageScrollPane.setVisible(false); messagePanel.getElement().setInnerHTML(""); deleteBt.setVisible(false); answerBt.setVisible(false); bookmarkBt.setVisible(false); forwardBt.setVisible(false); closeBt.setVisible(false); } messageScrollPane.update(); messageScrollPane.scrollUp(99999); layout.update(); } } public void onClick(Widget sender) { StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); if (sender == writeBt) { WriteMessageDialog dialog = new WriteMessageDialog(WriteMessageDialog.TYPE_MESSAGE, lastUpdate, WriteMessageDialog.OPTION_RECEIVER | WriteMessageDialog.OPTION_TITLE); dialog.setVisible(true); } else if (sender == deleteBt) { // Supprime le message slectionn if (messagesList.getSelectedIndex() != -1) { JSOptionPane.showMessageDialog(messages.confirmDel(), "Confirmation", JSOptionPane.OK_OPTION | JSOptionPane.CANCEL_OPTION, JSOptionPane.QUESTION_MESSAGE, new OptionPaneListener() { public void optionSelected(Object option) { if ((Integer) option == JSOptionPane.OK_OPTION) { MessageData message = getSelectedMessage(); HashMap<String, String> params = new HashMap<String, String>(); params.put("id", String.valueOf(message.getId())); new Action("messages/delete", params); // Supprime le message de la liste des messages getCurrentMessages().remove(messagesList.getSelectedIndex()); if (currentFolder == FOLDER_ARCHIVES) { for (int i = 0; i < inboxMessages.size(); i++) if (inboxMessages.get(i).getId() == message.getId()) { inboxMessages.remove(i); break; } } messagesList.removeItemAt(messagesList.getSelectedIndex()); } } }); } } else if (sender == forwardBt) { // Transfrer un message MessageData message = getSelectedMessage(); String title = message.getTitle(); if (!title.startsWith("Tr :")) title = "Tr : " + title; if (title.length() > 30) title = title.substring(0, 30); WriteMessageDialog dialog = new WriteMessageDialog(WriteMessageDialog.TYPE_MESSAGE, lastUpdate, WriteMessageDialog.OPTION_RECEIVER | WriteMessageDialog.OPTION_TITLE, "", title, message.getContent()); dialog.setVisible(true); } else if (sender == answerBt) { // Rponse un message MessageData message = getSelectedMessage(); // Titre du message, en ajoutant Re : ou Re(xx) : au titre String title; String messageTitle = message.getTitle(); if (messageTitle.indexOf("Re(") == 0 || messageTitle.indexOf("Re :") == 0) { if (messageTitle.indexOf("Re(") == 0 && messageTitle.indexOf(") :") != -1) { String number = messageTitle.substring(3, messageTitle.indexOf(")")); try { int index = Integer.parseInt(number); if (index > 0) title = "Re(" + (index + 1) + ") :" + messageTitle.substring(6 + number.length()); else title = "Re : " + messageTitle; } catch (Exception e) { title = "Re : " + messageTitle; } } else { title = "Re(2) : " + messageTitle.substring(4); } } else { title = "Re : " + messageTitle; } if (title.length() > 30) title = title.substring(0, 30); WriteMessageDialog dialog = new WriteMessageDialog(WriteMessageDialog.TYPE_MESSAGE, lastUpdate, WriteMessageDialog.OPTION_RECEIVER | WriteMessageDialog.OPTION_TITLE, message.getTargetPlayer(), title); dialog.setVisible(true); } else if (sender == bookmarkBt) { // Archivage du message final MessageData message = getSelectedMessage(); if (!message.isBookmark()) { HashMap<String, String> params = new HashMap<String, String>(); params.put("id", String.valueOf(message.getId())); new Action("messages/bookmark", params, new ActionCallbackAdapter() { public void onSuccess(AnswerData data) { // Marque le message comme archiv message.setBookmark(true); for (MessageData msg : inboxMessages) if (msg.getId() == message.getId()) { msg.setBookmark(true); break; } messagesList.setItemAt(new MessageUI(message), messagesList.getSelectedIndex()); bookmarkBt.setVisible(false); layout.update(); // Ajoute le message aux messages archivs for (int i = 0; i < bookmarkedMessages.size(); i++) { if (bookmarkedMessages.get(i).getDate() < message.getDate()) { bookmarkedMessages.add(i, message); return; } } bookmarkedMessages.add(message); } }); } } else if (sender == nextPageBt) { currentPage++; updateUI(); } else if (sender == previousPageBt) { currentPage--; updateUI(); } else if (sender == closeBt) { messagesList.setSelectedIndex(-1); } } public void onFailure(String error) { ActionCallbackAdapter.onFailureDefaultBehavior(error); } public void onSuccess(AnswerData data) { MessageBoxData box = data.getMessageBox(); this.lastUpdate = (long) box.getLastUpdate(); boolean updateUI = false; // Messages reus for (int i = 0; i < box.getReceivedMessageCount(); i++) { inboxMessages.add(0, box.getReceivedMessageAt(i)); if (box.getReceivedMessageAt(i).isBookmark()) { bookmarkedMessages.add(0, box.getReceivedMessageAt(i)); if (currentFolder == FOLDER_ARCHIVES) updateUI = true; } if (currentFolder == FOLDER_INBOX) updateUI = true; } // Messages envoys for (int i = 0; i < box.getSentMessageCount(); i++) { sentboxMessages.add(0, box.getSentMessageAt(i)); if (currentFolder == FOLDER_SENT) updateUI = true; } if (updateUI) updateUI(); } public int getUnreadMessages() { return unreadMessages; } public void setUnreadMessages(int unreadMessages) { this.unreadMessages = unreadMessages; if (unreadMessages > 0) Client.getInstance().getToolBar().blinkMessages(true); if (isVisible()) { if (downloadAction != null && downloadAction.isPending()) return; HashMap<String, String> params = new HashMap<String, String>(); params.put("update", String.valueOf(lastUpdate)); downloadAction = new Action("messages/get", params, this); } } public void onWindowResized(int width, int height) { int clientWidth = Window.getClientWidth(); highres = clientWidth > 1024; if (currentClientWidth > 1024 && clientWidth <= 1024) { foldersPane.setPixelWidth(550); messagesList.setPixelSize(550, (messagesList.getSelectedIndex() != -1 ? 70 : 280)); messageScrollPane.setPixelSize(550, 182); horizontalSeparator.setWidth("550px"); separator.setPixelWidth(248); layout.update(); updateUI(); if (isVisible()) centerOnScreen(); } else if (currentClientWidth <= 1024 && clientWidth > 1024) { foldersPane.setPixelWidth(550 + HIGH_RES_EXTRA_WIDTH); messagesList.setPixelSize(550 + HIGH_RES_EXTRA_WIDTH, messagesList.getSelectedIndex() != -1 ? 70 + HIGH_RES_EXTRA_HEIGHT / 2 : 280 + HIGH_RES_EXTRA_HEIGHT); messageScrollPane.setPixelSize(550 + HIGH_RES_EXTRA_WIDTH, 182 + HIGH_RES_EXTRA_HEIGHT / 2); horizontalSeparator.setWidth((550 + HIGH_RES_EXTRA_WIDTH) + "px"); separator.setPixelWidth(248 + HIGH_RES_EXTRA_WIDTH); layout.update(); updateUI(); if (isVisible()) centerOnScreen(); } currentClientWidth = clientWidth; } // ------------------------------------------------- METHODES PRIVEES -- // private ArrayList<MessageData> getCurrentMessages() { switch (currentFolder) { case FOLDER_INBOX: return inboxMessages; case FOLDER_SENT: return sentboxMessages; case FOLDER_ARCHIVES: return bookmarkedMessages; } return null; } public MessageData getSelectedMessage() { return messagesList.getSelectedIndex() != -1 ? ((MessageUI) messagesList.getSelectedItem()).getData() : null; } private void updateUI() { MessageData selectedMessage = getSelectedMessage(); ArrayList<MessageData> messages = getCurrentMessages(); if (messages.size() > MESSAGES_PER_PAGE) { int maxPage = (int) Math.ceil(messages.size() / (double) MESSAGES_PER_PAGE); pageLabel.setText("<b>" + (currentPage + 1) + "</b> / " + maxPage); pageLabel.setVisible(true); previousPageBt.setVisible(true); nextPageBt.setVisible(true); previousPageBt.getElement().getStyle().setProperty("visibility", currentPage == 0 ? "hidden" : ""); nextPageBt.getElement().getStyle().setProperty("visibility", currentPage == maxPage - 1 ? "hidden" : ""); } else { previousPageBt.setVisible(false); pageLabel.setVisible(false); nextPageBt.setVisible(false); } layout.update(); int selectedIndex = -1; ArrayList<MessageUI> items = new ArrayList<MessageUI>(); int limit = Math.min(messages.size(), (currentPage + 1) * MESSAGES_PER_PAGE); for (int i = currentPage * MESSAGES_PER_PAGE; i < limit; i++) { items.add(new MessageUI(messages.get(i))); if (selectedMessage != null && selectedMessage.getId() == messages.get(i).getId()) selectedIndex = i; } messagesList.setItems(items); messagesList.setSelectedIndex(selectedIndex); messagesList.getScrollPane().scrollUp(9999); } private class MessageUI { // --------------------------------------------------- CONSTANTES -- // // ---------------------------------------------------- ATTRIBUTS -- // private MessageData data; // ------------------------------------------------ CONSTRUCTEURS -- // public MessageUI(MessageData data) { this.data = data; } // ----------------------------------------------------- METHODES -- // public MessageData getData() { return data; } public String toString() { StaticMessages messages = (StaticMessages) GWT.create(StaticMessages.class); long now = Utilities.getCurrentTime(); // Affiche l'heure quand le message a t envoy dans la journe String date; if ((int) Math.floor(now / (3600 * 24)) == (int) Math.floor(data.getDate() / (3600 * 24))) date = DateTimeFormat.getFormat(messages.timeFormat()) .format(new Date((long) (1000 * data.getDate()))); else date = DateTimeFormat.getFormat(messages.dateFormat()) .format(new Date((long) (1000 * data.getDate()))); return "<table " + (!data.isRead() ? "class=\"unread\" " : "") + "unselectable=\"on\" cellspacing=\"0\"><tr unselectable=\"on\">" + "<td unselectable=\"on\" style=\"width: 20px;\">" + (data.isBookmark() ? "<div class=\"bookmark\"></div>" : "") + "</td>" + "<td " + (data.hasTargetPlayer() ? "class=\"owner-" + TreatyData.getPact(data.getTreaty()) + "\" " : "") + "unselectable=\"on\" " + "style=\"width: " + (170 + (highres ? 40 : 0)) + "px;\">" + (data.hasTargetPlayer() ? (data.hasAllyTag() ? "<span unselectable=\"on\" class=\"allyTag\">[" + data.getAllyTag() + "]</span> " : "") + data.getTargetPlayer() : "-") + "</td>" + "<td unselectable=\"on\" style=\"width: " + (270 + (highres ? HIGH_RES_EXTRA_WIDTH - 60 : 0)) + "px;\">" + Utilities.parseSmilies(data.getTitle()) + "</td>" + "<td class=\"center\" unselectable=\"on\" style=\"width: " + (80 + (highres ? 20 : 0)) + "px;\">" + date + "</td></tr></table>"; } // --------------------------------------------- METHODES PRIVEES -- // } }