JProgressBar 复制 [英] JProgressBar duplicating
问题描述
在我将 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屋!