File Source: IRCDocument.java
/*
P/P * Method: com.dmdirc.addons.ui_swing.textpane.IRCDocument__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22 package com.dmdirc.addons.ui_swing.textpane;
23
24 import com.dmdirc.config.ConfigManager;
25 import com.dmdirc.interfaces.ConfigChangeListener;
26 import com.dmdirc.util.RollingList;
27
28 import java.io.Serializable;
29 import java.text.AttributedCharacterIterator;
30 import java.text.AttributedString;
31 import java.util.ArrayList;
32 import java.util.List;
33
34 import javax.swing.event.EventListenerList;
35
36 /**
37 * Data contained in a TextPane.
38 */
39 public final class IRCDocument implements Serializable, ConfigChangeListener {
40
41 /**
42 * A version number for this class. It should be changed whenever the class
43 * structure is changed (or anything else that would prevent serialized
44 * objects being unserialized with the new class).
45 */
46 private static final long serialVersionUID = 4;
47 /** List of lines of text. */
48 private final List<Line> lines;
49 /** Listener list. */
50 private final EventListenerList listeners;
51 /** Cached lines. */
52 private RollingList<Line> cachedLines;
53 /** Cached attributed strings. */
54 private RollingList<AttributedString> cachedStrings;
55 /** Configuration manager. */
56 private ConfigManager config;
57
58 /**
59 * Creates a new instance of IRCDocument.
60 *
61 * @param config Document's config manager
62 */
/*
P/P * Method: void com.dmdirc.addons.ui_swing.textpane.IRCDocument(ConfigManager)
*
* Postconditions:
* this.cachedLines == &new RollingList(IRCDocument#3)
* this.cachedStrings == &new RollingList(IRCDocument#4)
* this.config == config
* init'ed(this.config)
* this.lines == &new ArrayList(IRCDocument#1)
* this.listeners == &new EventListenerList(IRCDocument#2)
* new ArrayList(IRCDocument#1) num objects == 1
* new EventListenerList(IRCDocument#2) num objects == 1
* new RollingList(IRCDocument#3) num objects == 1
* new RollingList(IRCDocument#4) num objects == 1
*/
63 public IRCDocument(final ConfigManager config) {
64 this.config = config;
65 lines = new ArrayList<Line>();
66 listeners = new EventListenerList();
67
68 cachedLines = new RollingList<Line>(50);
69 cachedStrings = new RollingList<AttributedString>(50);
70 }
71
72 /**
73 * Returns the number of lines in this document.
74 *
75 * @return Number of lines
76 */
77 public int getNumLines() {
/*
P/P * Method: int getNumLines()
*
* Preconditions:
* this.lines != null
*
* Postconditions:
* init'ed(return_value)
*/
78 return lines.size();
79 }
80
81 /**
82 * Returns the Line at the specified number.
83 *
84 * @param lineNumber Line number to retrieve
85 *
86 * @return Line at the specified number or null
87 */
88 Line getLine(final int lineNumber) {
/*
P/P * Method: Line getLine(int)
*
* Preconditions:
* this.lines != null
*
* Postconditions:
* init'ed(return_value)
*/
89 return lines.get(lineNumber);
90 }
91
92 /**
93 * Adds the stylised string to the canvas.
94 *
95 * @param text stylised string to add to the text
96 */
97 public void addText(final String[] text) {
/*
P/P * Method: void addText(String[])
*
* Preconditions:
* init'ed(this.config)
* this.lines != null
* this.listeners != null
*/
98 synchronized (lines) {
99 lines.add(new Line(text, config));
100 fireLineAdded(lines.indexOf(text));
101 }
102 }
103
104 /**
105 * Adds the stylised string to the canvas.
106 *
107 * @param text stylised string to add to the text
108 */
109 public void addText(final List<String[]> text) {
/*
P/P * Method: void addText(List)
*
* Preconditions:
* text != null
* this.lines != null
* this.listeners != null
* (soft) init'ed(this.config)
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@112: {0}, {1}
*/
110 synchronized (lines) {
111 final int start = lines.size();
112 for (String[] string : text) {
113 lines.add(new Line(string, config));
114 }
115 fireLinesAdded(start, text.size());
116 }
117 }
118
119 /**
120 * Trims the document to the specified number of lines.
121 *
122 * @param numLines Number of lines to trim the document to
123 */
124 public void trim(final int numLines) {
/*
P/P * Method: void trim(int)
*
* Preconditions:
* this.lines != null
* this.listeners != null
*/
125 synchronized (lines) {
126 while (lines.size() > numLines) {
127 lines.remove(0);
128 }
129 fireTrimmed();
130 }
131 }
132
133 /** Clears all lines from the document. */
134 protected void clear() {
/*
P/P * Method: void clear()
*
* Preconditions:
* this.lines != null
* this.listeners != null
*/
135 synchronized (lines) {
136 lines.clear();
137 fireCleared();
138 }
139 }
140
141 /**
142 * Adds a IRCDocumentListener to the listener list.
143 *
144 * @param listener Listener to add
145 */
146 public void addIRCDocumentListener(final IRCDocumentListener listener) {
/*
P/P * Method: void addIRCDocumentListener(IRCDocumentListener)
*
* Preconditions:
* (soft) this.listeners != null
*
* Test Vectors:
* listener: Inverse{null}, Addr_Set{null}
*/
147 synchronized (listeners) {
148 if (listener == null) {
149 return;
150 }
151 listeners.add(IRCDocumentListener.class, listener);
152 }
153 }
154
155 /**
156 * Removes a IRCDocumentListener from the listener list.
157 *
158 * @param listener Listener to remove
159 */
160 public void removeIRCDocumentListener(final IRCDocumentListener listener) {
/*
P/P * Method: void removeIRCDocumentListener(IRCDocumentListener)
*
* Preconditions:
* this.listeners != null
*/
161 listeners.remove(IRCDocumentListener.class, listener);
162 }
163
164 /**
165 * Fires the line added method on all listeners.
166 *
167 * @param index Index of the added line
168 */
169 protected void fireLineAdded(final int index) {
/*
P/P * Method: void fireLineAdded(int)
*
* Preconditions:
* this.listeners != null
* (soft) this.lines != null
*
* Presumptions:
* javax.swing.event.EventListenerList:getListenerList(...)@170 != null
* listenerList.length@170 in {0, 2..232-1}
* listenerList[(i + 1)].canvas.textPane@170 != null
* listenerList[(i + 1)].canvas@170 != null
* listenerList[(i + 1)].document.lines@170 != null
* ...
*/
170 final Object[] listenerList = listeners.getListenerList();
171 for (int i = 0; i < listenerList.length; i += 2) {
172 if (listenerList[i] == IRCDocumentListener.class) {
173 ((IRCDocumentListener) listenerList[i + 1]).lineAdded(index,
174 lines.size());
175 }
176 }
177 }
178
179 /**
180 * Fires the lines added method on all listeners.
181 *
182 * @param index Index of the added line
183 * @param size Number of lines added
184 */
185 protected void fireLinesAdded(final int index, final int size) {
/*
P/P * Method: void fireLinesAdded(int, int)
*
* Preconditions:
* this.listeners != null
* (soft) this.lines != null
*
* Presumptions:
* javax.swing.event.EventListenerList:getListenerList(...)@186 != null
* listenerList.length@186 in {0, 2..232-1}
* listenerList[(i + 1)].canvas.textPane@186 != null
* listenerList[(i + 1)].canvas@186 != null
* listenerList[(i + 1)].document.lines@186 != null
* ...
*/
186 final Object[] listenerList = listeners.getListenerList();
187 for (int i = 0; i < listenerList.length; i += 2) {
188 if (listenerList[i] == IRCDocumentListener.class) {
189 ((IRCDocumentListener) listenerList[i + 1]).linesAdded(index,
190 size,
191 lines.size());
192 }
193 }
194 }
195
196 /**
197 * Fires the trimmed method on all listeners.
198 */
199 protected void fireTrimmed() {
/*
P/P * Method: void fireTrimmed()
*
* Preconditions:
* this.listeners != null
* (soft) this.lines != null
*
* Presumptions:
* javax.swing.event.EventListenerList:getListenerList(...)@200 != null
* listenerList.length@200 in {0, 2..232-1}
* listenerList[(i + 1)].canvas.textPane@200 != null
* listenerList[(i + 1)].canvas@200 != null
* listenerList[(i + 1)].document.lines@200 != null
* ...
*/
200 final Object[] listenerList = listeners.getListenerList();
201 for (int i = 0; i < listenerList.length; i += 2) {
202 if (listenerList[i] == IRCDocumentListener.class) {
203 ((IRCDocumentListener) listenerList[i + 1]).trimmed(lines.size());
204 }
205 }
206 }
207
208 /**
209 * fires the cleared method on all listeners.
210 */
211 protected void fireCleared() {
/*
P/P * Method: void fireCleared()
*
* Preconditions:
* this.listeners != null
*
* Presumptions:
* javax.swing.event.EventListenerList:getListenerList(...)@212 != null
* listenerList.length@212 in {0, 2..232-1}
* listenerList[(i + 1)].canvas@212 != null
* listenerList[i + 1]@212 != null
*/
212 final Object[] listenerList = listeners.getListenerList();
213 for (int i = 0; i < listenerList.length; i += 2) {
214 if (listenerList[i] == IRCDocumentListener.class) {
215 ((IRCDocumentListener) listenerList[i + 1]).cleared();
216 }
217 }
218 }
219
220 /**
221 * fires the need repaint method on all listeners.
222 */
223 protected void fireRepaintNeeded() {
/*
P/P * Method: void fireRepaintNeeded()
*
* Preconditions:
* this.listeners != null
*
* Presumptions:
* javax.swing.event.EventListenerList:getListenerList(...)@224 != null
* listenerList.length@224 in {0, 2..232-1}
* listenerList[(i + 1)].canvas@224 != null
* listenerList[i + 1]@224 != null
*/
224 final Object[] listenerList = listeners.getListenerList();
225 for (int i = 0; i < listenerList.length; i += 2) {
226 if (listenerList[i] == IRCDocumentListener.class) {
227 ((IRCDocumentListener) listenerList[i + 1]).repaintNeeded();
228 }
229 }
230 }
231
232 /**
233 * Returns an attributed character iterator for a particular line,
234 * utilising the document cache where possible.
235 *
236 * @param line Line to be styled
237 *
238 * @return Styled line
239 */
240 AttributedCharacterIterator getStyledLine(final Line line) {
/*
P/P * Method: AttributedCharacterIterator getStyledLine(Line)
*
* Preconditions:
* this.cachedLines != null
* (soft) line != null
* (soft) line.config != null
* (soft) line.config.sources != null
* (soft) this.cachedStrings != null
*
* Presumptions:
* com.dmdirc.util.RollingList:getList(...)@243 != null
*
* Postconditions:
* possibly_updated(line.lineHeight)
* init'ed(return_value)
*
* Test Vectors:
* com.dmdirc.util.RollingList:contains(...)@242: {0}, {1}
*/
241 AttributedString styledLine = null;
242 if (cachedLines.contains(line)) {
243 final int index = cachedLines.getList().indexOf(line);
244 styledLine = cachedStrings.get(index);
245 }
246
247 if (styledLine == null) {
248 styledLine = line.getStyled();
249 cachedLines.add(line);
250 cachedStrings.add(styledLine);
251 }
252
253 return styledLine.getIterator();
254 }
255
256 /**
257 * Returns an attributed string for a particular line, utilising the
258 * document cache where possible.
259 *
260 * @param line Line number to be styled
261 *
262 * @return Styled line
263 */
264 public AttributedCharacterIterator getStyledLine(final int line) {
/*
P/P * Method: AttributedCharacterIterator getStyledLine(int)
*
* Preconditions:
* this.cachedLines != null
* this.lines != null
* (soft) this.cachedStrings != null
*
* Presumptions:
* getLine(...).config != null
* getLine(...).config.sources != null
* java.util.List:get(...)@89 != null
*
* Postconditions:
* init'ed(return_value)
*/
265 return getStyledLine(getLine(line));
266 }
267
268 /**
269 * Returns the line height of the specified line
270 *
271 * @param line Line
272 *
273 * @return Line height
274 */
275 int getLineHeight(final Line line) {
/*
P/P * Method: int getLineHeight(Line)
*
* Preconditions:
* line != null
* init'ed(line.lineHeight)
*
* Postconditions:
* return_value == line.lineHeight
* init'ed(return_value)
*/
276 return line.getHeight();
277 }
278
279 /**
280 * Returns the line height of the specified line
281 *
282 * @param line Line
283 *
284 * @return Line height
285 */
286 public int getLineHeight(final int line) {
/*
P/P * Method: int getLineHeight(int)
*
* Preconditions:
* this.lines != null
*
* Presumptions:
* java.util.List:get(...)@89 != null
*
* Postconditions:
* init'ed(return_value)
*/
287 return getLineHeight(getLine(line));
288 }
289
290 /** {@inheritDoc} */
291 @Override
292 public void configChanged(final String domain, final String key) {
/*
P/P * Method: void configChanged(String, String)
*
* Preconditions:
* this.cachedLines != null
* this.cachedStrings != null
* this.listeners != null
*/
293 cachedLines.clear();
294 cachedStrings.clear();
295 fireRepaintNeeded();
296 }
297 }
298
SofCheck Inspector Build Version : 2.17854
| IRCDocument.java |
2009-Jun-25 01:54:24 |
| IRCDocument.class |
2009-Sep-02 17:04:14 |