■ ■ ■ ■ ■ ■
src/main/java/com/nccgroup/loggerplusplus/logging/JTextAreaAppender.java
1 | | - | package com.nccgroup.loggerplusplus.logging; |
2 | | - | |
3 | | - | import org.apache.logging.log4j.core.*; |
4 | | - | import org.apache.logging.log4j.core.appender.AbstractAppender; |
5 | | - | import org.apache.logging.log4j.core.config.plugins.Plugin; |
6 | | - | import org.apache.logging.log4j.core.config.plugins.PluginAttribute; |
7 | | - | import org.apache.logging.log4j.core.config.plugins.PluginElement; |
8 | | - | import org.apache.logging.log4j.core.config.plugins.PluginFactory; |
9 | | - | |
10 | | - | import javax.swing.*; |
11 | | - | import java.util.ArrayList; |
12 | | - | |
13 | | - | import static javax.swing.SwingUtilities.invokeLater; |
14 | | - | import static org.apache.logging.log4j.core.config.Property.EMPTY_ARRAY; |
15 | | - | import static org.apache.logging.log4j.core.layout.PatternLayout.createDefaultLayout; |
16 | | - | |
17 | | - | /** |
18 | | - | * JTextAreaAppender - https://stackoverflow.com/a/29736246 |
19 | | - | * Credit to https://stackoverflow.com/users/4544015/vshiro |
20 | | - | */ |
21 | | - | |
22 | | - | @Plugin(name = "JTextAreaAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) |
23 | | - | public class JTextAreaAppender extends AbstractAppender { |
24 | | - | private static volatile ArrayList<JTextArea> textAreas = new ArrayList<>(); |
25 | | - | |
26 | | - | private int maxLines; |
27 | | - | |
28 | | - | private JTextAreaAppender(String name, Layout<?> layout, Filter filter, int maxLines, boolean ignoreExceptions) { |
29 | | - | super(name, filter, layout, ignoreExceptions, EMPTY_ARRAY); |
30 | | - | this.maxLines = maxLines; |
31 | | - | } |
32 | | - | |
33 | | - | @SuppressWarnings("unused") |
34 | | - | @PluginFactory |
35 | | - | public static JTextAreaAppender createAppender(@PluginAttribute("name") String name, |
36 | | - | @PluginAttribute("maxLines") int maxLines, |
37 | | - | @PluginAttribute("ignoreExceptions") boolean ignoreExceptions, |
38 | | - | @PluginElement("Layout") Layout<?> layout, |
39 | | - | @PluginElement("Filters") Filter filter) { |
40 | | - | if (name == null) { |
41 | | - | LOGGER.error("No name provided for JTextAreaAppender"); |
42 | | - | return null; |
43 | | - | } |
44 | | - | |
45 | | - | if (layout == null) { |
46 | | - | layout = createDefaultLayout(); |
47 | | - | } |
48 | | - | return new JTextAreaAppender(name, layout, filter, maxLines, ignoreExceptions); |
49 | | - | } |
50 | | - | |
51 | | - | // Add the target JTextArea to be populated and updated by the logging information. |
52 | | - | public static void addLog4j2TextAreaAppender(final JTextArea textArea) { |
53 | | - | JTextAreaAppender.textAreas.add(textArea); |
54 | | - | } |
55 | | - | |
56 | | - | @Override |
57 | | - | public void append(LogEvent event) { |
58 | | - | String message = new String(this.getLayout().toByteArray(event)); |
59 | | - | |
60 | | - | // Append formatted message to text area using the Thread. |
61 | | - | try { |
62 | | - | invokeLater(() -> |
63 | | - | { |
64 | | - | for (JTextArea textArea : textAreas) { |
65 | | - | try { |
66 | | - | if (textArea != null) { |
67 | | - | if (textArea.getText().length() == 0) { |
68 | | - | textArea.setText(message); |
69 | | - | } else { |
70 | | - | textArea.append("\n" + message); |
71 | | - | if (maxLines > 0 & textArea.getLineCount() > maxLines + 1) { |
72 | | - | int endIdx = textArea.getDocument().getText(0, textArea.getDocument().getLength()).indexOf("\n"); |
73 | | - | textArea.getDocument().remove(0, endIdx + 1); |
74 | | - | } |
75 | | - | } |
76 | | - | String content = textArea.getText(); |
77 | | - | textArea.setText(content.substring(0, content.length() - 1)); |
78 | | - | } |
79 | | - | } catch (Throwable throwable) { |
80 | | - | throwable.printStackTrace(); |
81 | | - | } |
82 | | - | } |
83 | | - | }); |
84 | | - | } catch (IllegalStateException exception) { |
85 | | - | exception.printStackTrace(); |
86 | | - | } |
87 | | - | } |
88 | | - | } |
89 | | - | |