繁体   English   中英

Repaint()不重绘

[英]Repaint() not repainting

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

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);
    }
}

因此,在添加了有关该地点的一些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 绘画即挥舞是由一系列链接在一​​起的方法调用组成的,每个方法调用执行的都是小而重要的工作,除非您确切地知道该方法在做什么,并且您将接管它的工作,否则将其称为super更简单方法。

我猜您正在尝试绘制一条会增长的线,因此我修改了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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM