Java tutorial
/******************************************************************************* * Copyright 2011 Krzysztof Otrebski * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package pl.otros.logview.gui; import java.awt.Color; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.logging.Logger; import javax.swing.Icon; import javax.swing.JTable; import javax.swing.JTextPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.text.BadLocationException; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.StyledDocument; import org.apache.commons.lang.StringUtils; import pl.otros.logview.LogData; import pl.otros.logview.Note; import pl.otros.logview.gui.message.MessageColorizer; import pl.otros.logview.gui.message.MessageFormatter; import pl.otros.logview.gui.message.SearchResultColorizer; import pl.otros.logview.gui.note.NoteEvent; import pl.otros.logview.gui.note.NoteObserver; import pl.otros.logview.gui.renderers.LevelRenderer; import pl.otros.logview.pluginable.PluginableElement; import pl.otros.logview.pluginable.PluginableElementEventListener; import pl.otros.logview.pluginable.PluginableElementsContainer; import com.google.common.base.Joiner; public class MessageDetailListener implements ListSelectionListener, NoteObserver { private static final Logger LOGGER = Logger.getLogger(MessageDetailListener.class.getName()); private JTable table; private JTextPane logDetailTextArea; private LogDataTableModel dataTableModel; private SimpleDateFormat dateFormat; private Style defaultStyle = null; private Style mainStyle = null; private Style classMethodStyle = null; private Style noteStyle = null; private StyleContext sc; private final PluginableElementsContainer<MessageColorizer> colorizersContainer; private final PluginableElementsContainer<MessageFormatter> formattersContainer; private MessageColorizer searchResultMessageColorizer = null; private int maximumMessageSize = 200 * 1024; public MessageDetailListener(JTable table, JTextPane logDetailTextArea, LogDataTableModel dataTableModel, SimpleDateFormat dateFormat, PluginableElementsContainer<MessageFormatter> formattersContainer, PluginableElementsContainer<MessageColorizer> colorizersContainer) { super(); this.table = table; this.logDetailTextArea = logDetailTextArea; this.dataTableModel = dataTableModel; this.dateFormat = dateFormat; this.formattersContainer = formattersContainer; this.colorizersContainer = colorizersContainer; sc = new StyleContext(); defaultStyle = sc.getStyle(StyleContext.DEFAULT_STYLE); mainStyle = sc.addStyle("MainStyle", defaultStyle); StyleConstants.setFontSize(mainStyle, 12); StyleConstants.setForeground(mainStyle, Color.BLACK); classMethodStyle = sc.addStyle("classMethod", null); StyleConstants.setFontFamily(classMethodStyle, "monospaced"); StyleConstants.setForeground(classMethodStyle, Color.BLUE); noteStyle = sc.addStyle("note", mainStyle); StyleConstants.setFontFamily(noteStyle, "arial"); StyleConstants.setBold(noteStyle, true); formattersContainer.addListener(new PluginableElementEventListenerImplementation<MessageFormatter>()); colorizersContainer.addListener(new PluginableElementEventListenerImplementation<MessageColorizer>()); } @Override public void valueChanged(ListSelectionEvent e) { updateInfo(); } @Override public void update(NoteEvent noteEvent) { updateInfo(); } public void updateInfo() { Collection<MessageFormatter> formatters = formattersContainer.getElements(); Collection<MessageColorizer> colorizers = colorizersContainer.getElements(); int row = table.getSelectedRow(); if (row >= 0 && row < table.getRowCount()) { logDetailTextArea.setText(""); int rowConverted = table.convertRowIndexToModel(row); LogData ld = dataTableModel.getLogData(rowConverted); StyledDocument document = logDetailTextArea.getStyledDocument(); synchronized (document) { try { document.remove(0, document.getLength()); String s1 = "Date: " + dateFormat.format(ld.getDate()) + "\n"; document.insertString(0, s1, mainStyle); s1 = "Class: " + ld.getClazz() + "\n"; document.insertString(document.getLength(), s1, classMethodStyle); s1 = "Method: " + ld.getMethod() + "\n"; document.insertString(document.getLength(), s1, classMethodStyle); s1 = "Level: "; document.insertString(document.getLength(), s1, classMethodStyle); Icon levelIcon = LevelRenderer.getIconByLevel(ld.getLevel()); if (levelIcon != null) { logDetailTextArea.insertIcon(levelIcon); } s1 = " " + ld.getLevel().getName() + "\n"; document.insertString(document.getLength(), s1, classMethodStyle); s1 = "Message: "; document.insertString(document.getLength(), s1, mainStyle); int beforeMessage = document.getLength(); s1 = ld.getMessage(); if (s1.length() > maximumMessageSize) { int removedCharsSize = s1.length() - maximumMessageSize; s1 = StringUtils.left(s1, maximumMessageSize) + String.format("%n...%n...(+%,d chars)", removedCharsSize); } for (MessageFormatter messageFormatter : formatters) { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread() .setContextClassLoader(messageFormatter.getClass().getClassLoader()); if (messageFormatter.formattingNeeded(s1)) { s1 = messageFormatter.format(s1); } } catch (Throwable e) { LOGGER.severe(String.format("Error occured when using message formatter %s: %s", messageFormatter.getName(), e.getMessage())); LOGGER.fine(String.format( "Error occured when using message formatter %s with message\"%s\"", messageFormatter.getName(), s1)); } finally { Thread.currentThread().setContextClassLoader(contextClassLoader); } } document.insertString(document.getLength(), s1, mainStyle); searchResultMessageColorizer = null; for (MessageColorizer messageColorizer : colorizers) { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread() .setContextClassLoader(messageColorizer.getClass().getClassLoader()); if (messageColorizer.colorizingNeeded(s1)) { messageColorizer.colorize(document, beforeMessage, document.getLength() - beforeMessage); } } catch (Throwable e) { LOGGER.severe(String.format("Error occured when using message colorizer %s: %s", messageColorizer.getName(), e.getMessage())); LOGGER.fine(String.format( "Error occured when using message colorizer %s with message\"%s\"", messageColorizer.getName(), s1)); } finally { Thread.currentThread().setContextClassLoader(contextClassLoader); } if (messageColorizer.getPluginableId().equals(SearchResultColorizer.class.getName())) { searchResultMessageColorizer = messageColorizer; } } if (searchResultMessageColorizer != null && searchResultMessageColorizer.colorizingNeeded(s1)) { searchResultMessageColorizer.colorize(document, beforeMessage, document.getLength() - beforeMessage); } document.insertString(document.getLength(), "\n", mainStyle); if (ld.getProperties() != null && ld.getProperties().size() > 0) { document.insertString(document.getLength(), "\nProperties:\n", noteStyle); String prop = Joiner.on("\n").withKeyValueSeparator("=").join(ld.getProperties()); document.insertString(document.getLength(), prop, noteStyle); document.insertString(document.getLength(), "\n", noteStyle); } Note note = dataTableModel.getNote(rowConverted); if (note != null && note.getNote() != null && note.getNote().length() > 0) { s1 = "\nNote: " + note.getNote(); document.insertString(document.getLength(), s1, noteStyle); } } catch (BadLocationException e) { LOGGER.warning("Cant set message details: " + e.getMessage()); } } } else { StyledDocument document = logDetailTextArea.getStyledDocument(); synchronized (document) { try { document.remove(0, document.getLength()); document.insertString(0, "No event selected", mainStyle); } catch (BadLocationException e) { LOGGER.warning("Cant set message details: " + e.getMessage()); } } } logDetailTextArea.setCaretPosition(0); } public LogDataTableModel getDataTableModel() { return dataTableModel; } public void setDataTableModel(LogDataTableModel dataTableModel) { this.dataTableModel = dataTableModel; } private final class PluginableElementEventListenerImplementation<T extends PluginableElement> implements PluginableElementEventListener<T> { @Override public void elementRemoved(T element) { updateInfo(); } @Override public void elementChanged(T element) { updateInfo(); } @Override public void elementAdded(T element) { updateInfo(); } } }