kirill-grouchnikov / radiance

Building modern, elegant and fast Swing applications
BSD 3-Clause "New" or "Revised" License
807 stars 89 forks source link

[Component] Crash on displaying rich tooltips on Java 17+ #413

Closed homebeaver closed 2 years ago

homebeaver commented 2 years ago

Hi Kirill,

when using SVG File Viewer I get this OfBoundsException. To reproduce try to get the tooltip on an icon at right border.

Version of Radiance (latest development is 6.5-SNAPSHOT) : v5.0.0

Sub-project (Common, Animation, Theming, Component, ...) : component

Version of Java (current minimum is 9) : 17

Version of OS : WIN-10

The issue you're experiencing (expected vs actual, screenshot, stack trace etc)

grafik

Stack trace (line numbers not exact, because I add some log traces):


Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 9
    at java.desktop/java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:365)
    at java.desktop/java.awt.font.LineBreakMeasurer.nextLayout(LineBreakMeasurer.java:441)
    at java.desktop/java.awt.font.LineBreakMeasurer.nextLayout(LineBreakMeasurer.java:414)
    at org.pushingpixels.radiance.component.internal.ui.common.BasicRichTooltipPanelUI$RichTooltipPanelLayout.layoutContainer(BasicRichTooltipPanelUI.java:345)
    at java.desktop/java.awt.Container.layout(Container.java:1541)
    at java.desktop/java.awt.Container.doLayout(Container.java:1530)
    at java.desktop/java.awt.Container.validateTree(Container.java:1725)
    at java.desktop/java.awt.Container.validateTree(Container.java:1734)
    at java.desktop/java.awt.Container.validateTree(Container.java:1734)
    at java.desktop/java.awt.Container.validateTree(Container.java:1734)
    at java.desktop/java.awt.Container.validateTree(Container.java:1734)
    at java.desktop/java.awt.Container.validate(Container.java:1660)
    at java.desktop/javax.swing.Popup.reset(Popup.java:168)
    at java.desktop/javax.swing.PopupFactory$HeavyWeightPopup.getHeavyWeightPopup(PopupFactory.java:409)
    at java.desktop/javax.swing.PopupFactory.getHeavyWeightPopup(PopupFactory.java:336)
    at java.desktop/javax.swing.PopupFactory.getPopup(PopupFactory.java:291)
    at java.desktop/javax.swing.PopupFactory.getPopup(PopupFactory.java:235)
    at java.desktop/javax.swing.PopupFactory.getPopup(PopupFactory.java:194)
    at org.pushingpixels.radiance.component.api.common.RichTooltipManager.showTipWindow(RichTooltipManager.java:240)
    at org.pushingpixels.radiance.component.api.common.RichTooltipManager$InitialDelayTimerAction.actionPerformed(RichTooltipManager.java:345)
    at java.desktop/javax.swing.Timer.fireActionPerformed(Timer.java:311)
    at java.desktop/javax.swing.Timer$DoPostEvent.run(Timer.java:243)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
kirill-grouchnikov commented 2 years ago

Is this only happening for empty title or empty description? I can't reproduce this in the SVG viewer demo.

If this is only happening in those cases, I'd rather throw an exception in the RichTooltip.Builder.build() to not accept rich tooltips like that and force application code to provide that content.

homebeaver commented 2 years ago

With SVG File Viewer I open the folder theming/src/main/java/org/pushingpixels/radiance/theming/internal/svg/

The titleLabelWidth is calculated in BasicRichTooltipPanelUI$RichTooltipPanelLayout layoutContainer line 327. I add a log-trace there:

            // The title label
            int titleLabelWidth = parent.getWidth() - ins.left - ins.right;
            if(titleLabelWidth<0)
                LOG.info("parent Container:"+parent + ", parent.getWidth()="+parent.getWidth() + ", ins.left="+ins.left + ", ins.right="+ins.right);
... results to
INFORMATION: parent Container:org.pushingpixels.radiance.component.internal.ui.common.JRichTooltipPanel[,0,0,1x1,invalid,layout=org.pushingpixels.radiance.component.internal.ui.common.BasicRichTooltipPanelUI$RichTooltipPanelLayout,alignmentX=0.0,alignmentY=0.0,border=org.pushingpixels.radiance.theming.internal.utils.border.RadianceBorder@372f64a0,flags=9,maximumSize=,minimumSize=,preferredSize=], 
parent.getWidth()=1, ins.left=5, ins.right=5

So titleLabelWidthis -9!

kirill-grouchnikov commented 2 years ago

The fix should address the real issue, which is a 1x1 size of the JRichTooltipPanel

kirill-grouchnikov commented 2 years ago

Comment on the new commit:

This is still addressing the symptom. It should not be getting to a place where the size is 1x1.

The first place to check would be RichTooltipPanelLayout.preferredLayoutSize. The next one would be in RichTooltipManager.showTipWindow or maybe a bit before to track where the size is computed and set on the JRichTooltipPanel. There's a block in lines 205-207 that computes that.

homebeaver commented 2 years ago

Hi @kirill-grouchnikov I could not find why JRichTooltipPanel is 1x1

But I can reproduce the problem:

How to reproduce:

grafik

grafik

kirill-grouchnikov commented 2 years ago

Where do I find SvgViewer413?

homebeaver commented 2 years ago

commit 67b3bf0

kirill-grouchnikov commented 2 years ago

Still not seeing this. Is this happening for you on other machines with different OS / JVM versions?

kirill-grouchnikov commented 2 years ago

Ah, I see it now with Java 17

kirill-grouchnikov commented 2 years ago

Ugh, I would consider this a regression introduced in the JDK by this commit, and in particular this line that sets the popup content to the size of 1x1 before packing it.

Not much I can do in Radiance to work around this except for short-circuiting and not doing anything in the layout pass if the size is 1x1.