How to create partly transparent JButton on fully transparent JFrame?

徘徊边缘 提交于 2019-12-01 03:28:43

问题


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.

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( );
    }
}

回答1:


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 :-)

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

        /** 
         * @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

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)

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

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());
}



回答2:


Have you tried translucency?

The translucent and shaped window API was 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.

I think the above links may help you.



来源:https://stackoverflow.com/questions/7373345/how-to-create-partly-transparent-jbutton-on-fully-transparent-jframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!