22 package com.realtime.crossfire.jxclient.gui.log;
25 import java.awt.Color;
26 import java.awt.font.FontRenderContext;
27 import java.awt.geom.RectangularShape;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.concurrent.CopyOnWriteArrayList;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
80 private final List<Line>
lines =
new CopyOnWriteArrayList<>();
92 private final Object
sync =
new Object();
117 public Buffer(@NotNull
final Fonts fonts, @NotNull
final FontRenderContext context,
final int renderWidth) {
128 if (this.renderWidth == renderWidth) {
134 synchronized (
sync) {
136 for (
final Line line : lines) {
138 line.setHeight(height);
139 totalHeight += height;
148 final List<Line> removedLines;
149 synchronized (
sync) {
150 removedLines =
new ArrayList<>(
lines);
155 listener.linesRemoved(removedLines);
168 line.setHeight(height);
169 synchronized (
sync) {
170 totalHeight += height;
175 listener.lineAdded();
185 line.setHeight(height);
186 synchronized (
sync) {
187 totalHeight += height;
188 final int lastIndex = lines.size()-1;
189 totalHeight -= lines.get(lastIndex).getHeight();
190 lines.set(lastIndex, line);
194 listener.lineReplaced();
202 final List<Line> removedLines;
203 synchronized (
sync) {
208 removedLines =
new ArrayList<>(lines.size()-
MAX_LINES);
210 final Line line = lines.remove(0);
211 removedLines.add(line);
216 listener.linesRemoved(removedLines);
228 synchronized (
sync) {
229 return lines.get(line);
238 synchronized (
sync) {
239 return Math.max(totalHeight, 1);
250 assert Thread.holdsLock(sync);
251 return Collections.unmodifiableList(lines).iterator();
261 assert Thread.holdsLock(sync);
262 return Collections.unmodifiableList(lines).listIterator(line);
270 synchronized (
sync) {
287 for (
final Segment segment : line) {
288 final RectangularShape rectangle = segment.getSize(fonts, context);
289 final int width = (int)Math.round(rectangle.getWidth());
290 if (x != 0 && x+width > renderWidth) {
291 line.updateAttributes(beginIndex, i, height-minY, fonts, context);
301 segment.setY(height);
302 segment.setWidth(width);
305 minY = (int)Math.min(minY, Math.round(rectangle.getY()));
306 maxY = (int)Math.max(maxY, Math.round(rectangle.getY()+rectangle.getHeight()));
311 line.updateAttributes(beginIndex, i, height-minY, fonts, context);
314 return Math.max(MIN_LINE_HEIGHT, height);
322 listeners.
add(listener);
330 listeners.
remove(listener);
349 public boolean mergeLines(@NotNull
final String text, @Nullable
final Color color) {
350 if (lastCount > 0 && text.equals(lastText) && (lastColor == null ? color == null : lastColor.equals(color))) {
static final int MAX_LINES
The maximum number of lines the buffer can hold.
Manages the contents of one text line.
Line getLine(final int line)
Returns one Line by line index.
final FontRenderContext context
The FontRenderContext to use.
int getTotalHeight()
Returns the total height of all lines.
void clear()
Clears all lines from the buffer.
A list of event listeners.
int calculateHeight(@NotNull final Line line)
Determines the height of a Line in pixels.
Color lastColor
The color of the previously added line of text.
void replaceLine(@NotNull final Line line)
Replaces the last Line of this buffer.
int getHeight()
Returns the height of this line.
Iterator< Line > iterator()
Returns an Iterator for the lines in this buffer.
void addLine(@NotNull final Line line)
Appends a Line to the end of the buffer.
final Object sync
Object to synchronized access to lines and totalHeight.
void prune()
Prunes excess lines.
Object getSyncObject()
Returns the object to synchronize on when calling iterator() or listIterator(int).
void addBufferListener(@NotNull final BufferListener listener)
Adds a listener to notify of changes.
static final int MIN_LINE_HEIGHT
The minimal height of a line in pixels.
int size()
Returns the number of lines.
One segment of a Line which should be displayed without changing text attributes. ...
void add(@NotNull final T listener)
Adds a listener.
boolean mergeLines(@NotNull final String text, @Nullable final Color color)
Checks whether a new text line should be merged with a preceding line.
final EventListenerList2< BufferListener > listeners
The listeners to notify about changes.
Buffer(@NotNull final Fonts fonts, @NotNull final FontRenderContext context, final int renderWidth)
Creates a new instance.
int lastCount
The number of repetitions of the previously added line of text.
String lastText
The contents of the previously added line of text.
Manages the contents of the contents of a log window.
Iterator< Line > listIterator(final int line)
Returns an Iterator for the lines in this buffer.
final Fonts fonts
The Fonts instance for looking up fonts.
Interface for listeners for changes of Buffer contents.
void setRenderWidth(final int renderWidth)
Updates the width to render.
final List< Line > lines
The lines in display order.
void remove(@NotNull final T listener)
Removes a listener.
int getLastCount()
Returns the number of merged lines.
void removeBufferListener(@NotNull final BufferListener listener)
Removes a listener to be notified of changes.
int totalHeight
The total height of all lines.
int renderWidth
The width to render.