Insubstantial / insubstantial

Swing look-and-feel library and assorted widgets
195 stars 57 forks source link

JDesktopPane receive too many repaint event when using RibbonFrame with Substance LAF. #64

Closed Stephane-D closed 12 years ago

Stephane-D commented 12 years ago

Ok i edited the issue since i have more informations about it now. The DesktopPane is entirely painted when it should not and this cause some severe slowdown in application. It happens only when you use a RibbonFrame with Substance look and feel (and so may be localized in substance-flamingo part of the library). This bug was not existing when the new rounded border feature was absent.

I wrote an eclipse project which make the problem to happen : http://www.bioimageanalysis.com/icy/download/temp/BugSubstance.7z

Just active the JInternalFrame, when you have the default system look and feel there is no problem, but as soon you select the substance look and feel you will see the desktop repaint event to happen very often (there is a counter), even a simple mouse move over an acitve component in the JInternaFrame make the repaint to happen.

I also noted that if we switch back to system look and feel, the update problem partially persist, it looks like the painter manager is somewhat messed up...

shemnon commented 12 years ago

You can turn off the rounded corners with a command line switch:

-Dsubstancelaf.windowRoundedCorners=False

Also, are you running aero or windows 7 basic? Or over a VPN?

Stephane-D commented 12 years ago

I was running Windows 7 Aero, rounded corners looks really great and it would be nice to keep it enable :) and anyway even with that feature disabled it does not make any changes, we still have complete JDesktopPane repaint... I also tested with classic windows them, same problem. This bug was not present in early version of insubstantial where the round corners features was absent.

Stephane-D commented 12 years ago

Updated the issue with complete description and test case.

shemnon commented 12 years ago

The issue was that the JInternalFrames need to be non-opaque to get the non window portions of the rounded corners to "bleed through." However, setting the corners to square did not intiially fix it. So I changed some code to toggle the opaqueness based on the squareness, and to listen to things that will change the squareness.

To verify, I altered the code to create the simpleframe and demonstrate the squareness fixes.

 SimpleFrame f = new SimpleFrame();
 window.customDesktopPane.add(f);
 f.setTitle("Square");
 f.setLocation(10, 10);
 f.setSelected(true);
 f.putClientProperty(SubstanceLookAndFeel.WINDOW_ROUNDED_CORNERS, false);
 f = new SimpleFrame();
 window.customDesktopPane.add(f);
 f.setTitle("Round");
 f.setLocation(10, 175);
 f.setSelected(true);

The putClient Property line makes the window always square, and the maximizability make it so the squareness is detected on maximize as well.

Stephane-D commented 12 years ago

Indeed passing to JInternalFrame to opaque = true does fix the problem but i believe that is not the only source of the problem here (and this does not fix the problem where rounded corners are enabled).

The bug happen only when you use a JRibbonFrame and Substance LAF at same time, JRibbonFrame or Substance alone are not impacted. Also we can say that is a bug because there is no reason that a non opaque JInternalFrame requires complete DesktopPane repaint when one of its internal opaque component is repainted.

Stephane-D commented 12 years ago

I made more tests, it seems that JRibbonFrame alone already made more refresh than expected when JInternalFrame is transparent (when the caret of an internal JTextField is blinking) but it is worst when we use it in conjunction with Substance (even a single mouse move on active component make a complete repaint to happen).

I saw the JRibbonFrame uses a KeyTipLayer component to display KeyTip the JRibbonFrame. When we remove the KeyTipLayer from JRibbonFrame the problem disappears. It seems the KeyTipLayer uses a fake transparent (opaque = false) JComponent on the whole desktop JLayeredPane pane and this is the source of the problem :-/ Unfortunately i do not see an easy way to fix that JRibbonFrame behavior... right now i'm just removing KeyTipLayer component from the JLayeredPane as i don't really need it.

shemnon commented 12 years ago

I am adverse to placing anything in the glass pane in particular, because many apps replace the glasspane with something of their own, so it's an invitation to problems.

I'd rather do something else to fix it, such as (a) we could setVisible(false) when it's not in use (b) trim the size of the layer to cover just the ribbon. Covering the whole frame seems excessive. or (c) implement the KeyTipLayer as part of a JLayer (java7 api) for the JRibbon itself. On Wed, Feb 29, 2012 at 6:33 AM, Stephane Dallongeville < reply@reply.github.com

wrote:

