Java JPanel重新喷漆未清除
我有一个自定义的抽象类“Panel”,它扩展了JPanel。绘画时两者没有太多区别。我有一个面板,我正在通过更新图像的x值来模拟动画。我现在有两个动画,一个正确地重新绘制,另一个没有。这是给不喜欢的人的。有效的将被标记为A,无效的将被标记为B A和B采用相同的格式。更新面板上的一些变量,调用Update(面板中调用PaintComponent的方法),然后调用repaint。它调用repaint after,因为此问题与before有关,并通过这种方式解决 答:更新图像变量。 B:更新图像的x变量 问题是:重新绘制无法清除旧图像的位置,因此整个屏幕上乱七八糟 我所尝试的:Java JPanel重新喷漆未清除,java,swing,jpanel,repaint,Java,Swing,Jpanel,Repaint,我有一个自定义的抽象类“Panel”,它扩展了JPanel。绘画时两者没有太多区别。我有一个面板,我正在通过更新图像的x值来模拟动画。我现在有两个动画,一个正确地重新绘制,另一个没有。这是给不喜欢的人的。有效的将被标记为A,无效的将被标记为B A和B采用相同的格式。更新面板上的一些变量,调用Update(面板中调用PaintComponent的方法),然后调用repaint。它调用repaint after,因为此问题与before有关,并通过这种方式解决 答:更新图像变量。 B:更新图像的x变
- 我见过super.PaintComponent(g)提到了很多,但是这个 这个问题还没有解决
- 我已尝试更改重新绘制/更新方法启用时的顺序 打电话来
- “重新绘制”根本不会更新面板。(可能是因为 在PaintComponent(组件)中完成喷漆
public Panel (boolean visible){
super();
this.setLayout(new BorderLayout(640, 416));//sets the Layout type of the panel
this.setOpaque(false);//Makes it so that the panel underneath can be seen where images aren't drawn
this.setVisible(visible);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gs = ge.getDefaultScreenDevice();
gc = gs.getDefaultConfiguration();
}
public void paintComponent (Graphics g){
setUp();
drawOff();
setDown(g);
}
private void setUp(){
off_screen = gc.createCompatibleImage(getSize().width, getSize().height, Transparency.TRANSLUCENT);
buffer = off_screen.createGraphics();
}
protected abstract void drawOff();
private void setDown(Graphics g){
g.drawImage(off_screen,0,0,this);
off_screen.flush();
}
public void update(){
paintComponent(this.getGraphics());
}
动画方法(mg是讨论中的面板):
private void battleStart(用户){
for(int i=0;i
我认为你的设计太离谱了,这就是为什么事情不起作用的原因。我不太清楚你的非抽象JBAND是如何工作的,但是考虑让你的父JPAND更像这样:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyPanel extends JPanel {
private GraphicsEnvironment ge;
private GraphicsDevice gs;
private GraphicsConfiguration gc;
private BufferedImage offScreen;
public MyPanel(boolean visible) {
super();
this.setLayout(new BorderLayout(640, 416)); // strange constants for this layout.
this.setOpaque(false);
this.setVisible(visible);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gs = ge.getDefaultScreenDevice();
gc = gs.getDefaultConfiguration();
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setUp();
}
});
}
@Override
// don't make this public. Keep it protected like the super's
// just draw in this method. Don't call other methods that create buffers
// or draw to buffers.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (offScreen != null) {
g.drawImage(offScreen, 0, 0, null);
}
}
private void setUp() {
offScreen = gc.createCompatibleImage(getSize().width, getSize().height,
Transparency.TRANSLUCENT);
}
// draw to the buffer outside of the paintComponent
// and then call repaint() when done
public void upDateOffScreen() {
// ?? offScreen.flush(); // I've never used this before,
// so am not sure if you need this here
Graphics2D osGraphics = offScreen.createGraphics();
// TODO: do drawing with osGraphics object here
osGraphics.dispose();
repaint();
}
}
再三
- 在EDT(事件调度线程)之外执行所有长处理方法
- 永远不要调用线程。在EDT上睡眠(…)
- 考虑使用Swing计时器,而不是使用Thread.sleep进行动画
- 在你的JPanel上调用repaint关闭EDT是可以的,但在大多数情况下都是这样李>
- 应在EDT上调用所有其他Swing方法
- 阅读、重读并学习2D和Swing图形教程
javax.swing.Timer
istead ofThread.sleep(int)
这两个最疯狂的例子,我使用了swing计时器,解决了这个问题。这是因为repait方法没有被调用/执行它应该执行的操作。可能是因为你提到的EDT。但非常感谢你。:)
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyPanel extends JPanel {
private GraphicsEnvironment ge;
private GraphicsDevice gs;
private GraphicsConfiguration gc;
private BufferedImage offScreen;
public MyPanel(boolean visible) {
super();
this.setLayout(new BorderLayout(640, 416)); // strange constants for this layout.
this.setOpaque(false);
this.setVisible(visible);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gs = ge.getDefaultScreenDevice();
gc = gs.getDefaultConfiguration();
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setUp();
}
});
}
@Override
// don't make this public. Keep it protected like the super's
// just draw in this method. Don't call other methods that create buffers
// or draw to buffers.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (offScreen != null) {
g.drawImage(offScreen, 0, 0, null);
}
}
private void setUp() {
offScreen = gc.createCompatibleImage(getSize().width, getSize().height,
Transparency.TRANSLUCENT);
}
// draw to the buffer outside of the paintComponent
// and then call repaint() when done
public void upDateOffScreen() {
// ?? offScreen.flush(); // I've never used this before,
// so am not sure if you need this here
Graphics2D osGraphics = offScreen.createGraphics();
// TODO: do drawing with osGraphics object here
osGraphics.dispose();
repaint();
}
}