Java paintComponent переопределяет различия между версиями 5 и 6 - PullRequest
3 голосов
/ 16 февраля 2012

Разработав свое приложение для Java 5, я недавно протестировал в 6 и обнаружил, что у меня проблема с paintComponent.

Что происходит в jre5, так это то, что экран начинает тускнеть, а кнопка «передний план» появляется в верхней части панели затемнения (как и ожидалось). В jre6 кнопка вообще не появляется, но вы получаете затемнение. Вы можете вывести кнопку из строя, наведя указатель мыши на ее местоположение (заставив ролловер перерисовать ее). Я могу немного изменить код, чтобы кнопка появилась в jre6, но затемненная панель всегда закрашивается поверх кнопки.

Я предполагаю, что это скорее удача, чем здравое суждение, что он работает вообще в jre5, но не может найти большую помощь онлайн. Любая помощь, которую вы можете пролить на ситуацию, будет наиболее ценной.

Я создал приведенный ниже код, чтобы показать проблему:

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

Ответы [ 3 ]

2 голосов
/ 16 февраля 2012

вы должны попробовать этот код и затем собрать

1 голос
/ 16 февраля 2012

Создайте копию графического контекста в функции paintComponent.Это решит проблему.

public void paintComponent( Graphics g )
{       
    super.paintComponent( g ); 
    Graphics2D g2 = (Graphics2D) g.create();
    ...
}
0 голосов
/ 16 февраля 2012

Первый оператор в paintComponent должен иметь порядок

   super.paintComponent(g);

, чтобы очистить изображение за пределами экрана.В противном случае вы можете получить неожиданные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...