Aqua Default Button Repaints

Jeremy Wood mickleness at gmail.com
Sat Nov 9 18:34:20 UTC 2024


The Aqua L&F is constantly repainting the default button, but I don’t 
think Aqua does that anymore.

Any objections to my putting in a ticket to remove this behavior, or at 
least to make it conditional on the Mac OS version?

I’m currently running Mac OS 15.1, and I have an old Mac running OS 
12.6.3: the default buttons in Apple apps don’t repaint anymore. I don’t 
know how to check exactly which Mac OS version this behavior changed.

(Context: based on discussions around JDK-8342782 or JDK-8165863 I was 
planning on submitting a ticket & PR to make 
AquaRootPaneUI#updateDefaultButton more performant. But now I think a 
better solution is just to purge that repaint code.)

Here’s a test app I ran using OpenJDK 23 on Mac 15.1 that demonstrates 
that the default button is constantly repainting needlessly when the app 
is in the foreground:

import javax.swing.*;
import java.awt.*;

public class DefaultButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
class RepaintButton extends JButton {
RepaintButton(String text) {
super(text);
                     }

@Override
public void paint(Graphics g) {
                         g.setColor(new Color((int)(Math.random()*0xffffff)));
                         g.fillRect(0,0,getWidth(),getHeight());
super.paint(g);
                     }
                 }

JDialog d = new JDialog();
JButton defaultButton = new RepaintButton("Default Button");
JButton button2 = new RepaintButton("Non-Default Button");
JPanel panel = new JPanel(new FlowLayout());
panel.add(defaultButton);
panel.add(button2);
d.getContentPane().add(panel);
d.getRootPane().setDefaultButton(defaultButton);
d.pack();
d.setVisible(true);
             }
         });
     }
}

------ Original Message ------
>From "Sergey Bylokhov" <serb at openjdk.org>
To client-libs-dev at openjdk.org
Date 11/7/2024 8:00:48 PM
Subject Re: RFR: 8342782: AWTEventMulticaster throws StackOverflowError 
using AquaButtonUI

>On Thu, 7 Nov 2024 17:49:29 GMT, Jeremy <duke at openjdk.org> wrote:
>
>>  The AWTEventMulticaster is a tree node with 2 children. This PR proposes rebalancing that tree after 500 additions to avoid potential StackOverflowErrors when trying to interact with a large AWTEventMulticaster.
>>
>>  In the original headful test:
>>  We added 8,000 checkboxes, and when their parent panel was hidden the stack needed to grow to 24,000 lines. It took 8,000 lines to recursively call `java.awt.AWTEventMulticaster.componentHidden`, and then 16,000 additional lines to call two recursive methods to remove a listener:
>>
>>  java.desktop/java.awt.AWTEventMulticaster.removeInternal()
>>  java.desktop/java.awt.AWTEventMulticaster.remove()
>>
>>
>>  With this current PR the max stack size reaches 1,267 instead. (If we rebalanced at EVERY addition, then that same scenario would reach a max stack size of 71.)
>>
>>  JDK-8342782 included a headful test case, but I think the main problem it demonstrated can be represented by the headless test case attached to this PR.
>>
>>  Depending on how this PR is received I may submit a separate ticket & PR to modify AquaButtonUI so it doesn't always attach an AncestorListener. (That is: if my GUI includes 8,000 checkboxes then I don't need 8,000 AncestorListeners.) But JDK-8342782's test case is currently written in a way that should reproduce across all L&F's, so that can be discussed separately.
>
>This bug and its test could be related: https://bugs.openjdk.org/browse/JDK-8165863
>
>-------------
>
>PR Comment: https://git.openjdk.org/jdk/pull/21962#issuecomment-2463540556


More information about the client-libs-dev mailing list