Java组件覆盖版本5和版本6之间的差异

Java组件覆盖版本5和版本6之间的差异,java,swing,Java,Swing,在开发了针对Java 5的应用程序后,我最近在6中进行了测试,发现有一个组件问题 在jre5中,屏幕开始变暗,按钮“前台”出现在变暗面板的顶部(如预期)。在jre6中,按钮根本不会出现,但确实会变暗。您可以通过将鼠标移到按钮的位置(强制滚动以重新绘制按钮)来将按钮哄出。我可以稍微重新排列代码,使按钮出现在jre6中,但暗显的面板总是画在按钮的顶部 我认为它在jre5中完全有效,但在网上找不到太多帮助,这更多的是运气,而不是良好的判断。如果你能在这种情况下提供任何帮助,我将不胜感激 我已生成以下代

在开发了针对Java 5的应用程序后,我最近在6中进行了测试,发现有一个组件问题

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

paintComponent中的第一条语句应为

   super.paintComponent(g);

以清除屏幕外位图。否则,您可能会得到意外的结果。

在paintComponent函数中创建图形上下文的副本。这将解决问题

public void paintComponent( Graphics g )
{       
    super.paintComponent( g ); 
    Graphics2D g2 = (Graphics2D) g.create();
    ...
}

您必须尝试这些代码,然后将它们组合在一起

  • 阅读关于

  • 阅读全文,包括评论,可能是一个相互询问的选择


嗯,是和否。是的,我可能应该调用它,但它实际上并没有帮助解决问题。您可能有不止一个错误-我指出了一个会导致结果不一致的错误。我以前在我制作的任何自定义组件中都没有看到过这一点,但出于某种原因,处理
图形2d
会导致问题。删除这一行代码使它变得更好,但并没有完全修复它。创建一个
图形的副本并使用该副本似乎可以达到目的。