mgarin / weblaf

WebLaF is a fully open-source Look & Feel and component library written in pure Java for cross-platform desktop Swing applications.
http://weblookandfeel.com
GNU General Public License v3.0
1.13k stars 234 forks source link

JInternalFrame resizing problem #490

Closed stefan-reich closed 6 years ago

stefan-reich commented 6 years ago

Hi,

I tried the latest 1.2.9 WebLAF snapshot in my OS, and it is almost working! Looks really good too.

Problem 1: UI feels noticeably sluggish compared to other PLAFs (e.g. JTattoo). Not sure if that is due to advanced rendering?

Problem 2: Some internal frames always grow whenever you try to resize them (never shrink). Notice the big window in the background which basically only contains a JTextArea in a JScrollPane. Other PLAFs allow these same windows to be resized normally.

Many greetings, Stefan BotCompany.de

mgarin commented 6 years ago

Problem 1: UI feels noticeably sluggish compared to other PLAFs (e.g. JTattoo). Not sure if that is due to advanced rendering?

It might be a bit slower than other L&F libraries, but that heavily depends on use case.

By looking at the screenshot and considering the second problem context - I suppose you are using lots of JInternalFrames in that application. If so - that might be the reason of "sluggish" UI. Basically all JInternalFrames are non-opaque on your screenshot which puts a lot of strain on the rendering process due to the way Swing renders things.

I didn't really optimize default JInternalFrame style for some "heavy" use cases, so no wonder it may perform poorly.

My recomendation - if you want to increase performance - adjust JInternalFrame style to make them use a simple rectangular shape and be opaque. Default JInternalFrame style (internalframe.xml) looks like this:

    <!-- Internal frame -->
    <style type="internalframe">
        <component>
            <opaque>false</opaque>
        </component>
        <painter>
            <decorations>
                <decoration>
                    <WebShape round="4" />
                    <WebShadow type="outer" opacity="0.35" width="10" />
                    <LineBorder color="170,170,170" />
                    <ColorBackground color="237,237,237" />
                </decoration>
                <decoration states="focused">
                    <WebShadow type="outer" opacity="0.7" />
                </decoration>
                <decoration states="maximized">
                    <WebShape round="0" />
                    <WebShadow type="outer" width="0" />
                    <LineBorder opacity="0" />
                </decoration>
            </decorations>
        </painter>

        <!-- Title panel -->
        <style type="panel" id="title" extends="transparent" padding="0,5,0,0">

            <!-- Title icon -->
            <style type="image" id="icon" />

            <!-- Title label -->
            <style type="label" id="title" extends="shadow" padding="0,5,0,10">
                <component class="com.alee.laf.label.WebLabel">
                    <horizontalAlignment>0</horizontalAlignment>
                    <maximumWidth>100</maximumWidth>
                </component>
            </style>

            <!-- Buttons panel -->
            <style type="panel" id="buttons" extends="grouppane">

                <!-- Decoration control buttons -->
                <style type="button" id="control" padding="3,5,3,5">
                    <component>
                        <focusable>false</focusable>
                    </component>
                    <painter>
                        <decorations>
                            <decoration>
                                <WebShape round="2" />
                                <WebShadow type="outer" width="5" />
                            </decoration>
                        </decorations>
                    </painter>
                </style>
                <style type="button" id="minimize" extends="control" />
                <style type="button" id="maximize" extends="control" />
                <style type="button" id="close" extends="control" />

            </style>

        </style>

        <!-- Root pane -->
        <style type="rootpane" id="rootpane">
            <component>
                <opaque>false</opaque>
            </component>

            <!-- Content pane -->
            <style type="panel" id="content" extends="transparent" />

        </style>

    </style>

You don't really need to adjust everything - just the JInternalFrame decoration, so something like this should do the job:

    <!-- Internal frame -->
    <style type="internalframe">
        <component>
            <opaque>true</opaque>
        </component>
        <painter>
            <decorations overwrite="true">
                <decoration>
                    <WebShape round="0" />
                    <LineBorder color="170,170,170" />
                    <ColorBackground color="237,237,237" />
                </decoration>
                <decoration states="maximized">
                    <LineBorder opacity="0" />
                </decoration>
            </decorations>
        </painter>
    </style>

