我的程序运行并成功绘制了Sierpinski Triangle。但是,它只会出现一段时间然后消失。为什么是这样?
这是我的课程(2节课)。这是完全可编辑和可运行的。
的 TrianglePanel.java 的
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TrianglePanel extends JPanel {
int level = 2;
int width;
int height;
Graphics g;
public static void main(String[] agrs) {
TrianglePanel panel = new TrianglePanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(400, 400));
frame.setLocationRelativeTo(null);
frame.add(panel);
frame.setVisible(true);
}
public TrianglePanel() {
}
public void paintComponent(Graphics g) {
this.g = g;
width = this.getSize().width;
height = this.getSize().height;
ArrayList<Line> queue = new ArrayList<Line>();
queue.add(new Line(new Point(width / 2, 0), new Point(0, height)));
queue.add(new Line(new Point(0, height), new Point(width, height)));
queue.add(new Line(new Point(width, height), new Point(width / 2, 0)));
drawLine(queue.get(0));
drawLine(queue.get(1));
drawLine(queue.get(2));
int counter = 0;
while (true) {
if (level > 6) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
Line[] toDraw = queue.get(0).getTriangleToDraw(level, width, height);
Point[] toDrawPoints = toDraw[0].getPoints();
if (Math.sqrt(((Math.pow(toDrawPoints[1].x - toDrawPoints[0].x, 2)) + (Math.pow(toDrawPoints[1].y - toDrawPoints[0].y, 2)))) <= 4) {
System.out.println("breakyo");
break;
}
drawLine(toDraw[0]);
drawLine(toDraw[1]);
drawLine(toDraw[2]);
queue.remove(0);
queue.add(toDraw[0]);
queue.add(toDraw[1]);
queue.add(toDraw[2]);
counter++;
System.out.println(counter + " and " + level);
if (counter - Math.pow(3, level - 1) == 0) {
counter = 0;
level++;
}
}
}
private void drawLine(Line line) {
g.drawLine(line.getPoints()[0].x, line.getPoints()[0].y, line.getPoints()[1].x, line.getPoints()[1].y);
}
}
的 Line.java 的
import java.awt.Point;
public class Line {
private Point endpoint1;
private Point endpoint2;
private Point midpoint;
private double slope;
public Line(Point endpoint1, Point endpoint2) {
this.endpoint1 = endpoint1;
this.endpoint2 = endpoint2;
midpoint = new Point((endpoint1.x + endpoint2.x) / 2, (endpoint1.y + endpoint2.y) / 2);
slope = (double) (endpoint2.y - endpoint1.y) / (double) (endpoint2.x - endpoint1.x);
}
public Point[] getPoints() {
return new Point[] { endpoint1, endpoint2 };
}
public Line[] getTriangleToDraw(int level, int width, int height) {
Line[] lines = new Line[3];
if (slope > 0) { //negative slope
Point left = new Point(midpoint.x - (width / (int)(Math.pow(2, level - 1))), midpoint.y);
Point middle = new Point(midpoint.x - (width / (int)(Math.pow(2, level))), midpoint.y + (height / (int)(Math.pow(2, level - 1))));
lines[0] = new Line(midpoint, left);
lines[1] = new Line(midpoint, middle);
lines[2] = new Line(middle, left);
}
else if (slope < 0) { // positive slope
Point right = new Point(midpoint.x + (width / (int)(Math.pow(2, level - 1))), midpoint.y);
Point middle = new Point(midpoint.x + (width / (int)(Math.pow(2, level))), midpoint.y + (height / (int)(Math.pow(2, level - 1))));
lines[0] = new Line(midpoint, right);
lines[1] = new Line(midpoint, middle);
lines[2] = new Line(middle, right);
}
else { //zero slope
Point left = new Point(midpoint.x - (width / (int)(Math.pow(2, level))), midpoint.y - (height / (int)(Math.pow(2, level - 1))));
Point right = new Point(midpoint.x + (width / (int)(Math.pow(2, level))), midpoint.y - (height / (int)(Math.pow(2, level - 1))));
lines[0] = new Line(midpoint, left);
lines[1] = new Line(midpoint, right);
lines[2] = new Line(left, right);
}
return lines;
}
}
答案 0 :(得分:3)
这采用类似于@Hovercraft建议的方法,但将SwingWorker
交换为Timer
,而不是为标签设置新图标,而是调用repaint()
。< / p>
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.util.ArrayList;
public class TrianglePanel extends JPanel {
int level = 2;
int width;
int height;
Timer timer;
BufferedImage canvas;
JLabel label;
public static void main(String[] agrs) {
TrianglePanel panel = new TrianglePanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public TrianglePanel() {
final int width = 400;
final int height = 400;
canvas = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
label = new JLabel(new ImageIcon(canvas));
add( label );
final Graphics2D g = canvas.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(new Color(255,127,0));
final ArrayList<Line> queue = new ArrayList<Line>();
queue.add(new Line(new Point(width / 2, 0), new Point(0, height)));
queue.add(new Line(new Point(0, height), new Point(width, height)));
queue.add(new Line(new Point(width, height), new Point(width / 2, 0)));
drawLine(queue.get(0),g);
drawLine(queue.get(1),g);
drawLine(queue.get(2),g);
ActionListener al = new ActionListener() {
int counter = 0;
public void actionPerformed(ActionEvent ae) {
if (level > 6) {
timer.stop();
return;
}
Line[] toDraw = queue.get(0).getTriangleToDraw(level, width, height);
Point[] toDrawPoints = toDraw[0].getPoints();
if (Math.sqrt(((Math.pow(toDrawPoints[1].x - toDrawPoints[0].x, 2)) + (Math.pow(toDrawPoints[1].y - toDrawPoints[0].y, 2)))) <= 4) {
System.out.println("breakyo");
return;
}
drawLine(toDraw[0],g);
drawLine(toDraw[1],g);
drawLine(toDraw[2],g);
queue.remove(0);
queue.add(toDraw[0]);
queue.add(toDraw[1]);
queue.add(toDraw[2]);
counter++;
System.out.println(counter + " and " + level);
if (counter - Math.pow(3, level - 1) == 0) {
counter = 0;
level++;
}
label.repaint();
}
};
timer = new Timer(20,al);
timer.start();
}
private void drawLine(Line line, Graphics g) {
g.drawLine(line.getPoints()[0].x, line.getPoints()[0].y, line.getPoints()[1].x, line.getPoints()[1].y);
}
}
class Line {
private Point endpoint1;
private Point endpoint2;
private Point midpoint;
private double slope;
public Line(Point endpoint1, Point endpoint2) {
this.endpoint1 = endpoint1;
this.endpoint2 = endpoint2;
midpoint = new Point((endpoint1.x + endpoint2.x) / 2, (endpoint1.y + endpoint2.y) / 2);
slope = (double) (endpoint2.y - endpoint1.y) / (double) (endpoint2.x - endpoint1.x);
}
public Point[] getPoints() {
return new Point[] { endpoint1, endpoint2 };
}
public Line[] getTriangleToDraw(int level, int width, int height) {
Line[] lines = new Line[3];
if (slope > 0) { //negative slope
Point left = new Point(midpoint.x - (width / (int)(Math.pow(2, level - 1))), midpoint.y);
Point middle = new Point(midpoint.x - (width / (int)(Math.pow(2, level))), midpoint.y + (height / (int)(Math.pow(2, level - 1))));
lines[0] = new Line(midpoint, left);
lines[1] = new Line(midpoint, middle);
lines[2] = new Line(middle, left);
}
else if (slope < 0) { // positive slope
Point right = new Point(midpoint.x + (width / (int)(Math.pow(2, level - 1))), midpoint.y);
Point middle = new Point(midpoint.x + (width / (int)(Math.pow(2, level))), midpoint.y + (height / (int)(Math.pow(2, level - 1))));
lines[0] = new Line(midpoint, right);
lines[1] = new Line(midpoint, middle);
lines[2] = new Line(middle, right);
}
else { //zero slope
Point left = new Point(midpoint.x - (width / (int)(Math.pow(2, level))), midpoint.y - (height / (int)(Math.pow(2, level - 1))));
Point right = new Point(midpoint.x + (width / (int)(Math.pow(2, level))), midpoint.y - (height / (int)(Math.pow(2, level - 1))));
lines[0] = new Line(midpoint, left);
lines[1] = new Line(midpoint, right);
lines[2] = new Line(left, right);
}
return lines;
}
}
答案 1 :(得分:2)
您的代码存在严重的Swing线程问题。为了解决这个问题,你真的应该绘制一个BufferedImage,关闭事件调度线程(EDT),然后在完成的EDT 时显示图像。从BufferedImage获取Graphics对象。我会在SwingWorker<BufferedImage, Void>
中执行此操作。或者,如果您需要显示临时图像,则SwingWorker<BufferedImage, BufferedImage>