我的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());
}
}
}
感谢您阅读
答案 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);
}
}
}
。
您的玻璃窗格也应该是透明的,允许在其下方绘制。
{{1}}