To clarify - this is an XML description of component style that can used with styling branch WebLaF version. Since you are writing an OS - you most certainly will need some custom styles, so this might be a good thing to start with.

There are two ways to use any separate style for the component (like the one i've shown above):

  1. Provide it within a fully-implemented skin which can be described in XML - for example the default library light skin.xml, this way you can even change default component styles, but you will have to provide style definitions for all component types in your skin OR at least extend a skin that already has them.

  2. Provide it as a skin extension for existing skin - for example demo application uses extensions for providing custom styles it uses, here is its default light skin extension.xml. Unlike skin - skin extension doesn't require you to provide style definitions for all component types, you can provide only styles you need. The downside of using extension - you cannot change default component styles or styles that are defined in the extended skin.

Either of ways would work for you, but if you go with an extension - you will need to specify your custom style identifier (StyleId) whenever you create component that should use it. It is easy with Web* components as they have custom constructors for providing StyleId and a bit more tricky with common J* components - here is a small guide on how it can be done.

You can check how demo application uses skin extensions in demo module sources:

mgarin commented 6 years ago

Problem 2: Some internal frames always grow whenever you try to resize them (never shrink). Notice the big window in the background which basically only contains a JTextArea in a JScrollPane. Other PLAFs allow these same windows to be resized normally.

I'm not really sure what might cause that or how exactly it can be reproduced - can you provide a short code example? It will help a lot to find out the cause of the problem.

stefan-reich commented 6 years ago

Thanks for the detailed answer!

Sorry for calling WebLAF "sluggish", it sounds very negative. It is perfectly usable, just not as snappy as other LAFs in my case. The transparent frames may really have something to do with it.

I will try to make an example case for the resizing thing.

stefan-reich commented 6 years ago

I totally take back the "sluggishness" comment - I'm sure it's only about resizing JInternalFrames (which I do a lot).

stefan-reich commented 6 years ago

Bug demo program is here. It's in my Java dialect JavaX, but should be readable as Java too. If in doubt, you can also click on the "Pure Java version" link.

mgarin commented 6 years ago

Thanks for the sample code! I will try it out tomorrow and see what exactly happens there.

And no problem, I know better than anyone that UI performance can fall into unacceptable range pretty easily due to multiple things and sometimes it is hard to track all possible cases. At this point I've already fixed countless rendering bottlenecks in the code and will keep improving UI performance along the way, so if you see any kinds of performance drops or unhealthy delays - don't hesitate to report them here :)

Also sorry for late response, for some reason GitHub ate a few days of notifications, so I wasn't aware about the updates.

stefan-reich commented 6 years ago

Wow you're a nice guy.

Just saying :)

A general comment: I see that WebLAF offers many cool extra components over Swing, so I would like to use it... I'm just not sure if I should commit to a single LaF like that. It's so nice to be able to switch LaF at will.

Many greetings

mgarin commented 6 years ago

Whether you should commit to some specific components and/or L&F library (like WebLaF, Jide, SwingX etc) or simply use multiple L&Fs with default Swing components depends on whether or not you actually need any of those extended features for your application.

If you don't - then going with one or multiple L&F libraries might be better as it will not tie you anyhow to those libraries and you will be free to switch to another one whenever you decide to without making any major code adjustments.

But if you do really need more components than default Swing offers - then you might find it problematic to use extended component libraries with multiple L&Fs as those extended components most probably will not be supported.

kirill-grouchnikov commented 6 years ago

Adding my personal 2 cents here from the perspective of a fellow L&F and a component set developer (Substance / Flamingo).

