首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重新绘制-立即绘制和删除

重新绘制-立即绘制和删除
EN

Stack Overflow用户
提问于 2013-03-27 05:53:18
回答 1查看 206关注 0票数 1

我有一个乒乓球项目(某种),它可以工作,但run()函数中有一个问题。如果我用我写给面板的函数来绘制框架(它们可以工作,我检查过了),它会给出一个图形问题,如果我使用重绘(正如我想要的那样),它会绘制框架并立即删除它,每个解决方案都会有帮助(在我的代码级别上最好是一个简单的解决方案):

代码语言:javascript
运行
复制
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.*;
import sun.org.mozilla.javascript.internal.Kit;



public class Picture extends JPanel implements MouseListener, Runnable{

    private int k = 0;
    Thread MyThread;
    private DrawPic img;
 
    private Rectangle r1, r3;

    public Picture(DrawPic img, Rectangle rect1, Rectangle rect3) {
        super();
        this.setLocation(0, 85);
        this.setLayout(new FlowLayout());
        this.setSize(1280, 1024);
          
        this.addMouseListener(this);
        this.setFocusable(true);
      
        this.r1 = rect1;
    
        this.r3 = rect3;
        this.img = img;
        this.MyThread = new Thread(this);
        MyThread.start();
        this.setVisible(true);
    
    }
    
    

 
    public void paintRectangleL(Rectangle rect, Graphics g) {
        k = 3;
        
        rect.DrawRectangle(g);
        rect.FillRectangle(g);


    }
    public void paintRectangleR(Rectangle rect, Graphics g) {
        k = 1;
      
        rect.DrawRectangle(g);
        rect.FillRectangle(g);

    }
    public void paintImage(DrawPic img, Graphics g) {
        k = 2;
     
        //g.clearRect(0, 0, this.getWidth(), this.getHeight());
        img.DrawImg(g, this);
        


    }
    public void changeK(int k1){
        k = k1;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // throw new UnsupportedOperationException("Not supported yet.");
      
        
       
    }

    @Override
    public void mousePressed(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
        
            Point p = r3.FindCenter();
            double dx, dy;

            dy = e.getY() - p.getY();
            r3.Move(0, dy);
              this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight());
            this.paintRectangleL(r3, this.getGraphics());
            this.paintRectangleR(r1, this.getGraphics());
            this.paintImage(img, this.getGraphics());
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //   throw new UnsupportedOperationException("Not supported yet.");
    }
    public void animate(){
        double dx = 0, dy = 2;
        if ((this.img.getX() + 160 + this.r1.RightPoint().getX() - this.r1.LeftPoint().getX() > this.getWidth() || this.img.getX() < this.r3.RightPoint().getX() - this.r3.LeftPoint().getX())) {
                    dx = -1 * dx;
                    

                }
                if (this.img.getY() + 120> this.getHeight() || this.img.getY() < 0 ) {
                    dy = -1 * dy;
                }
                img.Move(dx, dy);
             //   this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight());
              //  this.paintImage(img, this.getGraphics());
              //  this.paintRectangleL(r3, this.getGraphics());
              //  this.paintRectangleR(r1, this.getGraphics());
                repaint();            
    }

    @Override
    public void run() {
        
        Color col;
        while (true) {
                 animate();

                try {
                    MyThread.sleep(35);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Picture.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        //   throw new UnsupportedOperationException("Not supported yet.");
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-27 07:16:22

不应使用getGraphics()进行自定义绘制,因为它是一个临时缓冲区,会在下一次重新绘制时回收。你在paintComponent()中作画吗。

有关更多信息和示例,请参阅Performing Custom PaintingA Closer Look at the Paint Mechanism一节很好地总结了paint()paintComponent()方法。另请参阅Painting in AWT and Swing

编辑:

您的程序的逻辑和结构不适合Swing的绘制过程。您需要重构您的程序,以便它可以插入到该进程中,并在正确的时间绘制正确的内容。通常,您可以通过覆盖组件的paintComponent()来自定义组件。在这种方法中,所有的绘画都会发生。这种方法应该尽可能快,避免在其中放入任何/太多的应用程序逻辑。

你应该保持所绘制对象的某种状态(即坐标、颜色等),一旦状态发生变化就发出repaint()。这将安排一次重新绘制,最终Swing将在调用paintComponent()的组件上执行paint()

在本例中,您有一个定期触发的计时器。您可以覆盖您使用的JPanelpaintComponent。你已经有了计算坐标的逻辑。将这些坐标存储在成员变量中。然后,发出repaint()。在paintComponent中,根据计算的坐标绘制图像。

编辑:

关于线程的另一个注意事项。Swing具有单线程绘制模型。所有的UI交互和绘制都是在Swing的事件调度线程( Event Dispatch Thread,EDT)上进行的。有关EDT的更多信息,请访问Concurrency in Swing。注意,animate()方法不是在EDT上执行的。您没有展示img.Move(dx, dy)的功能,但是以这种方式执行可能不安全。invokeLater可能有助于确保代码在EDT上执行。然而,在这种特殊情况下,使用Swing timers可能更容易,这确保了在EDT上执行操作。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15648088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档