Crossfire JXClient, Trunk  R20561
TooltipManagerImpl.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-2011 Andreas Kirschbaum.
20  */
21 
22 package com.realtime.crossfire.jxclient.gui.label;
23 
30 import java.awt.Component;
31 import java.util.Map;
32 import java.util.WeakHashMap;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35 
41 public class TooltipManagerImpl implements TooltipManager {
42 
46  private static final int TOOLTIP_DISTANCE = 8;
47 
51  private int windowWidth;
52 
56  private int windowHeight;
57 
62  @Nullable
64 
69  @Nullable
71 
75  @NotNull
76  private final Object activeGuiElementSync = new Object();
77 
83  @NotNull
84  private final Map<GUIElement, TooltipText> tooltipTexts = new WeakHashMap<>();
85 
90  @NotNull
91  private final Runnable resetRunnable = new Runnable() {
92 
93  @Override
94  public void run() {
95  synchronized (activeGuiElementSync) {
96  removeTooltip();
97  activeGuiElement = null;
98  }
99  }
100 
101  };
102 
108  public void setScreenSize(final int windowWidth, final int windowHeight) {
109  this.windowWidth = windowWidth;
110  this.windowHeight = windowHeight;
111  }
112 
117  public void setTooltip(@Nullable final AbstractLabel tooltip) {
118  this.tooltip = tooltip;
119  }
120 
124  public void reset() {
125  SwingUtilities2.invokeAndWait(resetRunnable);
126  }
127 
131  @Override
132  public void setElement(@NotNull final GUIElement guiElement) {
133  final TooltipText tooltipText = tooltipTexts.get(guiElement);
134  if (tooltipText != null) {
135  guiElement.setTooltipText(tooltipText.getText());
136  }
138  synchronized (activeGuiElementSync) {
139  if (activeGuiElement == null) {
140  activeGuiElement = guiElement;
141  addTooltip();
142  } else if (activeGuiElement != guiElement) {
143  removeTooltip();
144  activeGuiElement = guiElement;
145  addTooltip();
146  }
147  }
148  });
149  }
150 
154  @Override
155  public void unsetElement(@NotNull final GUIElement guiElement) {
157  synchronized (activeGuiElementSync) {
158  if (activeGuiElement == guiElement) {
159  removeTooltip();
160  activeGuiElement = null;
161  }
162  }
163  });
164  }
165 
169  @Override
170  public void setTooltipText(@NotNull final AbstractGUIElement element, @Nullable final String tooltipText) {
171  final Component gui = GuiUtils.getGui(element);
172  if (gui != null) {
173  setTooltipText(element, tooltipText, gui.getX()+element.getX(), gui.getY()+element.getY(), element.getWidth(), element.getHeight());
174  }
175  }
176 
180  @Override
181  public void setTooltipText(@NotNull final GUIElement element, @Nullable final String tooltipText, final int x, final int y, final int w, final int h) {
182  final TooltipText oldTooltipText = tooltipTexts.get(element);
183  if (oldTooltipText == null) {
184  if (tooltipText == null) {
185  return;
186  }
187  } else {
188  if (tooltipText != null && tooltipText.equals(oldTooltipText.getText()) && x == oldTooltipText.getX() && y == oldTooltipText.getY() && w == oldTooltipText.getW() && h == oldTooltipText.getH()) {
189  return;
190  }
191  }
192  tooltipTexts.put(element, tooltipText == null ? null : new TooltipText(tooltipText, x, y, w, h));
193 
195  synchronized (activeGuiElementSync) {
196  if (activeGuiElement == element) {
197  removeTooltip();
198  addTooltip();
199  }
200  }
201  });
202  }
203 
207  @Override
208  public boolean hasTooltipText(final AbstractGUIElement element) {
209  return tooltipTexts.get(element) != null;
210  }
211 
216  private void addTooltip() {
217  final GUIElement tmpActiveGuiElement = activeGuiElement;
218  assert tmpActiveGuiElement != null;
219  assert Thread.holdsLock(activeGuiElementSync);
220 
221  final AbstractLabel tmpTooltip = tooltip;
222  if (tmpTooltip == null) {
223  return;
224  }
225 
226  final TooltipText tooltipText = tooltipTexts.get(tmpActiveGuiElement);
227  if (tooltipText == null) {
228  tmpTooltip.setVisible(false);
229  return;
230  }
231 
232  tmpTooltip.setVisible(true);
233  tmpTooltip.setText(tooltipText.getText());
234 
235  final int preferredX = tooltipText.getX()+tooltipText.getW()/2-tmpTooltip.getWidth()/2;
236  final int maxX = windowWidth-tmpTooltip.getWidth();
237  final int tx = Math.max(0, Math.min(preferredX, maxX));
238  final int elementY = tooltipText.getY();
239  final int preferredY = elementY+tooltipText.getH()+TOOLTIP_DISTANCE;
240  final int ty = preferredY+tmpTooltip.getHeight() <= windowHeight ? preferredY : elementY-tmpTooltip.getHeight()-TOOLTIP_DISTANCE;
241  tmpTooltip.setLocation(tx, ty);
242  }
243 
247  private void removeTooltip() {
248  if (tooltip != null) {
249  tooltip.setVisible(false);
250  }
251  }
252 
253 }
void addTooltip()
Adds or updates the tooltip (text and location) for the activeGuiElement.
Abstract base class for all label classes.
static Gui getGui(@NotNull final Component element)
Returns the Gui an element is part of.
Definition: GuiUtils.java:91
void setText(@NotNull final String text)
The label text.
Information for displaying tooltips.
final Object activeGuiElementSync
Synchronizes accesses to activeGuiElement.
int getY()
Returns the y coordinate of the associated gui element.
Interface defining an abstract GUI element.
Definition: GUIElement.java:32
boolean hasTooltipText(final AbstractGUIElement element)
Returns whether the tooltip is enabled.the element to check whether the tooltip is enabled ...
void setElement(@NotNull final GUIElement guiElement)
Displays the tooltip for a GUI element.the GUI element to show the tooltip of
void unsetElement(@NotNull final GUIElement guiElement)
Removes the tooltip of a GUI element.Does nothing if the given GUI element is not active...
int getW()
Returns the width of the associated gui element.
Utility class for Gui related functions.
Definition: GuiUtils.java:35
int getH()
Returns the height of the associated gui element.
GUIElement activeGuiElement
The last known active gui element.
Utility class for Swing related functions.
void setScreenSize(final int windowWidth, final int windowHeight)
Updates the current window size.
void setTooltipText(@NotNull final GUIElement element, @Nullable final String tooltipText, final int x, final int y, final int w, final int h)
Updates the tooltip text of a GUI element.Does nothing if the given GUI element is not active...
Abstract base class for GUI elements to be shown in Guis.
int getX()
Returns the x coordinate of the associated gui element.
static final int TOOLTIP_DISTANCE
Distance of tooltip from its associated GUI element.
final Runnable resetRunnable
The Runnable that implements the functionality of reset().
final Map< GUIElement, TooltipText > tooltipTexts
Maps GUIElement to associated TooltipText.
void setTooltip(@Nullable final AbstractLabel tooltip)
Sets the tooltip label.
static void invokeAndWait(@NotNull final Runnable runnable)
Calls SwingUtilities#invokeAndWait(Runnable) if not on the EDT or calls the Runnable directly if on t...
void setTooltipText(@NotNull final AbstractGUIElement element, @Nullable final String tooltipText)
Updates the tooltip text of a GUI element.Does nothing if the given GUI element is not active...