JProgressBar重复

时间:2015-03-26 00:00:16

标签: java swing jprogressbar

我的JProgressBar完美运行,直到我将JFrame GlassPane设置为可见。然后它随机决定在屏幕上拍摄并复制。

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

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

这只发生在我这样做的时候 。this.getGlassPane()调用setVisible(真);

以下是代码:

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

}

感谢您阅读

2 个答案:

答案 0 :(得分:1)

制作Graphics对象的副本,在 上设置合成并使用它进行绘制。然后处理它。

public void paintComponent(Graphics g) {
    super.paintComponent(g); 
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
    g2.setColor(getBackground());
    g2.fillRect(0,0,getWidth(),getHeight());
    g2.dispose();
}

答案 1 :(得分:1)

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

由于Graphics是共享资源,因此您对其所做的任何更改都将影响在其后绘制的任何其他组件。您应该在Graphics存在之前将paintComponent上下文恢复到之前的状态。这最容易通过使用Graphics#create来实现,Graphics会创建快照Graphics#dispose上下文的属性,但不会影响原始属性。然后,您应该确保在完成后在副本上致电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); } } }

您的玻璃窗格也应该是透明的,允许在其下方绘制。

Fade

{{1}}