【问题标题】:Repaint() not repaintingRepaint() 不重绘
【发布时间】:2017-03-20 09:53:41
【问题描述】:

我似乎没有完全理解paintcomponent方法包括repaint的使用。 有几次我不明白为什么重绘在某些代码中不起作用,而在另一个代码中工作正常。 我正在尝试创建一个图形绘画类。现在它的y = x。但它不会工作。油漆组件似乎只被调用了一次。这是为什么呢?

public class Graph extends JPanel
{
    private int oldX=0,oldY=0,newX=1,newY=1;
    public Graph()
    {
        invokeInitWindow();
    }
    public void invokeInitWindow()
    {
        SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        init();
                    }
                });

    }
    public void init()
    {
        JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(300,300));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.pack();
        frame.setVisible(true);
    }
    public void move()
    {
        newY=++newX;
        oldX=oldY=newX+1;
    }
    public void runGraph()
    {
        while(newX < 500)
        {
            move();
            repaint();
        }
    }
    public static void main(String[] args)
    {
        Graph g = new Graph();
        g.runGraph();
    }
    public void paintComponent(Graphics g)
    {
        g.setColor(Color.BLACK);
        g.drawLine(oldX, oldY, newX, newY);
    }
}

【问题讨论】:

  • 是的,但是你 while-loop 跑得太快了,在帧出现在屏幕上之前就完成了

标签: java repaint


【解决方案1】:

所以,在添加了一些关于这个地方的System.out.println 命令之后,很明显你基本上有一个竞争条件。

也就是说,您的while-loop 能够运行得如此之快,它实际上是在窗口出现在屏幕上之前完成的,因此它正在屏幕外某处绘制一个点。

您需要做的是在循环中注入一个小的延迟以减慢它的速度(因此人们可以实际看到它),例如......

public void runGraph() {
    while (newX < 500) {
        try {
            Thread.sleep(40);
        } catch (InterruptedException ex) {
            Logger.getLogger(Graph.class.getName()).log(Level.SEVERE, null, ex);
        }
        move();
        repaint();
    }
}

代码审查

对不起,我忍不住了。您的代码存在的(重要)问题之一是构造函数有副作用,也就是说,它正在创建 JFrame 并在将来的某个时间这样做。这是您真正想要避免的事情。构造函数应该初始化对象的状态,仅此而已。

按照您目前的设置方式,您不可能以任何有意义的方式重复使用面板。

其次,您确实应该在进行任何自定义绘画之前致电super.paintComponent。绘画是 Swing 由一系列链接在一​​起的方法调用组成,每个方法调用都执行一项小而重要的工作,除非您确切知道该方法在做什么并且您愿意接管它的工作,否则将其称为 @ 更简单987654326@方法。

我猜你想画一条增长的线,所以我修改了move 方法,所以线的起点保持不动。我可能是你打算让它在屏幕上向下移动,在这种情况下,恢复你的代码并不难,我只是不确定

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Graph extends JPanel {

    private int oldX = 0, oldY = 0, newX = 1, newY = 1;

    public Graph() {
    }

    public void move() {
        newY = ++newX;
//      oldX = oldY = 
        newX += 1;
    }

    public void runGraph() {
        while (newX < 500) {
            try {
                Thread.sleep(40);
            } catch (InterruptedException ex) {
                Logger.getLogger(Graph.class.getName()).log(Level.SEVERE, null, ex);
            }
            move();
            repaint();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Graph g = new Graph();
                JFrame frame = new JFrame();
                frame.setPreferredSize(new Dimension(300, 300));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(g);
                frame.pack();
                frame.setVisible(true);
                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        g.runGraph();
                    }
                });
                t.start();
            }
        });

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        g.drawLine(oldX, oldY, newX, newY);
    }
}

【讨论】:

  • 好的,感谢您的快速和有用的评论,实际上我想要的是在足够小的间隔内“绘制”一堆这些线,以便绘制图形。我仍在努力解决这个问题,因为它每次都会刷新,所以我得到的是一条移动的小线,但它并没有“停留”在原来的位置。
  • Paint 是破坏性的,如果你想在“块”中绘制图形,那么你需要维护这些块的 List,当调用 paintComponent 时,再次绘制它们
猜你喜欢
  • 1970-01-01
  • 2011-09-08
  • 2011-12-28
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多