JProgressBar 复制 [英] JProgressBar duplicating

查看:29
本文介绍了JProgressBar 复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我将 JFrame GlassPane 设置为可见之前,我的 JProgressBar 运行良好.然后它随机决定在屏幕上拍摄并复制.

My JProgressBar is worked perfectly up until i set my JFrame GlassPane visible. It then randomly decides to shoot across the screen and duplicate.

这是显示错误的动画 GIF.无论我的代码是什么,都会发生这种情况 - 即使使用非常基本的 GUI

Here is an animated GIF displaying the bug. This happens no matter what my code is - even with an extremely basic GUI

http://i.gyazo.com/bd70df610a3cad6bfff258b80f21c78a.gif

http://i.gyazo.com/bd70df610a3cad6bfff258b80f21c78a.gif

这只会在我这样做时发生this.getGlassPane().setVisible(true);

This ONLY happens when i do this.getGlassPane().setVisible(true);

代码如下:

    public void setProgress(final int percent) {
            pb.setValue(percent);

            if (percent == 100) {

                    SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                    FadingMirror glassPane = new FadingMirror();
                                    instance.setGlassPane(glassPane);

                                    ((FadingMirror)instance.getGlassPane()).startAnimation();
                                    ((FadingMirror)instance.getGlassPane()).setVisible(true);
                            }
                    });
            }
    }

    @Override
    public void addText(String text) {
            System.out.println(text);
    }

    public static class FadingMirror extends JPanel implements ActionListener {

            /**
             *
             */
            private static final long serialVersionUID = 7341931028635559650L;
            private float opacity = 0f;
            private Timer fadeTimer;

            public void startAnimation() {
                    fadeTimer = new javax.swing.Timer(75, this);
                    fadeTimer.setInitialDelay(0);
                    fadeTimer.start();

            }

            public void actionPerformed(ActionEvent e) {
                    opacity += .03;
                    if(opacity > 1) {
                            opacity = 1;
                            fadeTimer.stop();
                            fadeTimer = null;
                    }
                    repaint();
            }

            public void paintComponent(Graphics g) {
                    //super.paintComponent(g); //Cannot do this before setting composite without destroying the animation
                    ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
                    g.setColor(getBackground());
                    g.fillRect(0,0,getWidth(),getHeight());
            }
    }

}

感谢阅读

推荐答案

Graphics 是一种共享资源.通常,框架绘制的任何 Swing 组件都使用相同的 Graphics 上下文.paintComponent 的工作之一是为绘制准备 Graphics 上下文,通常是通过填充当前背景颜色.

Graphics is a shared resource. Generally, any Swing component painted by the frame uses the same Graphics context. One of the jobs of paintComponent is to prepare the Graphics context for painting, typically by filling it the current background color.

因为 Graphics 是共享资源,您对其所做的任何更改都会影响在其之后绘制的任何其他组件.您应该在 paintComponent 存在之前将 Graphics 上下文恢复到它的先前状态.这最容易通过使用 Graphics#create 来实现,它将创建 Graphics 上下文的属性的快照,但不会影响原始.然后,您应该确保在完成后在副本上调用 Graphics#dispose.

Because Graphics is a shared resource, any changes you make to it will affect any other components that are painted after it. You should be restoring the Graphics context to it's previous state before paintComponent exists. This is most easily achieved by using Graphics#create which will create a snap-shot the properties of the Graphics context, but won't affect the original. You should then ensure that you call Graphics#dispose on your copy when you're done.

你的玻璃板也应该是透明的,以便它下面的东西可以被涂上.

Your glass pane should also be transparent, allowing what ever is below it to be painted.

import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setGlassPane(new FadePane());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class FadePane extends JPanel {

        private float alpha = 0;
        private Timer timer;

        public FadePane() {
            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    alpha += 0.1f;
                    if (alpha > 1.0) {
                        alpha = 1f;
                        timer.stop();
                    }
                    repaint();
                }
            });
            setOpaque(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();
        }

        public void fadeAway() {
            setVisible(true);
            timer.stop();
            alpha = 0f;
            timer.start();
        }

    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            setBorder(new EmptyBorder(50, 50, 50, 50));

            JButton btn = new JButton("It's better to burn out then fade away");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JRootPane rootPane = (JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class, TestPane.this);
                    FadePane fadePane = (FadePane) rootPane.getGlassPane();
                    fadePane.fadeAway();
                }
            });
            add(btn);
        }

    }

}

这篇关于JProgressBar 复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