Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPanel重新喷漆未清除_Java_Swing_Jpanel_Repaint - Fatal编程技术网

Java JPanel重新喷漆未清除

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变

我有一个自定义的抽象类“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图形教程

也许双缓冲有帮助-看看为什么要直接调用paintComponent()?我从未在Swing图形程序中见过这样的操作。你的整个设计似乎,。。。不寻常。您是否遵循某种教程?为什么要从paintComponent中创建离屏图像?这违背了屏幕外的目的,因为它会不必要地减慢您的绘画速度?此外,您是否注意在EDT的背景线程中制作动画?请参阅此链接,并检查stack oerflow问题+1我错过了使用
javax.swing.Timer
istead of
Thread.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();
   }
}