Swing is effectively dead as far as new components / major functionality going into the core of it. Third-party component ecosystem has very few active players. JIDE seems to be in maintenance mode (based on http://www.jidesoft.com/history/index.php#3.7.4), SwingX is long dead, and the only third-party look-and-feels that are still being actively developed are Synthetica, WebLaF and Substance.

As for non-core / third-party components, there was never a really good story of how to do those in a way that would play relatively well with core and third-party look-and-feels. SwingX tried going with add-on model which worked decently with core LAFs. JIDE do their own thing. Synthetica has their own components http://www.jyloo.com/syntheticaaddons that seem to be only playing with their look-and-feel. And recently I've made a decision to switch Flamingo to be Substance-only.

I think that this is a combination of two things - the effective freeze of core Swing development, and the continuing shrinking of Swing ecosystem in general. On top of that, I would venture to say that allowing the user to change the entire appearance of the app is an outdated model. The world at large (TM) has pretty much settled on light-vs-dark skinning (see IntelliJ IDEA for example), and the Swing model of allowing you to completely change the appearance at runtime has not proven itself to be a big hit.

I would suggest making the choice as the developer, as far as selecting the specific look-and-feel. The unfortunate, but realistic choice, would also include the selection of third-party components that come from the same company that makes that LaF (be it Synthetica, WebLaF or Substance).

Endogen commented 6 years ago

I actually can't add anything valuable to this discussion but... wow, never thought that i would see Kirill crossing paths with Mikle in an github issue xD

Sorry for this comment - please just delete it from your brain ;) never happened

stefan-reich commented 6 years ago

@Endogen So you think there is some kind of chasm between LaF developers? Anyway I was actually surprised too. :)

I still very much like the idea of switching look&feels whenever I (or the users) feel like it. After a long Substance phase, I am currently using JTattoo in production and eyeing WebLAF. JTattoo has an Apple-ish theme which is gorgeous IMO. However, I mailed the author about a tiny problem (top pixel row of fullscreen menus not clickable), but haven't gotten any response yet.

It's sadly too hard to write your own look&feel (and get it fast & reliable), so that's why we're not seeing more of those. Still, I maintain that the concept is really cool.

Endogen commented 6 years ago

There is no chasm whatsoever. I'm just surprised that Kirill is following WebLAF.

Personally i don't care about switching LaFs. Since i'm a perfectionist there is no way you can have two LaFs and display them both perfectly IMO. At least not without a significant effort.

I used JTattoo about 10 years ago but didn't use it long since i don't think it's looking good. I'm kind of amazed that it is still around. Last change was end of 2014. Personally i wouldn't touch it in 2018.

I liked Substance (and then Insubstantial) for a while but then found WebLAF and never looked back. It's just the ultimate thing if you ask me.

It is really well done, active, the main developer cares about stuff you report and it works. Only thing i can't wrap my head around is the release stuff. It's just a shame that people actually think that the project is history because there wasn't an official release since 2015... That's just bad lifecycle management if you ask me... I understand the reason for it but can't agree that this was the only way to go. But other then that, no way i'm going to use anything else.

kirill-grouchnikov commented 6 years ago

There was a time when switching skins in WinAmp was all the rage. That was around when Swing had around a dozen active look-and-feels. There was also a time when Linux on desktop was promised to become a thing, and the rage was downloading and installing custom distribution-specific skins from DeviantArt. These are pretty much the only two examples that I can think of where people are willing to not only tweak the surface of the UI, but are also willing to live with completely different metrics for the UI (fonts, margins, paddings, insets, etc) while doing so.

I'm looking at the modern desktop, web and mobile offerings, and the most I see is tweaking a few colors here and there as user preferences. There might be something like cozy / comfortable / compact mode in gmail that tweaks margins in a specific part of the window. Or selecting the main article font for various reading apps that drop you into the fullscreen immersive mode. But otherwise I don't see designers willing to let the users make such drastic changes in the UI as a complete change of look-and-feel.

Which brings me to another part of modern, polished UIs. Using the default appearance of the specific look-and-feel is just the beginning. There is a ton of work that goes into making sure that everything looks consistent across the entire surface of the app, and that only comes from a deep integration with the APIs / configuration options exposed by the specific look-and-feel. Be it Synthetica that goes the route of client properties, Substance / Radiance with APIs, WebLaF with XML-driven appearance configuration or the couple of others that seem to be losing steam (JIDE / JGoodies), I just don't see how a well-designed app can withstand a switch at the level of changes "available" at what Swing allows you to do with look-and-feels.

mgarin commented 6 years ago

Wow, I've been shortly away and missed a lot here! So let me throw my "two cents" into the discussion :)

