Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add animated transition to frame on double-click. #37

Merged
merged 3 commits into from
Mar 18, 2022

Conversation

jfree
Copy link
Collaborator

@jfree jfree commented Mar 17, 2022

Adds an animated transition between frames upon double-click, using the Radiance animation library (https://github.com/kirill-grouchnikov/radiance). To make this work, a small refactoring has been done to remove state from the FrameGraphPainter (specifically flameGraphWidth and visibleWidth) that can more easily be passed to the paint methods when called.

To test this PR, run the main app, load a JFR file and double-click on some frames.

@bric3
Copy link
Owner

bric3 commented Mar 17, 2022

Nice this works well. I wonder though if the external library could be plugged in as most of its code is the ZoomTarget consumer.

I haven't looked at all the code yet. But I like the ZoomTarget notion and that the width is now specific to the canvas.

Comment on lines +367 to +375
.ifPresent(fgp -> fgp.hoverFrameAt(
(Graphics2D) view.getGraphics(),
canvas.getBounds(),
point,
frame -> {
canvas.setToolTipText(frame);
scrollPane.repaint();
}
));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bric3
Copy link
Owner

bric3 commented Mar 17, 2022

Enabling the debug mode -Dfireplace.swing.debug=true I noticed this triggers a lot of violations. This may cause some issues if this components gets embedded in an app that checks these (like IJ).

EDT violation detected on component javax.swing.JScrollPane[,0,0,1000x475,invalid,layout=javax.swing.ScrollPaneLayout$UIResource,alignmentX=0.0,alignmentY=0.0,border=com.formdev.flatlaf.ui.FlatBorder@22284f87,flags=320,maximumSize=,minimumSize=,preferredSize=,columnHeader=,horizontalScrollBar=javax.swing.JScrollPane$ScrollBar[,3,462,984x10,layout=com.formdev.flatlaf.ui.FlatScrollBarUI,alignmentX=0.0,alignmentY=0.0,border=,flags=4194632,maximumSize=,minimumSize=,preferredSize=,blockIncrement=10,orientation=HORIZONTAL,unitIncrement=16],horizontalScrollBarPolicy=HORIZONTAL_SCROLLBAR_AS_NEEDED,lowerLeft=,lowerRight=,rowHeader=,upperLeft=,upperRight=,verticalScrollBar=javax.swing.JScrollPane$ScrollBar[,987,3,10x459,layout=com.formdev.flatlaf.ui.FlatScrollBarUI,alignmentX=0.0,alignmentY=0.0,border=,flags=4194632,maximumSize=,minimumSize=,preferredSize=,blockIncrement=10,orientation=VERTICAL,unitIncrement=16],verticalScrollBarPolicy=VERTICAL_SCROLLBAR_AS_NEEDED,viewport=javax.swing.JViewport[,3,3,984x459,invalid,layout=javax.swing.ViewportLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=25165832,maximumSize=,minimumSize=,preferredSize=,isViewSizeSet=true,lastPaintPosition=java.awt.Point[x=-7705,y=-172],scrollUnderway=true],viewportBorder=]
    at java.desktop/javax.swing.JComponent.repaint(JComponent.java:4836)
    at java.desktop/javax.swing.JViewport.repaint(JViewport.java:1509)
    at java.desktop/java.awt.Component.repaint(Component.java:3436)
    at java.desktop/java.awt.Component.repaintParentIfNeeded(Component.java:2402)
    at java.desktop/java.awt.Component.reshape(Component.java:2390)
    at java.desktop/javax.swing.JComponent.reshape(JComponent.java:4241)
    at java.desktop/java.awt.Component.setBounds(Component.java:2326)
    at java.desktop/java.awt.Component.move(Component.java:2158)
    at java.desktop/java.awt.Component.setLocation(Component.java:2140)
    at java.desktop/javax.swing.JViewport.setViewPosition(JViewport.java:1240)
    at io.github.bric3.fireplace.flamegraph.FlameGraph$FlameGraphMouseInputListener$1.onTimelinePulse(FlameGraph.java:316)
    at org.pushingpixels.radiance.animation.api.Timeline$Chain.handlePulse(Timeline.java:298)
    at org.pushingpixels.radiance.animation.api.Timeline$Chain.onTimelinePulse(Timeline.java:315)
    at org.pushingpixels.radiance.animation.api.TimelineEngine.lambda$callbackCallTimelinePulse$3(TimelineEngine.java:505)
    at org.pushingpixels.radiance.animation.api.TimelineEngine$TimelineCallbackThread.run(TimelineEngine.java:182)

EDT violation detected on component io.github.bric3.fireplace.flamegraph.FlameGraph$FlameGraphCanvas[,-9825,-219,11108x108535,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
    at java.desktop/javax.swing.JComponent.repaint(JComponent.java:4836)
    at java.desktop/java.awt.Component.repaint(Component.java:3393)
    at java.desktop/java.awt.Component.repaintParentIfNeeded(Component.java:2404)
    at java.desktop/java.awt.Component.reshape(Component.java:2390)
    at java.desktop/javax.swing.JComponent.reshape(JComponent.java:4241)
    at java.desktop/java.awt.Component.setBounds(Component.java:2326)
    at java.desktop/java.awt.Component.move(Component.java:2158)
    at java.desktop/java.awt.Component.setLocation(Component.java:2140)
    at java.desktop/javax.swing.JViewport.setViewPosition(JViewport.java:1240)
    at io.github.bric3.fireplace.flamegraph.FlameGraph$FlameGraphMouseInputListener$1.onTimelinePulse(FlameGraph.java:316)
    at org.pushingpixels.radiance.animation.api.Timeline$Chain.handlePulse(Timeline.java:298)
    at org.pushingpixels.radiance.animation.api.Timeline$Chain.onTimelinePulse(Timeline.java:315)
    at org.pushingpixels.radiance.animation.api.TimelineEngine.lambda$callbackCallTimelinePulse$3(TimelineEngine.java:505)
    at org.pushingpixels.radiance.animation.api.TimelineEngine$TimelineCallbackThread.run(TimelineEngine.java:182)

@bric3
Copy link
Owner

bric3 commented Mar 17, 2022

I didn't see a toggle to enable or disable animations. (This might go along with plugability)

@jfree
Copy link
Collaborator Author

jfree commented Mar 17, 2022

I'll fix the EDT violations first, should have checked myself 🤦‍♂️

@jfree
Copy link
Collaborator Author

jfree commented Mar 18, 2022

I didn't see a toggle to enable or disable animations. (This might go along with plugability)

Now there is an attribute animateZoomTransitions on the FlameGraphCanvas which defaults to true. This can be disabled programmatically, or by setting the System property fireplace.zoom.animation.disabled at program startup.

@bric3
Copy link
Owner

bric3 commented Mar 18, 2022

I guess the animation library would cause trouble if you want to get this into JMC. What kind of pluggability did you have in mind?

Since all the animation code is contained as a consumer here, we can create a separate gradle module that extends the core flameGraph by configuring the consumer.

Another alternative is I just roll-my-own timeline pulse generator with java.util.concurrent - I don’t think it would be that hard.

Possibly but I still think this could be made as a separate module.

Bu we can move extract this in another PR, to move quickly.

@bric3 bric3 merged commit 12688e6 into bric3:master Mar 18, 2022
bric3 added a commit that referenced this pull request Mar 18, 2022
feat: add popup handler mechanism.
@kirill-grouchnikov
Copy link

Just happened to see this PR. Haven't looked closely at everything, but one thing jumped out - EDT violations. Radiance animation has a special annotation to mark callbacks to be dispatched on the EDT - org.pushingpixels.radiance.animation.api.swing.RunOnEventDispatchThread. There's also the base EventDispatchThreadTimelineCallbackAdapter that can be used without the explicit need to wrap stuff with SwingUtilities.invokeLater.

@jfree
Copy link
Collaborator Author

jfree commented Apr 2, 2022

Thanks Kirill, I'm going to take a look at this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants