package com.google.gwt.gwtpages.client.message.ui; import java.util.HashMap; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.HasHandlers; import com.google.gwt.gwtpages.client.Pages; import com.google.gwt.gwtpages.client.event.MessageChangeEvent; import com.google.gwt.gwtpages.client.event.MessageChangeEvent.MessageChangeHandler; import com.google.gwt.gwtpages.client.message.Message; import com.google.gwt.gwtpages.client.message.Messages; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.TextBoxBase; /** * Default drop-in component used to display GWT Page messages. These messages * can be applied using the {@link Messages} class. Messages will automatically * be applied to this component as it receives {@link MessageChangeEvent} * events. * * The DOM structure of the rendered output is: <div> <div class= * "messages {messages-success|messages-info|messages-warn|messages-error|messages-fatal}" * > <div class= * "message {message-success|message-info|message-warn|message-error|message-fatal}" * >message text</div> </div> </div> * * @author Joe Hudson */ public class MessagePanel extends Composite implements MessageChangeHandler { protected SimplePanel outerContainer; protected FlowPanel messagesContainer; protected boolean listenForEvents = true; protected HandlerRegistration registration; protected HandlerManager eventBus = null; private static MessagePanelClientBundle bundle = GWT .create(MessagePanelClientBundle.class); static { bundle.css().ensureInjected(); } public MessagePanel() { this(((MessagePanelClientBundle) (MessagePanelClientBundle) GWT .create(MessagePanelClientBundle.class)).css(), null); } public MessagePanel(MessagePanelCSS css, HandlerManager eventBus) { outerContainer = new SimplePanel(); initWidget(outerContainer); outerContainer.add(this.messagesContainer = new FlowPanel()); this.eventBus = eventBus; getCss().ensureInjected(); } public MessagePanel listenForEvents(boolean listenForEvents) { this.listenForEvents = listenForEvents; if (!listenForEvents && null != registration) registration.removeHandler(); else if (listenForEvents && null == registration && isAttached()) { registration = eventBus.addHandler(MessageChangeEvent.TYPE, this); } return this; } public void onReplaceMessages(Message[] messages, HasHandlers scopedWidget) { clearMessages(scopedWidget); addMessages(messages); resetStyle(); } public void onAddMessages(Message[] messages) { addMessages(messages); resetStyle(); } public void onClearMessages(HasHandlers scopedWidget) { clearMessages(scopedWidget); resetStyle(); } protected void addMessages(Message[] messages) { if (null != messages) { for (Message message : messages) messagesContainer.add(new MessageEntry(message)); } } protected void clearMessages(HasHandlers scopedWidget) { if (null != scopedWidget) { for (int i = messagesContainer.getWidgetCount() - 1; i >= 0; i--) { MessageEntry entry = (MessageEntry) messagesContainer .getWidget(i); if (null != entry.message.getWidget() && entry.message.getWidget().equals(scopedWidget)) { messagesContainer.remove(i); } } } else { messagesContainer.clear(); } } @Override protected void onLoad() { super.onLoad(); registerHandler(); } @Override protected void onUnload() { super.onUnload(); messagesContainer.clear(); outerContainer.setVisible(false); if (null != registration) { registration.removeHandler(); registration = null; } } protected void registerHandler() { if (listenForEvents) { if (null == eventBus) eventBus = Pages.get().getEventBus(); if (null == registration) registration = eventBus.addHandler(MessageChangeEvent.TYPE, this); } } protected void resetStyle() { if (messagesContainer.getWidgetCount() == 0) { outerContainer.setVisible(false); } else { messagesContainer.setStyleName(null); HashMap<Integer, Integer> messageLevels = new HashMap<Integer, Integer>(); outerContainer.setVisible(true); for (int i = messagesContainer.getWidgetCount() - 1; i >= 0; i--) { MessageEntry entry = (MessageEntry) messagesContainer .getWidget(i); messageLevels.put(entry.message.getLevel(), entry.message.getLevel()); } if (messageLevels.size() == 1) { int level = messageLevels.values().iterator().next(); if (level == Message.LEVEL_SUCCESS) messagesContainer.setStyleName(getCss().messages() + " " + getCss().successMessages()); else if (level == Message.LEVEL_ERROR) messagesContainer.setStyleName(getCss().messages() + " " + getCss().errorMessages()); else if (level == Message.LEVEL_WARN) messagesContainer.setStyleName(getCss().messages() + " " + getCss().warnMessages()); else if (level == Message.LEVEL_INFO) messagesContainer.setStyleName(getCss().messages() + " " + getCss().infoMessages()); else messagesContainer.setStyleName(getCss().messages()); } else { messagesContainer.setStyleName(getCss().messages() + " " + getCss().multiMessages()); } messagesContainer.getElement().scrollIntoView(); } } public class MessageEntry extends SimplePanel implements ClickHandler { private Message message; public MessageEntry(Message message) { this.message = message; MessagePanelCSS css = getCss(); if (null != message.getWidget() && message.getWidget() instanceof Focusable) { Anchor anchor = new Anchor(message.getMessage()); anchor.addClickHandler(this); add(anchor); } else { add(new Label(message.getMessage())); } if (message.getLevel() == Message.LEVEL_FATAL) { addStyleName(css.message() + " " + css.errorMessage()); } else if (message.getLevel() == Message.LEVEL_ERROR) { addStyleName(css.message() + " " + css.errorMessage()); } else if (message.getLevel() == Message.LEVEL_WARN) { addStyleName(css.message() + " " + css.warnMessage()); } else if (message.getLevel() == Message.LEVEL_INFO) { addStyleName(css.message() + " " + css.infoMessage()); } else if (message.getLevel() == Message.LEVEL_SUCCESS) { addStyleName(css.message() + " " + css.successMessage()); } else { addStyleName(css.message()); } } public void onClick(ClickEvent event) { ((Focusable) message.getWidget()).setFocus(true); if (message.getWidget() instanceof TextBoxBase) ((TextBoxBase) message.getWidget()).selectAll(); } } protected MessagePanelCSS getCss() { return bundle.css(); } }