And sorry for so many quotes, but hopefully they make it a bit easier to see what I am referencing. Here goes wall of text!


I am generally agree with @kirill-grouchnikov on almost all points mentioned:

Swing is effectively dead as far as new components / major functionality going into the core of it

Third-party component ecosystem has very few active players

As for non-core / third-party components, there was never a really good story of how to do those in a way that would play relatively well with core and third-party look-and-feels

This is all true. Before I even started working on earliest WebLaF prototypes - we've already been struggling with 3rd-party software and core Swing in many cases. That was one of the reasons I started WebLaF in the first place - solutions that were available were not enough, not even close sometimes.

We were using Jide a lot for our internal projects, but Jide has quite a few issues of their own and it was REALLY hard to do anything about any problems we would find as it would take months after report to get some sort of solution as they were initially closed-source only (if I'm not wrong?) - now they do have some core parts open-sourced, but that doesn't fully solve the problem.

So I was writing WebLaF and slowly improving it over years, but only like a year and half ago we started actively replacing Jide with WebLaF's styling branch version and eventually it gave us some really good results. There are obviously issues with WebLaF as well, but at least we are fully in control of whats happening now and it is much easier to find any UI issues :)

@kirill-grouchnikov As for non-core / third-party components, there was never a really good story of how to do those in a way that would play relatively well with core and third-party look-and-feels. SwingX tried going with add-on model which worked decently with core LAFs. JIDE do their own thing. Synthetica has their own components http://www.jyloo.com/syntheticaaddons that seem to be only playing with their look-and-feel. And recently I've made a decision to switch Flamingo to be Substance-only.

Never got really deep into SwingX back in the days and later on it seemed to lack any kind of support, so we didn't risk using it. Jide, as I already mentioned above, worked for us for a long time but was still lacking sometimes and was hard to re-style. Synthetica have some shenanigans going on with the commercial licence price, won't go too deep into details here but it would basically end up being not worth to use and it also lacked quite a few components we needed that Jide had. Substance was attractive and I think we even tried to use it for a short time, but it was hard to combine with 3rd-party libraries and it also missed extra components (as did most of L&F-only libraries). There is also BizLaf that seem to be a solution somewhat similar to Synthetica, but it also has similar issues.

Basically everything came down to the fact that you either run with core Swing + any L&F (or mix of) OR any library with its own components and styling for them and core Swing stuff. The former is good until you actually need to use something extra (a tree table, a collapsible pane, a dockable framework etc) that is not in the core Swing. The latter ties you a lot to the way it works and it might prove to be a bad choice in the future in case of lack of support/components/features/etc.

@kirill-grouchnikov I think that this is a combination of two things - the effective freeze of core Swing development, and the continuing shrinking of Swing ecosystem in general. On top of that, I would venture to say that allowing the user to change the entire appearance of the app is an outdated model. The world at large (TM) has pretty much settled on light-vs-dark skinning (see IntelliJ IDEA for example), and the Swing model of allowing you to completely change the appearance at runtime has not proven itself to be a big hit.

I agree, but I would add a small bit to this part, just to clarify - runtime switching of multiple themes (L&Fs in case of Swing) might indeed be almost never needed and having just a few theme choices (mostly light and dark) should suffice most end users of any application. That being said I still think that it is really important for L&F library to provide developers of the said application with tools to customize those themes as much as it is possible as every application in a perfect case scenario should have at least a bit of personality to it. Although that probably goes without saying :)

@kirill-grouchnikov I would suggest making the choice as the developer, as far as selecting the specific look-and-feel. The unfortunate, but realistic choice, would also include the selection of third-party components that come from the same company that makes that LaF (be it Synthetica, WebLaF or Substance).

This is actually something I strongly agree with, but try not to emphasize too much. I think you can always avoid doing this hard choice to some extent.

But it is true that as soon as you "dive deep" into using any non-core Swing components and/or UI customization - you are, unfortunately, bound to make that choice.

mgarin commented 6 years ago

@Endogen I actually can't add anything valuable to this discussion but... wow, never thought that i would see Kirill crossing paths with Mikle in an github issue xD

