PageRenderTime 41ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/com/sk89q/skmcl/swing/MessageLog.java

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