1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.gui;
21
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24
25 import javax.swing.JScrollPane;
26 import javax.swing.JTextArea;
27 import javax.swing.SwingUtilities;
28 import javax.swing.border.EmptyBorder;
29 import javax.swing.text.BadLocationException;
30
31 import org.xnap.gui.util.GUIHelper;
32 import org.xnap.util.Preferences;
33
34 /***
35 * This class provides a simple text console that can be used for logging.
36 */
37 public class ConsolePane extends JScrollPane
38 implements PropertyChangeListener {
39
40
41
42
43
44 private static Preferences prefs = Preferences.getInstance();
45
46 private JTextArea jta;
47 private boolean crop;
48 private boolean appendPending = false;
49 private StringBuffer pendingText = new StringBuffer();
50
51
52
53 public ConsolePane(boolean crop)
54 {
55 this.crop = crop;
56
57 jta = new JTextArea();
58 jta.setLineWrap(true);
59 jta.setWrapStyleWord(true);
60 jta.setCaretColor(java.awt.Color.red);
61 jta.setSelectedTextColor(java.awt.Color.red);
62 jta.setEditable(false);
63 jta.setBorder(new EmptyBorder(5, 5, 5, 5));
64
65 setVerticalScrollBarPolicy
66 (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
67 setHorizontalScrollBarPolicy
68 (JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
69
70 setViewportView(jta);
71
72 updateProperties();
73
74 prefs.addPropertyChangeListener("consoleFont", this);
75 prefs.addPropertyChangeListener("consoleBackgroundColor", this);
76 prefs.addPropertyChangeListener("consoleForegroundColor", this);
77 }
78
79 public ConsolePane()
80 {
81 this(true);
82 }
83
84
85
86 /***
87 * Appends <code>text</code> to the console. This method is thread
88 * safe and can be called from any thread.
89 */
90 public void appendLater(final String text)
91 {
92 synchronized (pendingText) {
93 pendingText.append(text);
94 if (appendPending) {
95 return;
96 }
97 appendPending = true;
98 }
99
100 Runnable r = new Runnable()
101 {
102 public void run()
103 {
104 String toAppend;
105 synchronized (pendingText) {
106 toAppend = pendingText.toString();
107 pendingText.setLength(0);
108 appendPending = false;
109 }
110 append(toAppend);
111 }
112 };
113 SwingUtilities.invokeLater(r);
114 }
115
116 /***
117 * Appends <code>text</code> to the console.
118 */
119 public void append(String text)
120 {
121 boolean autoScroll = GUIHelper.shouldScroll(getVerticalScrollBar());
122
123 jta.append(text);
124
125 if (crop) {
126
127 int i = jta.getLineCount() - prefs.getMaxConsoleLines();
128 if (i > 0) {
129 try {
130 int endoffset = jta.getLineEndOffset(i);
131 jta.replaceRange(null, 0, endoffset);
132
133
134
135
136 }
137 catch (BadLocationException e) {
138 }
139 }
140 }
141
142 if (autoScroll) {
143 GUIHelper.scrollToEnd(jta);
144 }
145 }
146
147 public void propertyChange(PropertyChangeEvent e)
148 {
149 updateProperties();
150 }
151
152 /***
153 * Sets <code>text</code> to the console. This method is thread
154 * safe and can be called from any thread.
155 */
156 public void setLater(final String text)
157 {
158 synchronized (pendingText) {
159 pendingText.setLength(0);
160 }
161
162 Runnable r = new Runnable()
163 {
164 public void run()
165 {
166 setText(text);
167 }
168 };
169 SwingUtilities.invokeLater(r);
170 }
171
172 /***
173 * Sets the text of the console to <code>newValue</code>.
174 */
175 public void setText(String newValue)
176 {
177 jta.setText(newValue);
178 }
179
180 /***
181 * Updates the font and colors.
182 */
183 public void updateProperties()
184 {
185 jta.setFont(prefs.getFont("consoleFont"));
186 jta.setBackground(prefs.getColor("consoleBackgroundColor"));
187 jta.setForeground(prefs.getColor("consoleForegroundColor"));
188 }
189
190 }