非顶级窗口中的非透明JButton背景变得不透明?

afk*_*min 7 java user-interface swing synth jwindow

在您阅读之前,这里有一些关于问题的澄清:

  1. SSCCE是为Java 7设计的.可以使用sun.*.AWTUtilities使其适应Java 6,但对我来说它在Java 6上是如何工作并不重要.
  2. 断层线是[...]new JDialog(someWindow).重影可被固定在SSCCE 通过简单地改变该行[...]new JDialog().

为什么顶级窗户没有重影?


预期行为:( final JDialog d = new JDialog()见SSCCE) TL和非TL窗口都具有半透明背景

如您所见,右侧窗口具有半透明背景(如预期的那样).

实际行为:( final JDialog d = new JDialog(f)见SSCCE) TL窗口显示半透明背景,而非TL背景即使在单次重绘后也变得不透明

在这种情况下,右侧窗口具有不透明背景.事实上,由于任何原因(最容易重现,在翻转时重新绘制)需要3-4次重绘,以使背景变得完全不透明.


SSCCE:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.synth.ColorType;
import javax.swing.plaf.synth.Region;
import javax.swing.plaf.synth.SynthConstants;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthLookAndFeel;
import javax.swing.plaf.synth.SynthPainter;
import javax.swing.plaf.synth.SynthStyle;
import javax.swing.plaf.synth.SynthStyleFactory;

public class SynthSSCCE
{
        public static void main(String[] args) throws Exception
        {
                final SynthLookAndFeel laf = new SynthLookAndFeel();
                UIManager.setLookAndFeel(laf);
                SynthLookAndFeel.setStyleFactory(new StyleFactory());

                SwingUtilities.invokeLater(new Runnable()
                {
                        @Override
                        public void run()
                        {
                                final JFrame f = new JFrame();
                                {
                                        f.add(new JButton("Works properly"));
                                        f.setUndecorated(true);
                                        f.setBackground(new Color(0, true));
                                        f.setSize(300, 300);
                                        f.setLocation(0, 0);
                                        f.setVisible(true);
                                }
                                {
                                        final JDialog d = new JDialog(f);
                                        final JButton btn = new JButton("WTF?");
                                        // uncomment and notice that this has no effect
                                        // btn.setContentAreaFilled(false);
                                        d.add(btn);
                                        d.setUndecorated(true);
                                        d.setBackground(new Color(0, true));
                                        d.setSize(300, 300);
                                        d.setLocation(320, 0);
                                        d.setVisible(true);
                                }
                        }
                });
        }

        static class StyleFactory extends SynthStyleFactory
        {
                private final SynthStyle style = new Style();

                @Override
                public SynthStyle getStyle(JComponent c, Region id)
                {
                        return style;
                }
        }

        static class Style extends SynthStyle
        {
                private final SynthPainter painter = new Painter();

                @Override
                protected Color getColorForState(SynthContext context, ColorType type)
                {
                        if (context.getRegion() == Region.BUTTON && type == ColorType.FOREGROUND)
                                return Color.GREEN;

                        return null;
                }

                @Override
                protected Font getFontForState(SynthContext context)
                {
                        return Font.decode("Monospaced-BOLD-30");
                }

                @Override
                public SynthPainter getPainter(SynthContext context)
                {
                        return painter;
                }

                @Override
                public boolean isOpaque(SynthContext context)
                {
                        return false;
                }
        }

        static class Painter extends SynthPainter
        {
                @Override
                public void paintPanelBackground(SynthContext context, Graphics g, int x, int y, int w, int h)
                {
                        final Graphics g2 = g.create();
                        try
                        {
                                g2.setColor(new Color(255, 255, 255, 128));

                                g2.fillRect(x, y, w, h);
                        }
                        finally
                        {
                                g2.dispose();
                        }
                }

                @Override
                public void paintButtonBackground(SynthContext context, Graphics g, int x, int y, int w, int h)
                {
                        final Graphics g2 = g.create();
                        try
                        {
                                if ((context.getComponentState() & SynthConstants.MOUSE_OVER) == SynthConstants.MOUSE_OVER)
                                        g2.setColor(new Color(255, 0, 0, 255));
                                else
                                        g2.setColor(new Color(0xAA, 0xAA, 0xAA, 255));
                                g2.fillRoundRect(x, y, w, h, w / 2, h / 2);
                        }
                        finally
                        {
                                g2.dispose();
                        }
                }
        }
}
Run Code Online (Sandbox Code Playgroud)

这些是我的问题......

  1. 到底是怎么回事?就像在,为什么这会展示一个忘记调用super的自定义绘制非不透明组件的行为?
  2. TL窗口为什么不会发生?
  3. 除了不使用非TL窗口之外,最简单的修复方法是什么?

cam*_*ckr 1

由于任何原因(最容易重现的是翻转时重新绘制),需要重新绘制 3-4 次,背景才会变得完全不透明。

查看具有透明度的背景,这应该能让您对问题有一些了解。

我从未使用过 Synth,所以我不知道相同的解决方案是否有效。