0

I'm having a serious performance issue using a JLayer to do special drawing, but only under the AquaLookAndFeel on Macintosh. Using any other look and feel, the performance is fine.

Here's the scoop:

I have a test case that blurs the main window when a child dialog pops up above it. On most L&Fs it works fine. On Aqua, it takes five seconds to draw, and the screen is frozen the whole time. I can press OK to dismiss the dialog, but it doesn't respond until it's done drawing. And the reason it takes so long to draw is because Aqua is firing multiple paint events. For every component that might change its visual state, it fires a paint event. So it redraws the entire window, using the blur effect, once for each of the twelve JButtons or Checkboxes in the window. The blur effect takes about one third of a second to draw, but it takes about 5 seconds with all the repaints.

Under any other look and feel, only two paint events are fired, so the performance is acceptable.

To see this in action, run the test case at https://github.com/SwingGuy1024/Bugs/blob/main/AquaPaintBug.java

It lets you try it under different looks-and-feels. It runs fine on all but Aqua.

Has anyone else seen this? Does anyone know of a workaround? Is this a bug in Aqua, or am I missing something? If I can't use JLayer to enhance the drawing of a component, the JLayer is useless for drawing.

Note: I think this is partly caused by a PropertyChangeListener that gets set by the AquaRootPaneUI class, on a property called AquaFocusHandler.FRAME_ACTIVE_PROPERTY, which is defined as "Frame.active". This seems to get activated when the window's active state changes, which is what happens when a dialog opens up. This explains why it repaints all the JCheckBoxes, but doesn't explain why they each get a separate paint event.

MiguelMunoz
  • 4,548
  • 3
  • 34
  • 51
  • My suggestion would be to only paint to the offscreen when turning the blur mode on. If you only use the blur effect when showing a modal dialog then it is safe to assume that the frame won’t change its size or content. – weisj Oct 10 '21 at 15:25
  • @weisj Well, that was a very clever suggestion. While this does fix he delay, it has two unfortunate consequences. First, it fails to repaint the button I pressed to launch the message. This happens on any L&F. This is probably because that component goes from focussed to unfocussed, and needs repainting. Second, only on the Mac, it fails to paint any of the buttons or checkboxes. I think they're all getting invalidated, which is why they need to be repainted. I've been trying to fix this but it doesn't look promising. – MiguelMunoz Oct 10 '21 at 21:19
  • @weisj BTW, would you agree that this is a bug in the Aqua L&F? – MiguelMunoz Oct 11 '21 at 00:42
  • Components not being painted at seems very weird to me. Though the button still being focused should be avoidable by simply changing the blur state in SwingUtilities#invokeLater to ensure it happens after focus has moved to the dialog. Sadly I don't have easy access to a Mac so I can’t debug the problem myself. – weisj Oct 11 '21 at 13:02
  • At first, it looked like your fix worked. But when I tried it in an actual application, it didn't work. I don't yet know why it works in the test case but not in the application, but when I figure it out, I may need to revise my test case. This isn't over. – MiguelMunoz Oct 14 '21 at 09:36
  • I have since realized that one reason why this is only an issue with Aqua is that Aqua is the only L&F that paints the checkboxes one way when the window has the focus, and another way when it doesn't. This hasn't led me to a solution yet, but I'm still looking. – MiguelMunoz Apr 30 '22 at 10:10

0 Answers0