java - 如何在不删除以前绘制的东西的情况下重新绘制

标签 java swing graphics awt

所以,我想实现 DDA 算法来使用 java 和 swing 来画线,但我在这里遇到了一点问题。为了绘制每个像素,我使用 fillRect(X,Y,1,1)。因此,我需要绘制 XY 的不同位置来绘制一条线。为了更新新绘制的“像素”,我使用 revalidate()repaint() 但这似乎删除了我之前绘制的像素,我只看到了一个点。作为解决方法,我在 paintComponent(Graphics) 中注释掉了 super.paintComponent(g) 但这似乎不是一个好的解决方案,因为这样我就无法设置背景颜色,如果我使用 Thread.sleep() 放慢速度,我会看到正在绘制的线(否则我只会看到一个点)。这是代码

import javax.swing.*;
import java.awt.*;

public class Painter extends JPanel {
    private double x1,y1,x2,y2;
    Painter(int x1, int y1, int x2, int y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;

    }
    @Override
    protected void paintComponent(Graphics g) {
        //super.paintComponent(g);
        setBackground(Color.black);
        g.setColor(Color.RED);
        g.fillRect((int)x1,(int)y1,1,1);
    }

    public void drawLine() {
        double DX = (x2-x1);
        double DY = (y2-y1);

        double steps = (Math.abs(DX) > Math.abs(DY) ) ? Math.abs(DX) : Math.abs(DY);

        double xIncrement = DX/(steps);
        double yIncrement = DY/(steps);
        try {
            for (int i = 0; i < steps; ++i) {
                Thread.sleep(50);
                x1 += xIncrement;
                y1 += yIncrement;
                revalidate();
                repaint();
            }
        }
        catch (Exception e) {

        }

    }

}

在我的 main() 中,我这样调用它

JFrame jFrame = new JFrame("Graphics");
Painter dpl = new Painter(0,0,533,333);
jFrame.add(dpl);
jFrame.setSize(720,480);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dpl.drawLine();

如何解决?

最佳答案

我会使用屏幕外图像来解决问题,这样您就不必省略 super.paintComponent();:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Painter extends JPanel {
    BufferedImage offi;
    Graphics offg;
    private double x1,y1,x2,y2;

    Painter(int x1, int y1, int x2, int y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;

    }
    @Override
    protected synchronized void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(offi,0,0,this);
    }

    private void draw(){
        if(offi == null){
            offi = (BufferedImage)createImage(getWidth(),getHeight());
            offg = offi.getGraphics();
            offg.setColor(Color.black);
            offg.fillRect(0,0,getWidth(),getHeight());
        }  
        offg.setColor(Color.RED);
        offg.fillRect((int)x1,(int)y1,1,1);
    }

    public void drawLine() {
        double DX = (x2-x1);
        double DY = (y2-y1);

        double steps = (Math.abs(DX) > Math.abs(DY) ) ? Math.abs(DX) : Math.abs(DY);

        double xIncrement = DX/(steps);
        double yIncrement = DY/(steps);        
        for (int i = 0; i < steps; ++i) {           
            x1 += xIncrement;
            y1 += yIncrement;

            /*try{
                Thread.sleep(50); //sleep if you want it to be animated
            }catch(InterruptedException e){
                e.printStackTrace();
            }*/
            draw();            
            repaint();
        }  
    }

    public static void main(String[] args){
        SwingUtilities.invokeLater(() -> {
            JFrame jFrame = new JFrame("Graphics");
            Painter dpl = new Painter(0,0,533,333);
            jFrame.add(dpl);
            jFrame.setSize(720,480);
            jFrame.setResizable(false);
            jFrame.setVisible(true);
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            new Thread(() -> dpl.drawLine()).start();;
        });
    }

}

您有时看到一条线,有时只看到一个点的原因是 swing 合并了短时间内发生的连续 repaint() 调用。

关于java - 如何在不删除以前绘制的东西的情况下重新绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41414716/

相关文章:

java - 如何将带有泛型的 java 构建器编写为 scala?

java - 打印字符串,所有元音都替换为下划线 - java

java - JTextPane 不会换行

java - 如何在同一个 JPanel 中实现南北部分

android - 如何绘制闭合曲线形状?

java - 如何为g.drawLine选择颜色?

java - 如何注入(inject)用户名(不是身份验证)?

java - 我怎么解决这个问题? Android studio更新错误..jre/bin/java.exe不存在

java - 我如何调整 jscrollpane 的大小

opengl - VSync=on 的非阻塞 SwapBuffers()