gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:07:29 24 4
gpt4 key购买 nike

所以,我想实现 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com