I don't think it is so impossible, I would even say that the fact we never crossed before in the issues is surprising because as @kirill-grouchnikov said - the ecosystem around L&Fs is really small and we probably know about each other for a very long time now :)

And I certainly don't think there is any chasm there :)

@kirill-grouchnikov I still very much like the idea of switching look&feels whenever I (or the users) feel like it. After a long Substance phase, I am currently using JTattoo in production and eyeing WebLAF. JTattoo has an Apple-ish theme which is gorgeous IMO. However, I mailed the author about a tiny problem (top pixel row of fullscreen menus not clickable), but haven't gotten any response yet.

I like switching L&Fs as well, but sadly it doesn't always work well with highly-customized applications.

Another thing you reminded me about - its actually been quite a while since I checked any other L&Fs (had two really busy years of web development, ugh), so I'm a bit out of the loop - I should really take a look once again.

And about WebLaF - hold tight, there will be a bunch of themes coming out as soon as I'm done with the last few components (damn those three cursed ones!) and will finally release that styling branch version. Maybe some of those themes will appeal to you :)

@kirill-grouchnikov It's sadly too hard to write your own look&feel (and get it fast & reliable), so that's why we're not seeing more of those. Still, I maintain that the concept is really cool.

It is hard and might not be ever worth it anymore for companies that don't already have some sort of solution of their own. So I also doubt we will see any more L&Fs appearing out there unless someone is really passionate about Swing and would want to create his own new L&F (or extend an existing open-source one).

mgarin commented 6 years ago

@Endogen It is really well done, active, the main developer cares about stuff you report and it works. Only thing i can't wrap my head around is the release stuff. It's just a shame that people actually think that the project is history because there wasn't an official release since 2015... That's just bad lifecycle management if you ask me...

Yes, this is mainly my fault. I am also quite a perfectionist and often get carried away whenever I dive into any kinds of changes and might go over the top while only a small change would have been sufficient. And the other problem is simply free time, but I try to squish it here and there between projects and on the vacation to get major changes out.

And well, I should have gone with multiple versions throughout the years instead of piling all of the changes into one ultimate update, but sadly I realised that a few years too late.

Luckily some of my new colleagues are helping me out with WebLaF and some organizational aspects, so there will surely be improvements on that front.

In any case - don't worry, as I said multiple times before - I will not abandon this project and will make sure it lives for many more years. And gets new features and updates of course. Even with all the FX hype and new things coming along - I still believe that Swing has a stong place in desktop applications development, it just needs a good push in the right direction.


And about the last @kirill-grouchnikov message (shortened, just for reference) -

There was a time when switching skins in WinAmp was all the rage ...

That is actually a really good explaination why you might have to choose a specific L&F at some point, I certainly can't phrase it better. That might actually be a highlight of this whole discussion here :)

mgarin commented 6 years ago

@stefan-reich I almost forgot to comment on this issue topic (problem with JInternalFrame size) - I found the source of the problem - there are some shenanigans going on with the preferred size returned by the UI, probably I missed something important when I was porting JInternalFrame to the new styling scheme.

I will most probably commit a small fix tomorrow from the office and I'll come back and comment here again when that fix is available in git/snapshot repo.

stefan-reich commented 6 years ago

I found the source of the problem

Very cool!

mgarin commented 6 years ago

@stefan-reich Fix was a bit trickier than I expected, but it worked out well as it actually fixed another old internal problem I had with WebInternalFrameUI implementation. I've pushed this fix to styling branch and new snapshot artifacts are now also available, so you can try it out to see if it works as intended now.

Resize should now be working as intended: image image

And minimum size should be exactly the header of the JInternalFrame plus style insets: image

mgarin commented 6 years ago

@stefan-reich And once more on the UI being sluggish - I took a few quite heavy UIs from another app and put them into multiple JInternalFrame copies to try it out. Result wasn't too bad, but there are surely some delays whenever you resize the frames (dragging frames, working with their content or resizing the desktop pane works perfectly fine), but that unfortunately is quite a heavy operation and its speed mostly depends on the "heaviness" of the UI inside of the resized JInternalFrame. You might see similar issues when working with WebDockableFrames and resizing them. Or generally when resizing windows with "heavy" UI placed on them.

