java 如何在完全透明的 JFrame 上创建部分透明的 JButton?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7373345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:42:47  来源:igfitidea点击:

How to create partly transparent JButton on fully transparent JFrame?

javaswingtransparencyjframejbutton

提问by Pete

I am able to make JFrame totally transparent and the JButton is partly transparent just fine until I move my mouse on the button ( do not click ) and move the mouse off from the button ( MouseExited called via MouseListener ). What happens is that the background of the JButton is drawn again, so after couple of mouse movements on and off the button the button is totally opaque.

我能够使 JFrame 完全透明,而 JButton 部分透明就好了,直到我将鼠标移到按钮上(不要单击)并将鼠标从按钮上移开(通过 MouseListener 调用 MouseExited)。发生的情况是 JButton 的背景再次被绘制,因此在按钮上和关闭鼠标几次移动后,按钮完全不透明。

public class ButtonExample extends JWindow
{
   public ButtonExample( )
   {
        JButton But = new JButton( "Testing" );
        But.setBackground( new Color( 0, 0, 0, 200 ) );
        But.setForeground( new Color( 70, 155, 255 ) );
        this.add( But );
        this.setBackground( new Color( 0, 0, 0, 0 ) );
        this.setMinimumSize( new Dimension( 200,100 ) );
        this.setVisible( true );
    }

    public static void main( String[ ] Args ) 
    {
        new ButtonExample( );
    }
}

回答by kleopatra

problem is that the button reports being fully opaque when in fact it isn't (due to the partially transparent color)

问题是按钮报告完全不透明,而实际上它不是(由于部分透明的颜色)

  but.setOpaque(false);

BTW: as you see I changed the field name to conform to java naming conventions :-)

顺便说一句:如您所见,我更改了字段名称以符合 java 命名约定:-)

Edit

编辑

arggghh .. missed that, sorry. Need to check what we do in SwingX, from the top of my head I would say you need to override paintComponent and handle the background painting yourself, like

arggghh .. 错过了,抱歉。需要检查我们在 SwingX 中做了什么,从我的头顶我会说你需要覆盖paintComponent并自己处理背景绘画,比如

        /** 
         * @inherited <p>
         */
        @Override
        protected void paintComponent(Graphics g) {
            if (!isOpaque() && getBackground().getAlpha() < 255) {
                g.setColor(getBackground());
                g.fillRect(0, 0, getWidth(), getHeight());
            }
            super.paintComponent(g);
        }

didn't try, though, maybe the "getting more opaque" is back again with doing so .. will come back tomorrow

不过没试过,也许“变得更不透明”又回来了……明天会回来

Edit 2

编辑 2

okay, checked - the edited code works correctly. So in summary: components with translucent background

好的,已检查 - 编辑后的代码可以正常工作。总而言之:具有半透明背景的组件

  • must report that they are not opaque to not confuse the default painting mechanism
  • must take over the background painting and fill it with the background color themselves (SwingX JXPanel f.i. does by explicit support for an alpha property)
  • 必须报告它们不是不透明的,以免混淆默认的绘制机制
  • 必须接管背景绘画并用背景颜色自己填充它(SwingX JXPanel fi 通过显式支持 alpha 属性来实现)

for your convenience, here's a small runnable with incorrect/correct background side-by-side

为方便起见,这里有一个小的 runnable 并排显示不正确/正确的背景

public class TransparentButton  {

    public TransparentButton() {
        JWindow incorrectOpaque = createWindow("incorrect opaque", true);
        incorrectOpaque.setLocation(600, 600);
        incorrectOpaque.setVisible(true);
        JWindow correctOpaque = createWindow("correct opaque", false);
        correctOpaque.setLocation(800, 600);
        correctOpaque.setVisible(true);
    }


    private JButton createButton(final boolean opaque) {
        JButton but = new JButton("Testing") {

            /**
             * @inherited <p>
             * Overridden to take over background painting with 
             * transparent color.
             */
            @Override
            protected void paintComponent(Graphics g) {
                if (!isOpaque() && getBackground().getAlpha() < 255) {
                    g.setColor(getBackground());
                    g.fillRect(0, 0, getWidth(), getHeight());
                }
                super.paintComponent(g);
            }

        };
        but.setBackground(new Color(0, 0, 0, 100));
        but.setForeground(new Color(70, 155, 255));
        but.setOpaque(opaque);
        return but;
    }

    private JWindow createWindow(String text, boolean opaque) {
        JWindow window = new JWindow();
        JButton but = createButton(opaque);
        window.add(but);
        window.add(new JLabel(""), BorderLayout.SOUTH);
        window.setOpacity(0.5f);
        window.setBackground(new Color(0, 0, 0, 0));
        window.setSize(new Dimension(200, 100));
        return window;
    }

    public static void main(String[] Args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                new TransparentButton();
            }
        });
    }

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger.getLogger(TransparentButton.class
            .getName());
}

回答by Manohar Bhattarai

Have you tried translucency?

你试过半透明吗?

The translucent and shaped window APIwas first added to the Java SE 6 Update 10 release as a private API. This functionality was moved to the public AWT package in the JDK 7 release.

透明和不规则窗口API首次添加到Java SE 6 Update 10的发行为私有API。此功能已移至 JDK 7 版本中的公共 AWT 包。

I think the above links may help you.

我认为以上链接可能对您有所帮助。