作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,我想实现 DDA 算法来使用 java 和 swing 来画线,但我在这里遇到了一点问题。为了绘制每个像素,我使用 fillRect(X,Y,1,1)
。因此,我需要绘制 X
和 Y
的不同位置来绘制一条线。为了更新新绘制的“像素”,我使用 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/
我是一名优秀的程序员,十分优秀!