【发布时间】:2020-09-30 05:14:09
【问题描述】:
我正在学习计算机图形学,想用 Java Swing 画线。我想画多条线,它们会留下随机的颜色和随机的 x 和 y 点。我可以用这段代码顺利地画一条线:
package tugas1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Tugas1 extends JPanel{
public static int time = 0;
public static int x1,y1,x2,y2;
Color randomcolor;
public Tugas1() {
this.x1 = (int) (Math.random()*1280);
this.y1 = (int) (Math.random()*720);
this.x2 = (int) (Math.random()*1280);
this.y2 = (int) (Math.random()*720);
randomcolor = new Color((float)Math.random(),(float)Math.random(),(float)Math.random());
// Inisialisasi timer untuk animasi
javax.swing.Timer timer = new javax.swing.Timer(10, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//menambah value variabel time secara berkala
time++;
repaint();
}
});
timer.start();
}
public void garis(Graphics g, int xa, int ya, int xb, int yb){
int count = 0;
int a = xa;
int b = ya;
int dxa = ((xb - xa));
int dya = ((yb - ya));
g.setColor(randomcolor);
if(dxa==0){
if(dya > 0) {
while(ya != yb && time>=count) {
ya++;
g.drawLine(a,b,xa,ya);
count++;
}
} else {
while(ya != yb && time>=count) {
ya--;
g.drawLine(a,b,xa,ya);
count++;
}
}
} else if(dya==0){
if(dxa > 0) {
while(xa != xb&& time>=count) {
xa++;
g.drawLine(a,b,xa,ya);
count++;
}
} else {
while(xa != xb&& time>=count) {
xa--;
g.drawLine(a,b,xa,ya);
count++;
}
}
} else{
dxa = Math.abs(dxa);
dya = Math.abs(dya);
int pk = (dya < dxa) ? 2*dya - dxa : 2*dxa - dya;
int dp = (dya < dxa) ? 2*(dya-dxa) : 2*(dxa-dya);
boolean opr1 = (xa > xb);
boolean opr2 = (ya > yb);
while(xa != xb && ya != yb && time>=count) {
if(pk > 0) {
if(opr1) xa-=1;
else xa+=1;
if(opr2) ya-=1;
else ya+=1;
pk += dp;
}
else {
if (dya < dxa) pk = pk + 2 * dya;
else pk = pk + 2 * dxa;
if(dxa>dya){
if(opr1) xa-=1;
else xa+=1;
}
else {
if(opr2) ya-=1;
else ya+=1;
}
}
g.drawLine(a,b,xa,ya);
a = xa;
b = ya;
count++;
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
garis(g, x1, y1, x2, y2);
}
public static void main(String[] args) {
JFrame fr = new JFrame("Gambar");
fr.setSize(1280,720);
Tugas1 panelGambar = new Tugas1();
fr.getContentPane().add(panelGambar);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setVisible(true);
}
}
但是当我尝试通过单击按钮创建多行时,比如说 100 行,我的按钮不起作用(它只创建一行,并且动画消失了)。这是我创建多行的代码行:
package tugas1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
public class Tugas1 extends JPanel{
public static int time = 0;
public static int x1,y1,x2,y2;
Color randomcolor;
public Tugas1(int x1, int y1, int x2, int y2, Color color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.randomcolor = color;
// Inisialisasi timer untuk animasi
javax.swing.Timer timer = new javax.swing.Timer(10, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//menambah value variabel time secara berkala
time++;
repaint();
}
});
timer.start();
}
public final LinkedList<Tugas1> line = new LinkedList<Tugas1>();
public void garis(Graphics g, int xa, int ya, int xb, int yb){
int count = 0;
int a = xa;
int b = ya;
int dxa = ((xb - xa));
int dya = ((yb - ya));
g.setColor(randomcolor);
if(dxa==0){
if(dya > 0) {
while(ya != yb && time>=count) {
ya++;
g.drawLine(a,b,xa,ya);
count++;
}
} else {
while(ya != yb && time>=count) {
ya--;
g.drawLine(a,b,xa,ya);
count++;
}
}
} else if(dya==0){
if(dxa > 0) {
while(xa != xb&& time>=count) {
xa++;
g.drawLine(a,b,xa,ya);
count++;
}
} else {
while(xa != xb&& time>=count) {
xa--;
g.drawLine(a,b,xa,ya);
count++;
}
}
} else{
dxa = Math.abs(dxa);
dya = Math.abs(dya);
int pk = (dya < dxa) ? 2*dya - dxa : 2*dxa - dya;
int dp = (dya < dxa) ? 2*(dya-dxa) : 2*(dxa-dya);
boolean opr1 = (xa > xb);
boolean opr2 = (ya > yb);
while(xa != xb && ya != yb && time>=count) {
if(pk > 0) {
if(opr1) xa-=1;
else xa+=1;
if(opr2) ya-=1;
else ya+=1;
pk += dp;
}
else {
if (dya < dxa) pk = pk + 2 * dya;
else pk = pk + 2 * dxa;
if(dxa>dya){
if(opr1) xa-=1;
else xa+=1;
}
else {
if(opr2) ya-=1;
else ya+=1;
}
}
g.drawLine(a,b,xa,ya);
a = xa;
b = ya;
count++;
}
}
}
public void addLine(int x1, int y1, int x2, int y2, Color color) {
line.add(new Tugas1(x1, y1, x2, y2, color));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
for (Tugas1 lines : line){
garis(g, lines.x1, lines.y1, lines.x2, lines.y2);
}
}
public static void main(String[] args) {
JFrame fr = new JFrame("Gambar");
fr.setSize(1280,720);
final Tugas1 panelGambar = new Tugas1(0,0,0,0, Color.WHITE);
fr.getContentPane().add(panelGambar);
JPanel buttonsPanel = new JPanel();
JButton startButton = new JButton("Start");
buttonsPanel.add(startButton);
fr.getContentPane().add(buttonsPanel, BorderLayout.PAGE_END);
startButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
for(int i= 0; i<100; i++){
int x1 = (int) (Math.random()*1280);
int y1 = (int) (Math.random()*720);
int x2 = (int) (Math.random()*1280);
int y2 = (int) (Math.random()*720);
Color randomColor = new Color((float)Math.random(), (float)Math.random(), (float)Math.random());
panelGambar.addLine(x1, y1, x2, y2, randomColor);
}
}
});
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setVisible(true);
}
}
也许有一种方法可以保持绘制的线条不会消失,并且所有线条都被绘制为代码的第一个模板
【问题讨论】:
-
使用某种
List并存储您想要在其中绘制的所有“线条”。然后在调用paintComponent时,遍历List并绘制每一行 -
我推荐 Java Collections Trail、Performing Custom Painting、Painting in AWT and Swing 和 Java 2D Graphics Trail 作为一些宝贵的资源——尤其是关于 2D 图形轨迹中“形状”的决定
-
@MadProgrammer "使用某种
List" 代码声明了List,例如public final LinkedList<Tugas1> line = new LinkedList<Tugas1>();。 OP 对属性以及它们应该附加到什么/应该如何存储它们非常困惑。关于本教程的好建议,如果 OP 这样做了,他们希望能理解为什么设置 BG 颜色应该在构造函数中完成,而不是在绘制方法中完成。 -
请参阅:Custom Painting Approaches 以获取帮助您入门的基本工作示例。它演示了如何将有关要绘制的对象的信息存储在自定义对象中。