PageRenderTime 35ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/launcher/src/main/java/com/skcraft/launcher/swing/MessageLog.java

https://gitlab.com/Slind/Launcher
Java | 313 lines | 197 code | 47 blank | 69 comment | 15 complexity | 7b3d0d57352d3334a832e1e6cff947de MD5 | raw file
  1. /*
  2. * SK's Minecraft Launcher
  3. * Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
  4. * Please see LICENSE.txt for license information.
  5. */
  6. package com.skcraft.launcher.swing;
  7. import com.skcraft.launcher.LauncherUtils;
  8. import com.skcraft.launcher.util.LimitLinesDocumentListener;
  9. import com.skcraft.launcher.util.SimpleLogFormatter;
  10. import javax.swing.*;
  11. import javax.swing.text.*;
  12. import java.awt.*;
  13. import java.io.ByteArrayOutputStream;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import java.io.PrintWriter;
  17. import java.util.logging.Handler;
  18. import java.util.logging.Level;
  19. import java.util.logging.LogRecord;
  20. import java.util.logging.Logger;
  21. import static org.apache.commons.io.IOUtils.closeQuietly;
  22. /**
  23. * A simple message log.
  24. */
  25. public class MessageLog extends JPanel {
  26. private static final Logger rootLogger = Logger.getLogger("");
  27. private final int numLines;
  28. private final boolean colorEnabled;
  29. protected JTextComponent textComponent;
  30. protected Document document;
  31. private Handler loggerHandler;
  32. protected final SimpleAttributeSet defaultAttributes = new SimpleAttributeSet();
  33. protected final SimpleAttributeSet highlightedAttributes;
  34. protected final SimpleAttributeSet errorAttributes;
  35. protected final SimpleAttributeSet infoAttributes;
  36. protected final SimpleAttributeSet debugAttributes;
  37. public MessageLog(int numLines, boolean colorEnabled) {
  38. this.numLines = numLines;
  39. this.colorEnabled = colorEnabled;
  40. this.highlightedAttributes = new SimpleAttributeSet();
  41. StyleConstants.setForeground(highlightedAttributes, new Color(0xFF7F00));
  42. this.errorAttributes = new SimpleAttributeSet();
  43. StyleConstants.setForeground(errorAttributes, new Color(0xFF0000));
  44. this.infoAttributes = new SimpleAttributeSet();
  45. this.debugAttributes = new SimpleAttributeSet();
  46. setLayout(new BorderLayout());
  47. initComponents();
  48. }
  49. private void initComponents() {
  50. if (colorEnabled) {
  51. JTextPane text = new JTextPane() {
  52. @Override
  53. public boolean getScrollableTracksViewportWidth() {
  54. return true;
  55. }
  56. };
  57. this.textComponent = text;
  58. } else {
  59. JTextArea text = new JTextArea();
  60. this.textComponent = text;
  61. text.setLineWrap(true);
  62. text.setWrapStyleWord(true);
  63. }
  64. textComponent.setFont(new JLabel().getFont());
  65. textComponent.setEditable(false);
  66. textComponent.setComponentPopupMenu(TextFieldPopupMenu.INSTANCE);
  67. DefaultCaret caret = (DefaultCaret) textComponent.getCaret();
  68. caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
  69. document = textComponent.getDocument();
  70. document.addDocumentListener(new LimitLinesDocumentListener(numLines, true));
  71. JScrollPane scrollText = new JScrollPane(textComponent);
  72. scrollText.setBorder(null);
  73. scrollText.setVerticalScrollBarPolicy(
  74. ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
  75. scrollText.setHorizontalScrollBarPolicy(
  76. ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
  77. add(scrollText, BorderLayout.CENTER);
  78. }
  79. public String getPastableText() {
  80. String text = textComponent.getText().replaceAll("[\r\n]+", "\n");
  81. text = text.replaceAll("Session ID is [A-Fa-f0-9]+", "Session ID is [redacted]");
  82. return text;
  83. }
  84. public void clear() {
  85. textComponent.setText("");
  86. }
  87. /**
  88. * Log a message given the {@link javax.swing.text.AttributeSet}.
  89. *
  90. * @param line line
  91. * @param attributes attribute set, or null for none
  92. */
  93. public void log(String line, AttributeSet attributes) {
  94. if (colorEnabled) {
  95. if (line.startsWith("(!!)")) {
  96. attributes = highlightedAttributes;
  97. }
  98. }
  99. try {
  100. int offset = document.getLength();
  101. document.insertString(offset, line,
  102. (attributes != null && colorEnabled) ? attributes : defaultAttributes);
  103. textComponent.setCaretPosition(document.getLength());
  104. } catch (BadLocationException ble) {
  105. }
  106. }
  107. /**
  108. * Get an output stream that can be written to.
  109. *
  110. * @return output stream
  111. */
  112. public ConsoleOutputStream getOutputStream() {
  113. return getOutputStream((AttributeSet) null);
  114. }
  115. /**
  116. * Get an output stream with the given attribute set.
  117. *
  118. * @param attributes attributes
  119. * @return output stream
  120. */
  121. public ConsoleOutputStream getOutputStream(AttributeSet attributes) {
  122. return new ConsoleOutputStream(attributes);
  123. }
  124. /**
  125. * Get an output stream using the give color.
  126. *
  127. * @param color color to use
  128. * @return output stream
  129. */
  130. public ConsoleOutputStream getOutputStream(Color color) {
  131. SimpleAttributeSet attributes = new SimpleAttributeSet();
  132. StyleConstants.setForeground(attributes, color);
  133. return getOutputStream(attributes);
  134. }
  135. /**
  136. * Consume an input stream and print it to the dialog. The consumer
  137. * will be in a separate daemon thread.
  138. *
  139. * @param from stream to read
  140. */
  141. public void consume(InputStream from) {
  142. consume(from, getOutputStream());
  143. }
  144. /**
  145. * Consume an input stream and print it to the dialog. The consumer
  146. * will be in a separate daemon thread.
  147. *
  148. * @param from stream to read
  149. * @param color color to use
  150. */
  151. public void consume(InputStream from, Color color) {
  152. consume(from, getOutputStream(color));
  153. }
  154. /**
  155. * Consume an input stream and print it to the dialog. The consumer
  156. * will be in a separate daemon thread.
  157. *
  158. * @param from stream to read
  159. * @param attributes attributes
  160. */
  161. public void consume(InputStream from, AttributeSet attributes) {
  162. consume(from, getOutputStream(attributes));
  163. }
  164. /**
  165. * Internal method to consume a stream.
  166. *
  167. * @param from stream to consume
  168. * @param outputStream console stream to write to
  169. */
  170. private void consume(InputStream from, ConsoleOutputStream outputStream) {
  171. final InputStream in = from;
  172. final PrintWriter out = new PrintWriter(outputStream, true);
  173. Thread thread = new Thread(new Runnable() {
  174. @Override
  175. public void run() {
  176. byte[] buffer = new byte[1024];
  177. try {
  178. int len;
  179. while ((len = in.read(buffer)) != -1) {
  180. String s = new String(buffer, 0, len);
  181. System.out.print(s);
  182. out.append(s);
  183. out.flush();
  184. }
  185. } catch (IOException e) {
  186. } finally {
  187. closeQuietly(in);
  188. closeQuietly(out);
  189. }
  190. }
  191. });
  192. thread.setDaemon(true);
  193. thread.start();
  194. }
  195. /**
  196. * Register a global logger listener.
  197. */
  198. public void registerLoggerHandler() {
  199. loggerHandler = new ConsoleLoggerHandler();
  200. rootLogger.addHandler(loggerHandler);
  201. }
  202. /**
  203. * Detach the handler on the global logger.
  204. */
  205. public void detachGlobalHandler() {
  206. if (loggerHandler != null) {
  207. rootLogger.removeHandler(loggerHandler);
  208. loggerHandler = null;
  209. }
  210. }
  211. public SimpleAttributeSet asDefault() {
  212. return defaultAttributes;
  213. }
  214. public SimpleAttributeSet asHighlighted() {
  215. return highlightedAttributes;
  216. }
  217. public SimpleAttributeSet asError() {
  218. return errorAttributes;
  219. }
  220. public SimpleAttributeSet asInfo() {
  221. return infoAttributes;
  222. }
  223. public SimpleAttributeSet asDebug() {
  224. return debugAttributes;
  225. }
  226. /**
  227. * Used to send logger messages to the console.
  228. */
  229. private class ConsoleLoggerHandler extends Handler {
  230. private final SimpleLogFormatter formatter = new SimpleLogFormatter();
  231. @Override
  232. public void publish(LogRecord record) {
  233. Level level = record.getLevel();
  234. Throwable t = record.getThrown();
  235. AttributeSet attributes = defaultAttributes;
  236. if (level.intValue() >= Level.WARNING.intValue()) {
  237. attributes = errorAttributes;
  238. } else if (level.intValue() < Level.INFO.intValue()) {
  239. attributes = debugAttributes;
  240. }
  241. log(formatter.format(record), attributes);
  242. }
  243. @Override
  244. public void flush() {
  245. }
  246. @Override
  247. public void close() throws SecurityException {
  248. }
  249. }
  250. /**
  251. * Used to send console messages to the console.
  252. */
  253. private class ConsoleOutputStream extends ByteArrayOutputStream {
  254. private AttributeSet attributes;
  255. private ConsoleOutputStream(AttributeSet attributes) {
  256. this.attributes = attributes;
  257. }
  258. @Override
  259. public void flush() {
  260. String data = toString();
  261. if (data.length() == 0) return;
  262. log(data, attributes);
  263. reset();
  264. }
  265. }
  266. }