The solution I offered above might still help a bit (re-styling the frame a bit), but I wouldn't rely put too many hopes into it as it will only cut a bit of time from resize and drag operations.

kirill-grouchnikov commented 6 years ago

If I might budge in once again and recommend looking at https://github.com/kirill-grouchnikov/lightbeam

I use it to keep track of regressions in Substance between releases, as well as comparing it to the performance of core look-and-feels. There are about 20-25 different scenarios that are being tested, and it should be relatively straightforward to add more as needed for particular "heavy" cases for before/after tests.

mgarin commented 6 years ago

@kirill-grouchnikov Sounds neat, I will surely give it a try! :) I'm also slowly working on some basic tools to debug UI and measure performance, but at this point its not really anywhere close to automating anything, but mostly are just tools to peek at UI structure and raw rendering performance in runtime since that is always really annoying to do even in debug.

mgarin commented 6 years ago

@kirill-grouchnikov Since I was really curious - I ran a few tests using lightbeam on three L&Fs, here are some results:

image

Setup/environment was:

WebLaF was a bit sloppy on a few things and did fall behind two other L&Fs. Although generally I was expecting it to perform a bit worse on this kind of test because it has sort of a warm up time due to multiple internal caches for the styles and decorations, but it seems that those did not affect the final results too much and instead allowed WebLaF to go ahead on some times. And yes, I never really directly worked on improving WebLaF performance, but it will surely be my focus after I finish up the current release.

Nimbus was seemingly the fastest of all three which is not surprising considering its code. If you never checked it - it basically does raw case-based painting for most of the components and also has quite a few of internal caches to keep things in check. But it is kind of impossible to understand what is happening in its code and it was surely not intended to be modified anyhow, so you can probably only use it "as is" which is a big minus.

And Substance L&F was really close to Nimbus performance-wise but I did get a few stutters on some elements (according to test it was the menu bar) so it fell just a little bit behind on overall time. But it surely wins over WebLaF performance-wise at this point. Also I'm not sure - is there is any difference between different Substance themes?

Overall - this was just a quick test and I will surely do some more research (probably later this week) to see if there will be any major performance difference between platforms, OS and JDK versions, but nonetheless - lightbeam is an interesting approach to measure UI performance :)


On WebLaF side - I basically only have a HeatMap tool which I made some time ago.

Right now it can only display rendering time of each square on the UI in runtime, you can find its usage example in demo application:

image

It might not be completely representative and has a few issues, but it does give you a general idea of what might be slowing your UI down, from there it is not too hard to find out what causes painting to slow down.

One thing I will add to it soon is an alternative option to display rendering speed for each separate component separately instead of using abstract squares.

stefan-reich commented 6 years ago

Dear @kirill-grouchnikov from the Android team,

I have to get these things off my chest.

  1. I used to work at Google. I quit in 2009 because they wanted to kill me (virtually).

  2. I make an operating system in Java that is ALL THAT ANDROID SHOULD HAVE BEEN.

  3. I tried to install WhatsApp on a friend's Android phone yesterday and IT SIMPLY DID NOT WORK.

3b. I got kicked off the Play Store because I dynamically load code from un-servers (non-Google-servers). So it's a fight? Guess who'll win.

  1. In my Java OS, ALL MODULES RUN IN ONE VM AND IT'S NOT A PROBLEM.

4b. No, the Java process does not get "wonky" over time as misinformed programmers baselessly claim. They just have more deadlocks than I do (my deadlocks are fixed by the OS).

  1. I have an idea for a better Swing PLAF interface. Just two components: a painter and a "clicker" (event handler). Easy & really transparent.

  2. My OS has orthogonal persistence which is... slightly easier than your persistence approach.

Cheers.

Stefan

kirill-grouchnikov commented 6 years ago

I haven't run the Lightbeam suite on a Windows machine, only on a Mac. I'm not surprised to see the rather bad performance of Substance menus on Windows - that's the code from JGoodies Looks that adds emulated drop shadow border to all the menus. It's bypassed on the Mac. I'm willing to accept that penalty for the better look of the open menus - which are not usually critical for the overall UI performance.

As for Substance skins - unless there's a custom painter set on the current skin that does heavy computation or image manipulation, there shouldn't be any measurable difference between skins that are shipped as part of the core Substance binary.

