ToolTip: fixed positioning of huge tooltips (issue #333)

This commit is contained in:
Karl Tauber
2021-06-11 20:53:09 +02:00
parent 7b248427f0
commit d962f218a1
2 changed files with 32 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ FlatLaf Change Log
- Fixed white lines at bottom and right side of window (in dark themes on HiDPI - Fixed white lines at bottom and right side of window (in dark themes on HiDPI
screens with scaling enabled). screens with scaling enabled).
- ToolTip: Fixed positioning of huge tooltips. (issue #333)
## 1.2 ## 1.2

View File

@@ -20,12 +20,16 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets; import java.awt.Insets;
import java.awt.MouseInfo; import java.awt.MouseInfo;
import java.awt.Panel; import java.awt.Panel;
import java.awt.Point; import java.awt.Point;
import java.awt.PointerInfo; import java.awt.PointerInfo;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener; import java.awt.event.ComponentListener;
@@ -63,7 +67,7 @@ public class FlatPopupFactory
public Popup getPopup( Component owner, Component contents, int x, int y ) public Popup getPopup( Component owner, Component contents, int x, int y )
throws IllegalArgumentException throws IllegalArgumentException
{ {
Point pt = fixToolTipLocation( contents, x, y ); Point pt = fixToolTipLocation( owner, contents, x, y );
if( pt != null ) { if( pt != null ) {
x = pt.x; x = pt.x;
y = pt.y; y = pt.y;
@@ -207,13 +211,13 @@ public class FlatPopupFactory
/** /**
* Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20). * Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20).
* In case that the tooltip would be partly outside of the screen, * In case that the tooltip would be partly outside of the screen,
* ToolTipManagerthe changes the location so that the entire tooltip fits on screen. * the ToolTipManager changes the location so that the entire tooltip fits on screen.
* But this can place the tooltip under the mouse location and hide the owner component. * But this can place the tooltip under the mouse location and hide the owner component.
* <p> * <p>
* This method checks whether the current mouse location is within tooltip bounds * This method checks whether the current mouse location is within tooltip bounds
* and corrects the y-location so that the tooltip is placed above the mouse location. * and corrects the y-location so that the tooltip is placed above the mouse location.
*/ */
private Point fixToolTipLocation( Component contents, int x, int y ) { private Point fixToolTipLocation( Component owner, Component contents, int x, int y ) {
if( !(contents instanceof JToolTip) || !wasInvokedFromToolTipManager() ) if( !(contents instanceof JToolTip) || !wasInvokedFromToolTipManager() )
return null; return null;
@@ -229,8 +233,30 @@ public class FlatPopupFactory
if( !tipBounds.contains( mouseLocation ) ) if( !tipBounds.contains( mouseLocation ) )
return null; return null;
// place tooltip above mouse location // find GraphicsConfiguration at mouse location (similar to ToolTipManager.getDrawingGC())
return new Point( x, mouseLocation.y - tipSize.height - UIScale.scale( 20 ) ); GraphicsConfiguration gc = null;
for( GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() ) {
GraphicsConfiguration dgc = device.getDefaultConfiguration();
if( dgc.getBounds().contains( mouseLocation ) ) {
gc = dgc;
break;
}
}
if( gc == null )
gc = owner.getGraphicsConfiguration();
if( gc == null )
return null;
Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc );
int screenTop = screenBounds.y + screenInsets.top;
// place tooltip above mouse location if there is enough space
int newY = mouseLocation.y - tipSize.height - UIScale.scale( 20 );
if( newY < screenTop )
return null;
return new Point( x, newY );
} }
private boolean wasInvokedFromToolTipManager() { private boolean wasInvokedFromToolTipManager() {