Crossfire JXClient, Trunk
GUILog.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff
19  * Copyright (C) 2006-2017,2019-2023 Andreas Kirschbaum
20  * Copyright (C) 2010-2012,2014-2018,2020-2023 Nicolas Weeger
21  */
22 
23 package com.realtime.crossfire.jxclient.gui.log;
24 
32 import java.awt.Color;
33 import java.awt.Graphics;
34 import java.awt.Graphics2D;
35 import java.awt.GraphicsEnvironment;
36 import java.awt.Image;
37 import java.awt.Toolkit;
38 import java.awt.datatransfer.Clipboard;
39 import java.awt.datatransfer.StringSelection;
40 import java.awt.datatransfer.Transferable;
41 import java.awt.event.ActionListener;
42 import java.awt.event.MouseEvent;
43 import java.awt.font.FontRenderContext;
44 import java.awt.image.BufferedImage;
45 import java.util.Iterator;
46 import java.util.List;
47 import javax.swing.Timer;
48 import org.jetbrains.annotations.NotNull;
49 import org.jetbrains.annotations.Nullable;
50 
56 public abstract class GUILog extends AbstractGUIElement implements GUIScrollable2 {
57 
61  private static final long serialVersionUID = 1;
62 
66  private static final int SCROLL_PIXEL = 48;
67 
72  private static final int TIMEOUT_AUTO_SCROLL = 25;
73 
77  @NotNull
79 
83  @NotNull
84  private final Buffer buffer;
85 
90  @Nullable
91  private final Image backgroundImage;
92 
96  @NotNull
98 
102  @NotNull
103  private final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
104 
109  @Nullable
110  private final Clipboard selection = Toolkit.getDefaultToolkit().getSystemSelection();
111 
115  @NotNull
116  private final ActionListener timeoutEvent = e -> autoScroll();
117 
121  @NotNull
122  private final Timer timer = new Timer(TIMEOUT_AUTO_SCROLL, timeoutEvent);
123 
128  private int startSelection;
129 
133  private int beginSelection;
134 
138  private int endSelection;
139 
144  private boolean scrollForwards;
145 
149  @NotNull
150  @SuppressWarnings("FieldCanBeLocal")
152 
153  @Override
154  public void stateChanged() {
155  setChanged();
156  for (ScrollableListener listener : listeners) {
157  listener.setRange(0, buffer.getTotalHeight(), renderStateManager.getScrollPos(), getHeight());
158  }
159  }
160 
161  @Override
162  public int getHeight() {
163  return Math.max(1, GUILog.this.getHeight());
164  }
165 
166  };
167 
171  @NotNull
173 
174  @Override
175  public void lineAdded() {
176  // does not affect the selection => ignore
177  }
178 
179  @Override
180  public void lineReplaced() {
181  // does not affect the selection => ignore
182  }
183 
184  @Override
185  public void linesRemoved(@NotNull final List<Line> lines) {
186  final int endPosition = lines.get(lines.size()-1).getEndPosition();
187  if (beginSelection > endPosition) {
188  beginSelection -= endPosition;
189  endSelection -= endPosition;
190  } else if (endSelection > endPosition) {
191  beginSelection = 0;
192  endSelection -= endPosition;
193  copy();
194  } else if (beginSelection > 0 || endSelection > 0) {
195  beginSelection = 0;
196  endSelection = 0;
197  copy();
198  }
199  }
200 
201  };
202 
213  protected GUILog(@NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final String name, @Nullable final Image backgroundImage, @NotNull final Fonts fonts, @NotNull final GuiFactory guiFactory) {
215  this.backgroundImage = backgroundImage;
216  final FontRenderContext context;
217  final GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
218  final Graphics2D g = graphicsEnvironment.createGraphics(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)); // XXX
219  try {
220  context = g.getFontRenderContext();
221  } finally {
222  g.dispose();
223  }
224  buffer = new DefaultBuffer(fonts, context, getWidth());
226  renderStateManager.setHeight(getHeight());
228  }
229 
230  @Override
231  public void dispose() {
232  super.dispose();
235  }
236 
237  @Override
238  public void paintComponent(@NotNull final Graphics g) {
239  super.paintComponent(g);
240 
241  g.setColor(new Color(0, 0, 0, 0.0f));
242  g.fillRect(0, 0, getWidth(), getHeight());
243  if (backgroundImage != null) {
244  g.drawImage(backgroundImage, 0, 0, null);
245  }
246 
247  final int beginSelection = this.beginSelection;
248  final int endSelection = this.endSelection;
249  int y = -renderStateManager.getTopOffset();
250  final int topIndex = renderStateManager.getTopIndex();
251  synchronized (buffer.getSyncObject()) {
252  for (final Line line : buffer.lines(topIndex)) {
253  if (y >= getHeight()) {
254  break;
255  }
256  final int height = line.getHeight();
257  if (height > 0) {
258  line.drawLine((Graphics2D)g, y, beginSelection, endSelection);
259  y += height;
260  }
261  }
262  }
263  }
264 
265  @Override
266  public boolean canScroll(final int distance) { // XXX: implement |distance|>1
267  if (distance < 0) {
269  }
270  //noinspection SimplifiableIfStatement
271  if (distance > 0) {
273  }
274  return false;
275  }
276 
277  @Override
278  public void scroll(final int distance) {
279  if (distance < 0) {
281  } else if (distance > 0) {
283  } else {
284  assert false;
285  }
286  }
287 
288  @Override
289  public void resetScroll() {
291  }
292 
293  @Override
294  public void scrollTo(final int pos) {
296  }
297 
298  @Override
299  public void addScrollableListener(@NotNull final ScrollableListener listener) {
300  listeners.add(listener);
301  }
302 
303  @Override
304  public void removeScrollableListener(@NotNull final ScrollableListener listener) {
305  listeners.remove(listener);
306  }
307 
312  @NotNull
313  public Buffer getBuffer() {
314  return buffer;
315  }
316 
317  @Override
318  public void setBounds(final int x, final int y, final int width, final int height) {
319  super.setBounds(x, y, width, height);
320  buffer.setRenderWidth(width);
322  }
323 
324  @Override
325  public void mousePressed(@NotNull final MouseEvent e) {
326  super.mousePressed(e);
328  if (timer.isRunning()) {
329  timer.stop();
330  }
332  }
333 
334  @Override
335  public void mouseReleased(@NotNull final MouseEvent e) {
336  super.mouseReleased(e);
338  if (timer.isRunning()) {
339  timer.stop();
340  }
341  copy();
342  }
343 
344  @Override
345  public void mouseDragged(@NotNull final MouseEvent e) {
346  super.mouseDragged(e);
347 
348  if (e.getY() < 0) {
350  if (!timer.isRunning()) {
351  scrollForwards = false;
352  timer.start();
353  }
354  } else if (e.getY() >= getHeight()) {
356  if (!timer.isRunning()) {
357  scrollForwards = true;
358  timer.start();
359  }
360  } else {
362  if (timer.isRunning()) {
363  timer.stop();
364  }
365  }
366  }
367 
368  @Override
369  public void mouseWheelMoved(final int wheelRotation) {
370  super.mouseWheelMoved(wheelRotation);
371  scroll(wheelRotation);
372  }
373 
377  private void autoScroll() {
378  if (scrollForwards) {
382  }
383  } else {
388  timer.stop();
389  }
390  }
391  }
392  }
393 
399  private int getStartPosition() {
401  }
402 
408  private int getEndPosition() {
410  }
411 
416  public void setShowSentCommands(final boolean showSentCommands) {
417  final int oldBufferHeight = buffer.getTotalHeight();
418  buffer.setShowSentCommands(showSentCommands);
419  renderStateManager.update(oldBufferHeight);
420  copy();
421  }
422 
427  public void setShowTimestamps(final boolean showTimestamps) {
428  final int oldBufferHeight = buffer.getTotalHeight();
429  buffer.setShowTimestamps(showTimestamps);
430  renderStateManager.update(oldBufferHeight);
431  copy();
432  }
433 
438  private void setSelection(final int selection) {
439  final int newBeginSelection = Math.min(startSelection, selection);
440  final int newEndSelection = Math.max(startSelection, selection);
441  if (beginSelection == newBeginSelection && endSelection == newEndSelection) {
442  return;
443  }
444 
445  beginSelection = newBeginSelection;
446  endSelection = newEndSelection;
447  repaint();
448  }
449 
453  private void copy() {
454  final Transferable selection = new StringSelection(buffer.getText(beginSelection, endSelection));
455  if (this.selection != null) {
456  this.selection.setContents(selection, null);
457  }
458  clipboard.setContents(selection, null);
459  }
460 
461 }
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.gui.log.GUILog.mouseDragged
void mouseDragged(@NotNull final MouseEvent e)
Definition: GUILog.java:345
com.realtime.crossfire.jxclient.skin.skin
Definition: DefaultJXCSkin.java:23
com.realtime.crossfire.jxclient.gui.log.GUILog.scrollForwards
boolean scrollForwards
Definition: GUILog.java:144
com.realtime.crossfire.jxclient.gui.log.GUILog.mouseWheelMoved
void mouseWheelMoved(final int wheelRotation)
Definition: GUILog.java:369
com.realtime.crossfire.jxclient.gui.log.GUILog.setBounds
void setBounds(final int x, final int y, final int width, final int height)
Definition: GUILog.java:318
com.realtime.crossfire.jxclient.gui.log.BufferListener
Definition: BufferListener.java:33
com.realtime.crossfire.jxclient.gui.log.GUILog.canScroll
boolean canScroll(final int distance)
Definition: GUILog.java:266
com.realtime.crossfire.jxclient.gui.log.GUILog.getEndPosition
int getEndPosition()
Definition: GUILog.java:408
com.realtime.crossfire.jxclient.skin
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.setHeight
void setHeight(final int height)
Definition: RenderStateManager.java:122
com.realtime.crossfire.jxclient.gui.log.GUILog
Definition: GUILog.java:56
com.realtime.crossfire.jxclient.gui.log.GUILog.getBuffer
Buffer getBuffer()
Definition: GUILog.java:313
com.realtime.crossfire.jxclient.gui.log.GUILog.beginSelection
int beginSelection
Definition: GUILog.java:133
com.realtime.crossfire.jxclient.gui.log.GUILog.bufferListener
final BufferListener bufferListener
Definition: GUILog.java:172
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.resetScroll
void resetScroll()
Definition: RenderStateManager.java:178
com.realtime.crossfire.jxclient.gui.log.GUILog.mouseReleased
void mouseReleased(@NotNull final MouseEvent e)
Definition: GUILog.java:335
com.realtime.crossfire.jxclient.gui.log.GUILog.mousePressed
void mousePressed(@NotNull final MouseEvent e)
Definition: GUILog.java:325
com.realtime.crossfire.jxclient.gui.log.Buffer.addBufferListener
void addBufferListener(@NotNull final BufferListener listener)
Definition: Buffer.java:310
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.setChanged
void setChanged()
Definition: AbstractGUIElement.java:223
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement
Definition: AbstractGUIElement.java:37
com.realtime.crossfire.jxclient.gui.log.Buffer.getText
String getText(final int beginSelection, final int endSelection)
Definition: Buffer.java:454
com.realtime.crossfire.jxclient.gui.log.Buffer.setShowSentCommands
void setShowSentCommands(final boolean showSentCommands)
Definition: Buffer.java:147
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.elementListener
final GUIElementListener elementListener
Definition: AbstractGUIElement.java:89
com.realtime.crossfire.jxclient.gui.log.DefaultBuffer
Definition: DefaultBuffer.java:13
com.realtime.crossfire.jxclient.gui.log.GUILog.buffer
final Buffer buffer
Definition: GUILog.java:84
com.realtime.crossfire.jxclient.gui.log.GUILog.timeoutEvent
final ActionListener timeoutEvent
Definition: GUILog.java:116
com.realtime.crossfire.jxclient.gui.log.Buffer.lines
final List< Line > lines
Definition: Buffer.java:63
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.canScrollDown
boolean canScrollDown()
Definition: RenderStateManager.java:224
com.realtime.crossfire.jxclient.gui.log.GUILog.getStartPosition
int getStartPosition()
Definition: GUILog.java:399
com.realtime.crossfire.jxclient.gui.log.GUILog.copy
void copy()
Definition: GUILog.java:453
com.realtime.crossfire.jxclient.gui.log.GUILog.resetScroll
void resetScroll()
Definition: GUILog.java:289
com.realtime.crossfire.jxclient.util.EventListenerList2
Definition: EventListenerList2.java:37
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.dispose
void dispose()
Definition: RenderStateManager.java:139
com.realtime.crossfire.jxclient.gui.log.Buffer.getSyncObject
Object getSyncObject()
Definition: Buffer.java:327
com.realtime.crossfire.jxclient.gui.log.RenderStateListener
Definition: RenderStateListener.java:30
com.realtime.crossfire.jxclient.gui.log.GUILog.renderStateListener
final RenderStateListener renderStateListener
Definition: GUILog.java:151
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.canScrollUp
boolean canScrollUp()
Definition: RenderStateManager.java:216
com.realtime.crossfire.jxclient.gui.log.GUILog.serialVersionUID
static final long serialVersionUID
Definition: GUILog.java:61
com.realtime.crossfire.jxclient.gui.log.GUILog.autoScroll
void autoScroll()
Definition: GUILog.java:377
com.realtime.crossfire.jxclient.gui.log.Line
Definition: Line.java:39
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getScrollPos
int getScrollPos()
Definition: RenderStateManager.java:171
com.realtime.crossfire.jxclient.gui.log.GUILog.TIMEOUT_AUTO_SCROLL
static final int TIMEOUT_AUTO_SCROLL
Definition: GUILog.java:72
com.realtime.crossfire.jxclient.gui.log.GUILog.selection
final Clipboard selection
Definition: GUILog.java:110
com.realtime.crossfire.jxclient.gui.log.GUILog.setShowTimestamps
void setShowTimestamps(final boolean showTimestamps)
Definition: GUILog.java:427
com.realtime.crossfire.jxclient.gui.log.GUILog.SCROLL_PIXEL
static final int SCROLL_PIXEL
Definition: GUILog.java:66
com.realtime.crossfire.jxclient.gui.log.GUILog.addScrollableListener
void addScrollableListener(@NotNull final ScrollableListener listener)
Definition: GUILog.java:299
com.realtime.crossfire.jxclient.gui
com.realtime.crossfire.jxclient.gui.log.Buffer
Definition: Buffer.java:41
com.realtime.crossfire.jxclient.gui.log.GUILog.timer
final Timer timer
Definition: GUILog.java:122
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.scrollDown
void scrollDown(final int dy)
Definition: RenderStateManager.java:197
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.scrollTo
void scrollTo(final int y)
Definition: RenderStateManager.java:207
com.realtime.crossfire.jxclient.gui.log.RenderStateManager
Definition: RenderStateManager.java:32
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.guiFactory
final GuiFactory guiFactory
Definition: AbstractGUIElement.java:48
com.realtime.crossfire.jxclient.gui.log.GUILog.GUILog
GUILog(@NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final String name, @Nullable final Image backgroundImage, @NotNull final Fonts fonts, @NotNull final GuiFactory guiFactory)
Definition: GUILog.java:213
com.realtime.crossfire.jxclient.gui.log.GUILog.endSelection
int endSelection
Definition: GUILog.java:138
com.realtime.crossfire.jxclient.gui.log.GUILog.scrollTo
void scrollTo(final int pos)
Definition: GUILog.java:294
com.realtime.crossfire.jxclient.gui.log.GUILog.removeScrollableListener
void removeScrollableListener(@NotNull final ScrollableListener listener)
Definition: GUILog.java:304
com.realtime.crossfire.jxclient.gui.log.Buffer.removeBufferListener
void removeBufferListener(@NotNull final BufferListener listener)
Definition: Buffer.java:318
com.realtime.crossfire.jxclient.util
Definition: Codec.java:23
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getTopIndex
int getTopIndex()
Definition: RenderStateManager.java:155
com.realtime.crossfire.jxclient.gui.log.Buffer.coordinateToPosition
int coordinateToPosition(final int x, final int y)
Definition: Buffer.java:413
com.realtime.crossfire.jxclient.gui.log.Buffer.setRenderWidth
void setRenderWidth(final int renderWidth)
Definition: Buffer.java:132
com.realtime.crossfire.jxclient.skin.skin.GuiFactory
Definition: GuiFactory.java:41
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.name
final String name
Definition: AbstractGUIElement.java:77
com.realtime.crossfire.jxclient.gui.scrollable.GUIScrollable2
Definition: GUIScrollable2.java:33
com.realtime.crossfire.jxclient.gui.gui
Definition: AbstractGUIElement.java:23
com.realtime.crossfire.jxclient.gui.log.Buffer.setShowTimestamps
void setShowTimestamps(final boolean showTimestamps)
Definition: Buffer.java:162
com.realtime.crossfire.jxclient.gui.log.GUILog.setShowSentCommands
void setShowSentCommands(final boolean showSentCommands)
Definition: GUILog.java:416
com.realtime.crossfire.jxclient.gui.log.Fonts
Definition: Fonts.java:32
com.realtime.crossfire.jxclient.gui.scrollable.ScrollableListener
Definition: ScrollableListener.java:31
com.realtime.crossfire.jxclient.gui.log.Buffer.getTotalHeight
int getTotalHeight()
Definition: Buffer.java:275
com.realtime.crossfire
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getHeight
int getHeight()
Definition: RenderStateManager.java:147
com.realtime.crossfire.jxclient.gui.gui.TooltipManager
Definition: TooltipManager.java:33
com.realtime
com.realtime.crossfire.jxclient.gui.log.GUILog.startSelection
int startSelection
Definition: GUILog.java:128
com.realtime.crossfire.jxclient.gui.scrollable
Definition: GUIScrollable.java:23
com
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.update
void update(final int oldBufferHeight)
Definition: RenderStateManager.java:130
com.realtime.crossfire.jxclient.gui.log.GUILog.clipboard
final Clipboard clipboard
Definition: GUILog.java:103
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.tooltipManager
final TooltipManager tooltipManager
Definition: AbstractGUIElement.java:83
com.realtime.crossfire.jxclient.gui.log.GUILog.listeners
final EventListenerList2< ScrollableListener > listeners
Definition: GUILog.java:78
com.realtime.crossfire.jxclient.gui.log.GUILog.scroll
void scroll(final int distance)
Definition: GUILog.java:278
com.realtime.crossfire.jxclient.gui.log.GUILog.backgroundImage
final Image backgroundImage
Definition: GUILog.java:91
com.realtime.crossfire.jxclient.gui.log.GUILog.renderStateManager
final RenderStateManager renderStateManager
Definition: GUILog.java:97
com.realtime.crossfire.jxclient.gui.log.GUILog.dispose
void dispose()
Definition: GUILog.java:231
com.realtime.crossfire.jxclient.gui.log.GUILog.setSelection
void setSelection(final int selection)
Definition: GUILog.java:438
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.scrollUp
void scrollUp(final int dy)
Definition: RenderStateManager.java:187
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getTopOffset
int getTopOffset()
Definition: RenderStateManager.java:163
com.realtime.crossfire.jxclient.gui.log.GUILog.paintComponent
void paintComponent(@NotNull final Graphics g)
Definition: GUILog.java:238
com.realtime.crossfire.jxclient.gui.gui.GUIElementListener
Definition: GUIElementListener.java:32