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.List;
46 import javax.swing.Timer;
47 import org.jetbrains.annotations.NotNull;
48 import org.jetbrains.annotations.Nullable;
49 
55 public abstract class GUILog extends AbstractGUIElement implements GUIScrollable2 {
56 
60  private static final long serialVersionUID = 1;
61 
65  private static final int SCROLL_PIXEL = 48;
66 
71  private static final int TIMEOUT_AUTO_SCROLL = 25;
72 
76  @NotNull
78 
82  @NotNull
83  private final Buffer buffer;
84 
89  @Nullable
90  private final Image backgroundImage;
91 
95  @NotNull
97 
101  @NotNull
102  private final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
103 
108  @Nullable
109  private final Clipboard selection = Toolkit.getDefaultToolkit().getSystemSelection();
110 
114  @NotNull
115  private final ActionListener timeoutEvent = e -> autoScroll();
116 
120  @NotNull
121  private final Timer timer = new Timer(TIMEOUT_AUTO_SCROLL, timeoutEvent);
122 
127  private int startSelection;
128 
132  private int beginSelection;
133 
137  private int endSelection;
138 
143  private boolean scrollForwards;
144 
148  @NotNull
149  @SuppressWarnings("FieldCanBeLocal")
151 
152  @Override
153  public void stateChanged() {
154  setChanged();
155  for (ScrollableListener listener : listeners) {
156  listener.setRange(0, buffer.getTotalHeight(), renderStateManager.getScrollPos(), getHeight());
157  }
158  }
159 
160  @Override
161  public int getHeight() {
162  return Math.max(1, GUILog.this.getHeight());
163  }
164 
165  };
166 
170  @NotNull
172 
173  @Override
174  public void lineAdded() {
175  // does not affect the selection => ignore
176  }
177 
178  @Override
179  public void lineReplaced() {
180  // does not affect the selection => ignore
181  }
182 
183  @Override
184  public void linesRemoved(@NotNull final List<Line> lines) {
185  final int endPosition = lines.get(lines.size()-1).getEndPosition();
186  if (beginSelection > endPosition) {
187  beginSelection -= endPosition;
188  endSelection -= endPosition;
189  } else if (endSelection > endPosition) {
190  beginSelection = 0;
191  endSelection -= endPosition;
192  } else if (beginSelection > 0 || endSelection > 0) {
193  beginSelection = 0;
194  endSelection = 0;
195  }
196  }
197 
198  };
199 
210  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) {
212  this.backgroundImage = backgroundImage;
213  final FontRenderContext context;
214  final GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
215  final Graphics2D g = graphicsEnvironment.createGraphics(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)); // XXX
216  try {
217  context = g.getFontRenderContext();
218  } finally {
219  g.dispose();
220  }
221  buffer = new DefaultBuffer(fonts, context, getWidth());
223  renderStateManager.setHeight(getHeight());
225  }
226 
227  @Override
228  public void dispose() {
229  super.dispose();
232  }
233 
234  @Override
235  public void paintComponent(@NotNull final Graphics g) {
236  super.paintComponent(g);
237 
238  g.setColor(new Color(0, 0, 0, 0.0f));
239  g.fillRect(0, 0, getWidth(), getHeight());
240  if (backgroundImage != null) {
241  g.drawImage(backgroundImage, 0, 0, null);
242  }
243 
244  final int beginSelection = this.beginSelection;
245  final int endSelection = this.endSelection;
246  int y = -renderStateManager.getTopOffset();
247  final int topIndex = renderStateManager.getTopIndex();
248  synchronized (buffer.getSyncObject()) {
249  for (final Line line : buffer.lines(topIndex)) {
250  if (y >= getHeight()) {
251  break;
252  }
253  final int height = line.getHeight();
254  if (height > 0) {
255  line.drawLine((Graphics2D)g, y, beginSelection, endSelection);
256  y += height;
257  }
258  }
259  }
260  }
261 
262  @Override
263  public boolean canScroll(final int distance) { // XXX: implement |distance|>1
264  if (distance < 0) {
266  }
267  //noinspection SimplifiableIfStatement
268  if (distance > 0) {
270  }
271  return false;
272  }
273 
274  @Override
275  public void scroll(final int distance) {
276  if (distance < 0) {
278  } else if (distance > 0) {
280  } else {
281  assert false;
282  }
283  }
284 
285  @Override
286  public void resetScroll() {
288  }
289 
290  @Override
291  public void scrollTo(final int pos) {
293  }
294 
295  @Override
296  public void addScrollableListener(@NotNull final ScrollableListener listener) {
297  listeners.add(listener);
298  }
299 
300  @Override
301  public void removeScrollableListener(@NotNull final ScrollableListener listener) {
302  listeners.remove(listener);
303  }
304 
309  @NotNull
310  public Buffer getBuffer() {
311  return buffer;
312  }
313 
314  @Override
315  public void setBounds(final int x, final int y, final int width, final int height) {
316  super.setBounds(x, y, width, height);
317  buffer.setRenderWidth(width);
319  }
320 
321  @Override
322  public void mousePressed(@NotNull final MouseEvent e) {
323  super.mousePressed(e);
325  if (timer.isRunning()) {
326  timer.stop();
327  }
329  }
330 
331  @Override
332  public void mouseReleased(@NotNull final MouseEvent e) {
333  super.mouseReleased(e);
335  if (timer.isRunning()) {
336  timer.stop();
337  }
338  copy();
339  }
340 
341  @Override
342  public void mouseDragged(@NotNull final MouseEvent e) {
343  super.mouseDragged(e);
344 
345  if (e.getY() < 0) {
347  if (!timer.isRunning()) {
348  scrollForwards = false;
349  timer.start();
350  }
351  } else if (e.getY() >= getHeight()) {
353  if (!timer.isRunning()) {
354  scrollForwards = true;
355  timer.start();
356  }
357  } else {
359  if (timer.isRunning()) {
360  timer.stop();
361  }
362  }
363  }
364 
365  @Override
366  public void mouseWheelMoved(final int wheelRotation) {
367  super.mouseWheelMoved(wheelRotation);
368  scroll(wheelRotation);
369  }
370 
374  private void autoScroll() {
375  if (scrollForwards) {
379  }
380  } else {
385  timer.stop();
386  }
387  }
388  }
389  }
390 
396  private int getStartPosition() {
398  }
399 
405  private int getEndPosition() {
407  }
408 
413  public void setShowSentCommands(final boolean showSentCommands) {
414  final int oldBufferHeight = buffer.getTotalHeight();
415  buffer.setShowSentCommands(showSentCommands);
416  renderStateManager.update(oldBufferHeight);
417  }
418 
423  public void setShowTimestamps(final boolean showTimestamps) {
424  final int oldBufferHeight = buffer.getTotalHeight();
425  buffer.setShowTimestamps(showTimestamps);
426  renderStateManager.update(oldBufferHeight);
427  }
428 
433  private void setSelection(final int selection) {
434  final int newBeginSelection = Math.min(startSelection, selection);
435  final int newEndSelection = Math.max(startSelection, selection);
436  if (beginSelection == newBeginSelection && endSelection == newEndSelection) {
437  return;
438  }
439 
440  beginSelection = newBeginSelection;
441  endSelection = newEndSelection;
442  repaint();
443  }
444 
448  private void copy() {
449  final Transferable selection = new StringSelection(buffer.getText(beginSelection, endSelection));
450  if (this.selection != null) {
451  try {
452  this.selection.setContents(selection, null);
453  } catch (final IllegalStateException ignored) {
454  }
455  }
456  try {
457  clipboard.setContents(selection, null);
458  } catch (final IllegalStateException ignored) {
459  }
460  }
461 
462 }
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.setHeight
void setHeight(final int height)
Definition: RenderStateManager.java:122
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.name
final String name
Definition: AbstractGUIElement.java:77
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.skin.skin
Definition: DefaultJXCSkin.java:23
com.realtime.crossfire.jxclient.gui.log.GUILog.canScroll
boolean canScroll(final int distance)
Definition: GUILog.java:263
com.realtime.crossfire.jxclient.gui.log.Buffer.setShowTimestamps
void setShowTimestamps(final boolean showTimestamps)
Definition: Buffer.java:162
com.realtime.crossfire.jxclient.gui.log.GUILog.timeoutEvent
final ActionListener timeoutEvent
Definition: GUILog.java:115
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.resetScroll
void resetScroll()
Definition: RenderStateManager.java:178
com.realtime.crossfire.jxclient.gui.log.GUILog.scrollForwards
boolean scrollForwards
Definition: GUILog.java:143
com.realtime.crossfire.jxclient.gui.log.GUILog.scroll
void scroll(final int distance)
Definition: GUILog.java:275
com.realtime.crossfire.jxclient.gui.log.GUILog.clipboard
final Clipboard clipboard
Definition: GUILog.java:102
com.realtime.crossfire.jxclient.gui.log.RenderStateManager
Definition: RenderStateManager.java:32
com.realtime.crossfire.jxclient.skin
com.realtime.crossfire.jxclient.gui.log.GUILog.setSelection
void setSelection(final int selection)
Definition: GUILog.java:433
com.realtime.crossfire.jxclient.gui.log.GUILog.selection
final Clipboard selection
Definition: GUILog.java:109
com.realtime.crossfire.jxclient.gui.log.Line
Definition: Line.java:39
com.realtime.crossfire.jxclient.gui.log.GUILog.beginSelection
int beginSelection
Definition: GUILog.java:132
com.realtime.crossfire.jxclient.gui.log.GUILog.getStartPosition
int getStartPosition()
Definition: GUILog.java:396
com.realtime.crossfire.jxclient.gui.log.Buffer
Definition: Buffer.java:41
com.realtime.crossfire.jxclient.gui.log.GUILog.listeners
final EventListenerList2< ScrollableListener > listeners
Definition: GUILog.java:77
com.realtime.crossfire.jxclient.gui.log.GUILog.scrollTo
void scrollTo(final int pos)
Definition: GUILog.java:291
com.realtime.crossfire.jxclient.util.EventListenerList2
Definition: EventListenerList2.java:37
com.realtime.crossfire.jxclient.skin.skin.GuiFactory
Definition: GuiFactory.java:41
com.realtime.crossfire.jxclient.gui.log.BufferListener
Definition: BufferListener.java:33
com.realtime.crossfire.jxclient.gui.log.Buffer.setRenderWidth
void setRenderWidth(final int renderWidth)
Definition: Buffer.java:132
com.realtime.crossfire.jxclient.gui.log.GUILog.resetScroll
void resetScroll()
Definition: GUILog.java:286
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getScrollPos
int getScrollPos()
Definition: RenderStateManager.java:171
com.realtime.crossfire.jxclient.gui.log.GUILog.endSelection
int endSelection
Definition: GUILog.java:137
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.canScrollUp
boolean canScrollUp()
Definition: RenderStateManager.java:216
com.realtime.crossfire.jxclient.gui.scrollable.ScrollableListener
Definition: ScrollableListener.java:31
com.realtime.crossfire.jxclient.gui.log.Buffer.lines
final List< Line > lines
Definition: Buffer.java:63
com.realtime.crossfire.jxclient.gui.log.GUILog.removeScrollableListener
void removeScrollableListener(@NotNull final ScrollableListener listener)
Definition: GUILog.java:301
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.update
void update(final int oldBufferHeight)
Definition: RenderStateManager.java:130
com.realtime.crossfire.jxclient.gui.log.GUILog.timer
final Timer timer
Definition: GUILog.java:121
com.realtime.crossfire.jxclient.gui.log.GUILog.mouseWheelMoved
void mouseWheelMoved(final int wheelRotation)
Definition: GUILog.java:366
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getHeight
int getHeight()
Definition: RenderStateManager.java:147
com.realtime.crossfire.jxclient.gui.log.GUILog.backgroundImage
final Image backgroundImage
Definition: GUILog.java:90
com.realtime.crossfire.jxclient.gui.log.GUILog.mouseReleased
void mouseReleased(@NotNull final MouseEvent e)
Definition: GUILog.java:332
com.realtime.crossfire.jxclient.gui.log.GUILog.mouseDragged
void mouseDragged(@NotNull final MouseEvent e)
Definition: GUILog.java:342
com.realtime.crossfire.jxclient.gui.log.GUILog.TIMEOUT_AUTO_SCROLL
static final int TIMEOUT_AUTO_SCROLL
Definition: GUILog.java:71
com.realtime.crossfire.jxclient.gui.log.GUILog.copy
void copy()
Definition: GUILog.java:448
com.realtime.crossfire.jxclient.gui.log.RenderStateListener
Definition: RenderStateListener.java:30
com.realtime.crossfire.jxclient.gui.log.GUILog.serialVersionUID
static final long serialVersionUID
Definition: GUILog.java:60
com.realtime.crossfire.jxclient.gui.log.Buffer.removeBufferListener
void removeBufferListener(@NotNull final BufferListener listener)
Definition: Buffer.java:318
com.realtime.crossfire.jxclient.gui.log.GUILog
Definition: GUILog.java:55
com.realtime.crossfire.jxclient.gui.log.GUILog.SCROLL_PIXEL
static final int SCROLL_PIXEL
Definition: GUILog.java:65
com.realtime.crossfire.jxclient.gui.scrollable.GUIScrollable2
Definition: GUIScrollable2.java:33
com.realtime.crossfire.jxclient.gui.log.GUILog.mousePressed
void mousePressed(@NotNull final MouseEvent e)
Definition: GUILog.java:322
com.realtime.crossfire.jxclient.gui
com.realtime.crossfire.jxclient.gui.log.Buffer.addBufferListener
void addBufferListener(@NotNull final BufferListener listener)
Definition: Buffer.java:310
com.realtime.crossfire.jxclient.gui.log.GUILog.renderStateManager
final RenderStateManager renderStateManager
Definition: GUILog.java:96
com.realtime.crossfire.jxclient.gui.log.Buffer.getTotalHeight
int getTotalHeight()
Definition: Buffer.java:275
com.realtime.crossfire.jxclient.gui.log.Fonts
Definition: Fonts.java:32
com.realtime.crossfire.jxclient.util
Definition: Codec.java:23
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.elementListener
final GUIElementListener elementListener
Definition: AbstractGUIElement.java:89
com.realtime.crossfire.jxclient.gui.log.GUILog.autoScroll
void autoScroll()
Definition: GUILog.java:374
com.realtime.crossfire.jxclient.gui.gui.TooltipManager
Definition: TooltipManager.java:33
com.realtime.crossfire.jxclient.gui.log.Buffer.setShowSentCommands
void setShowSentCommands(final boolean showSentCommands)
Definition: Buffer.java:147
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.scrollDown
void scrollDown(final int dy)
Definition: RenderStateManager.java:197
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:315
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.dispose
void dispose()
Definition: RenderStateManager.java:139
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.scrollUp
void scrollUp(final int dy)
Definition: RenderStateManager.java:187
com.realtime.crossfire.jxclient.gui.gui
Definition: AbstractGUIElement.java:23
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.canScrollDown
boolean canScrollDown()
Definition: RenderStateManager.java:224
com.realtime.crossfire.jxclient.gui.log.GUILog.startSelection
int startSelection
Definition: GUILog.java:127
com.realtime.crossfire.jxclient.gui.log.GUILog.buffer
final Buffer buffer
Definition: GUILog.java:83
com.realtime.crossfire.jxclient.gui.log.GUILog.setShowSentCommands
void setShowSentCommands(final boolean showSentCommands)
Definition: GUILog.java:413
com.realtime.crossfire
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.GUILog.getBuffer
Buffer getBuffer()
Definition: GUILog.java:310
com.realtime
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getTopOffset
int getTopOffset()
Definition: RenderStateManager.java:163
com.realtime.crossfire.jxclient.gui.scrollable
Definition: GUIScrollable.java:23
com.realtime.crossfire.jxclient.gui.log.GUILog.addScrollableListener
void addScrollableListener(@NotNull final ScrollableListener listener)
Definition: GUILog.java:296
com.realtime.crossfire.jxclient.gui.log.GUILog.bufferListener
final BufferListener bufferListener
Definition: GUILog.java:171
com
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:210
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.getTopIndex
int getTopIndex()
Definition: RenderStateManager.java:155
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.setChanged
void setChanged()
Definition: AbstractGUIElement.java:223
com.realtime.crossfire.jxclient.gui.log.GUILog.getEndPosition
int getEndPosition()
Definition: GUILog.java:405
com.realtime.crossfire.jxclient.gui.log.GUILog.dispose
void dispose()
Definition: GUILog.java:228
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.gui.AbstractGUIElement
Definition: AbstractGUIElement.java:37
com.realtime.crossfire.jxclient.gui.log.Buffer.getSyncObject
Object getSyncObject()
Definition: Buffer.java:327
com.realtime.crossfire.jxclient.gui.log.RenderStateManager.scrollTo
void scrollTo(final int y)
Definition: RenderStateManager.java:207
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.guiFactory
final GuiFactory guiFactory
Definition: AbstractGUIElement.java:48
com.realtime.crossfire.jxclient.gui.log.DefaultBuffer
Definition: DefaultBuffer.java:13
com.realtime.crossfire.jxclient.gui.log.GUILog.renderStateListener
final RenderStateListener renderStateListener
Definition: GUILog.java:150
com.realtime.crossfire.jxclient.gui.log.GUILog.setShowTimestamps
void setShowTimestamps(final boolean showTimestamps)
Definition: GUILog.java:423
com.realtime.crossfire.jxclient.gui.log.GUILog.paintComponent
void paintComponent(@NotNull final Graphics g)
Definition: GUILog.java:235
com.realtime.crossfire.jxclient.gui.gui.GUIElementListener
Definition: GUIElementListener.java:32
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.tooltipManager
final TooltipManager tooltipManager
Definition: AbstractGUIElement.java:83