首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Repaint()不重绘

Repaint()不重绘
EN

Stack Overflow用户
提问于 2017-03-20 17:53:42
回答 1查看 134关注 0票数 0

我似乎不完全理解paintcomponent方法,包括重绘的用法。有几次我不明白为什么重绘在一些代码中不能工作,而在另一些代码中却工作得很好。我正在尝试创建一个Graph绘画类。现在它是y=x,但它不会工作。paintcomponent似乎只被调用了一次。为什么会这样呢?

代码语言:javascript
复制
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);
    }
}
EN

回答 1

Stack Overflow用户

发布于 2017-03-20 18:12:09

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

也就是说,您的while-loop能够运行得如此之快,它实际上是在窗口在屏幕上可见之前完成的,所以它正在屏幕上的某个地方绘制一个点。

你需要做的是,在循环中注入一个小的延迟来减慢它(这样一个人就可以真正地看到它),就像...

代码语言:javascript
复制
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是由一系列链接在一起的方法调用组成的,每个方法调用都做了一项很小但很重要的工作,除非你确切地知道那个方法在做什么,并且你愿意接管它的工作,否则叫它super方法更简单。

我猜您正在尝试绘制一条增长的直线,所以我修改了move方法,使直线的起点保持不变。我的意图可能是让它移到屏幕下,在这种情况下,恢复代码并不难,我只是不确定

代码语言:javascript
复制
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);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42900423

复制
相关文章

相似问题

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