I made more tests, it seems that JRibbonFrame alone already made some more refresh than expected but it is worst when we use it in conjunction with Substance.

I saw the JRibbonFrame uses a KeyTipLayer component to display KeyTip the JRibbonFrame. When we remove the KeyTipLayer from JRibbonFrame the problem disappear. It seems the KeyTipLayer uses a fake transparent (opaque = false) JComponent on the whole JLayeredPane pane to render Ribbon tips and this is the source of the problem :-/ I do not know a way to fix that JRibbonFrame behavior... may be the KeyTipLayer should be placed in the GlassPane instead of the LayeredPane.


Reply to this email directly or view it on GitHub:

https://github.com/Insubstantial/insubstantial/issues/64#issuecomment-4237436


"But you didn't." - Jim Halpert, The Office S05E23

Stephane-D commented 12 years ago

Yeah you're right, i edited my message as GlassPane is definitely not the solution. Right now i'm hidding the KeyTipLayer component, this is enough to avoid the repaint... But indeed i don't know why the KeyTipLayer dimension is set to the whole DesktopPane where the Ribbon component should be enough.

By the way i have a fork of insubstantial which is basically intended to be a custom version for our application. I added support to modify RibbonBand so we can now remove CommandButton / RibbonGallery / RibbonComponent from RibbonBand (we could only add new components before). Later i also plan to add support of removing / modifying RibbonBand or RibbonTask... I did these modifications as we need it for our application, i don't know if you plan to add that type of feature in insubstantial later but just wanted to let you know that i already made some stuff there.

We really appreciate the Substance / Flamingo library experience in our application and it is nice to see it in active development :) Keep up the great work !

shemnon commented 12 years ago

The ribbon mutability code would be useful. You are not the first person to mention it, Erich wants those features as well for his ribbon builder code. I'de have to dig deeper but I think write only APIs were merely a convience for Kirill as I don't think there are any side effects if done before the ribbon is 'frozen.'

On Wed, Feb 29, 2012 at 9:25 AM, Stephane Dallongeville < reply@reply.github.com

wrote:

Yeah you're right, i edited my message as GlassPane is definitely not the solution. Right now i'm hidding the KeyTipLayer component, this is enough to avoid the repaint... But indeed i don't know why the KeyTipLayer dimension is set to the whole DesktopPane where the Ribbon component should be enough.

By the way i have a fork of insubstantial which is basically intended to be a custom version for our application. I added support to modify RibbonBand so we can now remove CommandButton / RibbonGallery / RibbonComponent from RibbonBand (we could only add new components before). Later i also plan to add support of removing / modifying RibbonBand or RibbonTask... I did these modifications as we need it for our application, i don't know if you plan to add that type of feature in insubstantial later but just wanted to let you know that i already made some stuff there.

We really appreciate the Substance / Flamingo library experience in our application and it is nice to see it in active development :) Keep up the great work !


Reply to this email directly or view it on GitHub:

https://github.com/Insubstantial/insubstantial/issues/64#issuecomment-4240804


"But you didn't." - Jim Halpert, The Office S05E23

Stephane-D commented 12 years ago

Right now i only did modifications for the RibbonBand internals components which is probably the easiest but indeed i don't think there are unsolvable problems to add that for Task and Band themself. I remember Kirill mentioning the Ribbon was unmutable by "design"... i think it was referring more to the API than possible technicals issues.

shemnon commented 12 years ago

To add a quirk on the "by design" aspect the Microsoft writings on the ribbon state that while an application is running the only alterations to the ribbon should be via context tabs, analogous to the "frozen" field in some of the code.

On Wed, Feb 29, 2012 at 9:37 AM, Stephane Dallongeville < reply@reply.github.com

wrote:

Right now i only did modifications for the RibbonBand internals components which is probably the easiest but indeed i don't think there are unsolvable problems to add that for Task and Band themself. I remember Kirill mentioning the Ribbon was unmutable by "design"... i think it was referring more to the API than possible technicals issues.


Reply to this email directly or view it on GitHub:

https://github.com/Insubstantial/insubstantial/issues/64#issuecomment-4241115


"But you didn't." - Jim Halpert, The Office S05E23

Stephane-D commented 12 years ago

Yeah this is also that. Too bad MS designed Ribbon this way, why keep Ribbon static (context tabs is definitely different) where dynamic Ribbon would be totally awesome :D