public MessageCenterView(String locatorId) { super( locatorId, MSG.view_messageCenter_messageTitle(), null, new SortSpecifier[] {new SortSpecifier(FIELD_TIME, SortDirection.DESCENDING)}, null, false); CoreGUI.getMessageCenter().addMessageListener(this); }
/** * Message Center view that shows the latest messages generated by the app. This is a Table and can * therefore be a member to any layout. However, it can also be displayed in its own non-modal * dialog window. If you want this table shown in a dialog window, call {@link * #showMessageCenterWindow()}. * * <p>Note: this class has to be very careful about catching any and all exceptions. Otherwise, an * uncaught exception will cause a flooding of global exception messages (since the unhandled * exception handler in CoreGUI will recursively call into this message center). * * @author John Mazzitelli */ @SuppressWarnings("unchecked") public class MessageCenterView extends Table implements MessageCenter.MessageListener { public static final String LOCATOR_ID = "MessageCenter"; public static final String TABLE_TITLE = MSG.view_messageCenter_messageTitle(); private static final String FIELD_TIME = "time"; private static final String FIELD_SEVERITY = "severity"; private static final String FIELD_CONCISEMESSAGE = "conciseMessage"; private static final String FIELD_OBJECT = "object"; private MessageCenterWindow window; public MessageCenterView(String locatorId) { super( locatorId, MSG.view_messageCenter_messageTitle(), null, new SortSpecifier[] {new SortSpecifier(FIELD_TIME, SortDirection.DESCENDING)}, null, false); CoreGUI.getMessageCenter().addMessageListener(this); } /** This will popup a non-modal dialog window with the messages in a list. */ public void showMessageCenterWindow() { try { if (window == null) { window = new MessageCenterWindow("MessageCenterViewWindow"); window.addItem(this); window.addCloseClickHandler( new CloseClickHandler() { @Override public void onCloseClick(CloseClientEvent event) { try { window.hide(); } catch (Throwable e) { Log.warn("Cannot hide message center", e); } } }); } window.show(); markForRedraw(); // need this to ensure the list grid rows are selectable } catch (Throwable e) { Log.error("Cannot show message center window", e); } } @Override public void onMessage(final Message message) { try { if (!message.isTransient()) { refresh(); if (window != null) { window.blink(); } } } catch (Throwable e) { Log.error("Cannot process message", e); } } public void reset() { if (window != null) { window.hide(); } refresh(); } @Override protected void configureTable() { getListGrid().setEmptyMessage(MSG.view_messageCenter_noRecentMessages()); updateTitleCanvas( MSG.view_messageCenter_lastNMessages( String.valueOf(CoreGUI.getMessageCenter().getMaxMessages()))); ListGridField severityField = new ListGridField(FIELD_SEVERITY); severityField.setType(ListGridFieldType.ICON); severityField.setAlign(Alignment.CENTER); severityField.setShowValueIconOnly(true); HashMap<String, String> severityIcons = new HashMap<String, String>(5); severityIcons.put(Severity.Blank.name(), getSeverityIcon(Severity.Blank)); severityIcons.put(Severity.Info.name(), getSeverityIcon(Severity.Info)); severityIcons.put(Severity.Warning.name(), getSeverityIcon(Severity.Warning)); severityIcons.put(Severity.Error.name(), getSeverityIcon(Severity.Error)); severityIcons.put(Severity.Fatal.name(), getSeverityIcon(Severity.Fatal)); severityField.setValueIcons(severityIcons); severityField.setShowHover(true); severityField.setHoverCustomizer( new HoverCustomizer() { @Override public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) { try { Severity severity = ((Message) record.getAttributeAsObject(FIELD_OBJECT)).getSeverity(); switch (severity) { case Info: return MSG.common_severity_info(); case Warning: return MSG.common_severity_warn(); case Error: return MSG.common_severity_error(); case Fatal: return MSG.common_severity_fatal(); } } catch (Throwable e) { Log.error("Cannot get severity hover", e); } return null; } }); severityField.setSortNormalizer( new SortNormalizer() { @Override public Object normalize(ListGridRecord record, String fieldName) { try { Severity severity = ((Message) record.getAttributeAsObject(FIELD_OBJECT)).getSeverity(); return Integer.valueOf(severity.ordinal()); } catch (Throwable e) { Log.error("Cannot get sort nomalizer", e); } return Integer.valueOf(0); } }); ListGridField timeField = new ListGridField(FIELD_TIME, MSG.view_messageCenter_messageTime()); timeField.setType(ListGridFieldType.TIME); timeField.setAttribute("displayFormat", TimeFormatter.TOPADDEDTIME); timeField.setAlign(Alignment.LEFT); timeField.setShowHover(true); timeField.setHoverCustomizer(TimestampCellFormatter.getHoverCustomizer(FIELD_TIME)); ListGridField messageField = new ListGridField(FIELD_CONCISEMESSAGE, MSG.common_title_message()); severityField.setWidth(25); timeField.setWidth("15%"); messageField.setWidth("*"); getListGrid().setFields(severityField, timeField, messageField); setListGridDoubleClickHandler( new DoubleClickHandler() { @Override public void onDoubleClick(DoubleClickEvent event) { try { ListGrid listGrid = (ListGrid) event.getSource(); ListGridRecord[] selectedRows = listGrid.getSelection(); if (selectedRows != null && selectedRows.length > 0) { Message message = (Message) selectedRows[0].getAttributeAsObject( FIELD_OBJECT); // show the first selected showDetails(message); } } catch (Throwable e) { Log.error("Cannot show details for message", e); } } }); addTableAction( extendLocatorId("delete"), MSG.common_button_delete(), MSG.common_msg_areYouSure(), new AbstractTableAction(TableActionEnablement.ANY) { @Override public void executeAction(ListGridRecord[] selection, Object actionValue) { try { for (ListGridRecord record : selection) { Object doomed = record.getAttributeAsObject(FIELD_OBJECT); CoreGUI.getMessageCenter().getMessages().remove(doomed); } refresh(); } catch (Throwable e) { Log.error("Cannot delete messages", e); } } }); addTableAction( extendLocatorId("deleteAll"), MSG.common_button_delete_all(), MSG.common_msg_areYouSure(), new AbstractTableAction(TableActionEnablement.ALWAYS) { @Override public void executeAction(ListGridRecord[] selection, Object actionValue) { try { CoreGUI.getMessageCenter().getMessages().clear(); refresh(); } catch (Throwable e) { Log.error("Cannot delete all messages", e); } } }); LinkedHashMap<String, Integer> maxMessagesMap = new LinkedHashMap<String, Integer>(); maxMessagesMap.put("10", Integer.valueOf("10")); maxMessagesMap.put("25", Integer.valueOf("25")); maxMessagesMap.put("50", Integer.valueOf("50")); maxMessagesMap.put("100", Integer.valueOf("100")); maxMessagesMap.put("200", Integer.valueOf("200")); addTableAction( extendLocatorId("maxMessageMenu"), MSG.view_messageCenter_maxMessages(), null, maxMessagesMap, new AbstractTableAction(TableActionEnablement.ALWAYS) { @Override public void executeAction(ListGridRecord[] selection, Object actionValue) { try { Integer maxSize = (Integer) actionValue; CoreGUI.getMessageCenter().setMaxMessages(maxSize.intValue()); updateTitleCanvas(MSG.view_messageCenter_lastNMessages(maxSize.toString())); refresh(); } catch (Throwable e) { Log.error("Cannot set max messages", e); } } }); /* // TODO only for testing, remove this when done testing addTableAction(extendLocatorId("test"), "TEST MSG", null, new AbstractTableAction(TableActionEnablement.ALWAYS) { @Override public void executeAction(ListGridRecord[] selection, Object actionValue) { for (Severity severity : java.util.EnumSet.allOf(Severity.class)) { Message m = new Message(severity.name() + ':' + System.currentTimeMillis(), severity); CoreGUI.getMessageCenter().notify(m); } } }); */ // initial population of the list with current messages try { refresh(); } catch (Throwable e) { Log.error("Cannot perform initial refresh", e); } } @Override protected SelectionStyle getDefaultSelectionStyle() { return SelectionStyle.MULTIPLE; } @Override public void refresh() { try { super.refresh(); if ((getListGrid() != null) && (CoreGUI.getMessageCenter().getMessages() != null)) { getListGrid().setRecords(transform(CoreGUI.getMessageCenter().getMessages())); } refreshTableInfo(); } catch (Throwable e) { Log.error("Cannot refresh messages", e); } } private ListGridRecord[] transform(List<Message> list) { ListGridRecord[] results = new ListGridRecord[list.size()]; for (int i = 0; i < list.size(); i++) { results[i] = transform(list.get(i)); } return results; } private ListGridRecord transform(Message msg) { ListGridRecord record = new ListGridRecord(); record.setAttribute(FIELD_TIME, msg.fired); record.setAttribute( FIELD_SEVERITY, (msg.severity != null) ? msg.severity.name() : Severity.Info.name()); record.setAttribute(FIELD_CONCISEMESSAGE, msg.conciseMessage); record.setAttribute(FIELD_OBJECT, msg); return record; } /** * This is a static utility method that is package protected so the message center view and the * message bar can pop up a dialog showing a message's details. * * @param message the message whose details are to be shown */ static void showDetails(Message message) { if (message == null) { return; } DynamicForm form = new LocatableDynamicForm("MessageCenterDetailsForm"); form.setWrapItemTitles(false); form.setAlign(Alignment.LEFT); StaticTextItem title = new StaticTextItem("theMessage", MSG.common_title_message()); title.setValue(message.conciseMessage); StaticTextItem severity = new StaticTextItem("severity", MSG.view_messageCenter_messageSeverity()); FormItemIcon severityIcon = new FormItemIcon(); severityIcon.setSrc(getSeverityIcon(message.severity)); severity.setIcons(severityIcon); severity.setValue(message.severity.name()); StaticTextItem date = new StaticTextItem("time", MSG.view_messageCenter_messageTime()); date.setValue( TimestampCellFormatter.format(message.fired, TimestampCellFormatter.DATE_TIME_FORMAT_FULL)); StaticTextItem detail = new StaticTextItem("detail", MSG.view_messageCenter_messageDetail()); detail.setTitleVAlign(VerticalAlignment.TOP); detail.setValue(message.detailedMessage); form.setItems(title, severity, date, detail); final Window dialogWin = new LocatableWindow("MessageCenterDetailsWindow"); dialogWin.setTitle(MSG.common_title_message()); dialogWin.setWidth(600); dialogWin.setHeight(400); dialogWin.setIsModal(true); dialogWin.setShowModalMask(true); dialogWin.setCanDragResize(true); dialogWin.setShowMaximizeButton(true); dialogWin.setShowMinimizeButton(false); dialogWin.centerInPage(); dialogWin.addItem(form); dialogWin.show(); dialogWin.addCloseClickHandler( new CloseClickHandler() { @Override public void onCloseClick(CloseClientEvent event) { dialogWin.destroy(); } }); } private static String getSeverityIcon(Message.Severity severity) { if (severity == null) { severity = Severity.Blank; } return severity.getIcon(); } static class MessageCenterWindow extends LocatableWindow { private Timer blinkTimer; public MessageCenterWindow(String locatorId) { super(locatorId); setTitle(TABLE_TITLE); setShowMinimizeButton(true); setShowMaximizeButton(true); setShowCloseButton(true); setIsModal(false); setShowModalMask(false); setWidth(700); setHeight(300); setShowResizer(true); setCanDragResize(true); centerInPage(); final String origColor = getBodyColor(); blinkTimer = new Timer() { @Override public void run() { try { setBodyColor(origColor); setTitle(TABLE_TITLE); redraw(); } catch (Throwable e) { Log.error("Blink timer failed", e); } } }; } public void blink() { try { // window.flash() isn' t working so do it ourselves if (getMinimized()) { setTitle(TABLE_TITLE + " *"); } else { setBodyColor(getHiliteBodyColor()); } redraw(); blinkTimer.schedule(250); } catch (Throwable e) { Log.error("Cannot blink message center window", e); } } } }