And Lightbeam is set up in the way to minimize the initial warm up of image caches. When I first started with Lightbeam, I used it as a rough overview of performance issues. It pointed me to the Substance UI delegates that were the slowest compared to the core Metal / Nimbus, and then I dove in to identify the specific bottlenecks in painting / event handling / animations.

I do like the heat-map idea. Not sure if using nanoTime is very reliable though. That is why I'm using the aggregate info from ThreadMXBean in https://github.com/kirill-grouchnikov/lightbeam/blob/master/src/org/pushingpixels/lightbeam/DynamicPerformanceSuite.java. It's been a while though since I wrote that code, so it might be time to take another look at what is the best way today to measure code performance on Java 9/10/11.

mgarin commented 6 years ago

I haven't run the Lightbeam suite on a Windows machine, only on a Mac. I'm not surprised to see the rather bad performance of Substance menus on Windows - that's the code from JGoodies Looks that adds emulated drop shadow border to all the menus. It's bypassed on the Mac.

That actually makes sense if shadow is not cached anyhow.

On Mac, in theory, you shouldn't ever need to do any custom shadows as you can always incorporate native ones, but I didn't go with those for styling convenience (at least yet - might end up using them in the final polished skins), plus per-pixel translucency works fine on all Mac OS X versions, so you generally can do any kinds of shadows you want as long as they are more or less optimized.

As for Substance skins - unless there's a custom painter set on the current skin that does heavy computation or image manipulation, there shouldn't be any measurable difference between skins that are shipped as part of the core Substance binary.

I see, just asked to be sure I can pick any skin for the performance tests :)

And Lightbeam is set up in the way to minimize the initial warm up of image caches. When I first started with Lightbeam, I used it as a rough overview of performance issues. It pointed me to the Substance UI delegates that were the slowest compared to the core Metal / Nimbus, and then I dove in to identify the specific bottlenecks in painting / event handling / animations.

For WebLaF biggest bottleneck right now is startup time (L&F installation), after that there is a lot of lazy initialization going on, but all of it barely affect performance - only memory usage. So once L&F is initialized it should work at about the same performance as other L&Fs or just a slight bit slower depending on specific UI and Painter implementations.

L&F initialization might take up to 1.5-2 seconds on JDK 6, up to 0.5-1.5 seconds on JDK 7 or 8 and generally takes less than 0.5 seconds on JDK 9 and later (it seems they actually did a lot of optimization behind the scene). All that time mostly goes into reading style XML files and parsing them into final style objects used by components (about 50/50 for each of operations). I've got some ideas about how that time can be cut, but it will take a while to implement those, so thats more of a long-term goal.

And a side note about Lightbeam and what else can be used for benchmarking - UI components initialization time. It still plays a big role in application performance if you have a lot of lazy UI parts which are created on-demand (popups, menus, dialogs etc). But I'm not really sure how you can reliably instantiate all Swing components - I guess it have to be a custom thing for each core Swing component as you might want to test every single constructor separately to see if there are any big bottlenecks there as well.

I do like the heat-map idea. Not sure if using nanoTime is very reliable though. That is why I'm using the aggregate info from ThreadMXBean in https://github.com/kirill-grouchnikov/lightbeam/blob/master/src/org/pushingpixels/lightbeam/DynamicPerformanceSuite.java. It's been a while though since I wrote that code, so it might be time to take another look at what is the best way today to measure code performance on Java 9/10/11.

Hard to say for sure, but the numbers I've been getting from nanoTime made sense and were more or less representative of what was happening in the UI, at least as long as you filter out extra time of GC operations. But if ThreadMXBean can actually give cleaner results - I can surely make use of it instead.

Also current heat map does an extra run on the squares it finds suspiciously slow or fast and takes the extra run result - that is a pretty "lame" approach but it does give surprisingly good results. One more thing - heat map doesn't normalize displayed values, but such normalization would certainly help seeing a better overall picture over a few full iterations, so that is something I will be adding later as an option.

mgarin commented 6 years ago

I'll be closing this issue since original problem should be solved now, but feel free to reopen it if something is still off.