Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java paintComponent override differences between versions 5 and 6

Tags:

java

swing

Having developed my application against Java 5 I recently tested in 6 and found that I have a paintComponent problem.

What happens is in jre5 is the screen begins to dim and the button "foreground" appears on top of a dimming panel (as expected). In jre6 the button does not appear at all but you do get the dimming. You can coax the button out by moving your mouse over its location (forcing the rollover to repaint it). I can rearrange the code slightly to get the button to appear in jre6 but the dimmed panel is always painted over the top of the button.

I'm assuming its more by luck than good judgment that it works at all in jre5 but couldn't find much assistance online. Any help you can shed on the situation would be most appreciated.

I have produced the below code to show the problem:

    import java.awt.AlphaComposite;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;

    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;

    @SuppressWarnings( "serial" )
    public class TranslucentGlass extends JPanel
    {
        public static void main( String[] args )
        {
            // Create a frame
            JFrame f = new JFrame();
            JPanel mainPanel = new JPanel( new BorderLayout() );

            JLabel bgLabel = new JLabel( System.getProperty( "java.version" ) );
            mainPanel.add( bgLabel, BorderLayout.SOUTH );

            // create a panel for the glasspane
            final JPanel glassPane = new JPanel();
            glassPane.setLayout( new BorderLayout() );
            glassPane.setVisible( false );
            glassPane.setOpaque( false );

            // create the containing panel for the 'foreground' button
            final JPanel largePanel = new JPanel( new BorderLayout() );
            largePanel.setOpaque( false );
            largePanel.setBorder( BorderFactory.createEmptyBorder( 0, 20, 50, 20 ) );
            largePanel.add( new JButton( "Foreground" ), BorderLayout.SOUTH );

            // set the glass pane and mainpanel
            f.add( mainPanel );
            f.setGlassPane( glassPane );
            f.setPreferredSize( new Dimension( 250, 250 ) );

            f.addWindowListener( new WindowAdapter()
            {
                @Override
                public void windowClosing( WindowEvent e )
                {
                    System.exit( 0 );
                }
            } );

            // an action to show or hide the panel on mouse clicked
            f.addMouseListener( new MouseAdapter()
            {
                boolean panelVisible = false;

                @Override
                public void mouseClicked( MouseEvent e )
                {
                    if( !panelVisible )
                    {
                        glassPane.removeAll();

                        TranslucentGlass dimmingPanel = new TranslucentGlass( false );
                        dimmingPanel.add( largePanel );

                        glassPane.add( dimmingPanel );

                        dimmingPanel.startTimer();
                        glassPane.setVisible( true );

                        panelVisible = true;
                    }
                    else
                    {
                        glassPane.setVisible( false );
                        panelVisible = false;
                    }
                }
            } );

            f.pack();
            f.setVisible( true );
        }

        private Timer timer;
        private float opacity = 0;
        private long sysTime = System.currentTimeMillis();

        private static final int TIMER_INTERVAL = 50; // measured in milliseconds
        private static final int TIMER_TOTAL = 750; // measured in milliseconds

        private static final Color FADE_COLOUR = Color.RED;
        private static final float FINAL_OPACITY = 0.3f;

        public TranslucentGlass()
        {
            this( true );
        }

        public TranslucentGlass( boolean startTimer )
        {
            super();
            setOpaque( false );
            setLayout( new BorderLayout() );

            // Create a new timer to change the opacity over time and repaint the panel
            timer = new Timer( TIMER_INTERVAL, new ActionListener()
            {
                public void actionPerformed( ActionEvent e )
                {
                    long newSysTime = System.currentTimeMillis();
                    opacity += FINAL_OPACITY * ( newSysTime - sysTime ) / TIMER_TOTAL;
                    sysTime = newSysTime;
                    validate();
                    repaint();

                    if( opacity >= FINAL_OPACITY )
                    {
                        timer.stop();
                    }
                }
            } );

            if( startTimer )
            {
                timer.start();
            }
        }

        public void startTimer()
        {
            timer.start();
        }

        // Override the paintComponent calling paintComponent*s* to ensure the panels contents are painted
        @Override
        protected void paintComponent( Graphics g )
        {
            final Graphics2D g2 = ( Graphics2D ) g;

            g2.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, opacity ) );
            g2.setColor( FADE_COLOUR );
            g2.fillRect( 0, 0, getWidth(), getHeight() );
            g2.dispose();

            super.paintComponents( g );
        }
    }
like image 548
Remlap21 Avatar asked Sep 17 '26 18:09

Remlap21


1 Answers

you have to try these code and then put together

  • Layering multiple GlassPane's in a Root Container

  • ButtonTest and AlphaFrame by trashgod

  • read tutorial about Swing Timer

  • read whole Add loading circle to JTable including comments, maybe post by @aterai about JLayer could be interresting alternative

like image 186
mKorbel Avatar answered Sep 20 '26 08:09

mKorbel