绘制Sierpinski三角形分形图-Java

绘制Sierpinski三角形分形图-Java,java,swing,recursion,jpanel,paintcomponent,Java,Swing,Recursion,Jpanel,Paintcomponent,我的程序运行并成功地绘制了Sierpinski三角形。然而,它只出现了很短的一段时间,然后消失了。为什么会这样 这是我的课程(2节课)。这是完全可编译和可运行的 TrianglePanel.java 导入java.awt.Dimension; 导入java.awt.Graphics; 导入java.awt.Point; 导入java.util.ArrayList; 导入javax.swing.JFrame; 导入javax.swing.JPanel; 公共类TrianglePanel扩展了JPa

我的程序运行并成功地绘制了Sierpinski三角形。然而,它只出现了很短的一段时间,然后消失了。为什么会这样

这是我的课程(2节课)。这是完全可编译和可运行的

TrianglePanel.java

导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Point;
导入java.util.ArrayList;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类TrianglePanel扩展了JPanel{
智力水平=2;
整数宽度;
内部高度;
图形g;
公共静态void main(字符串[]agrs){
三角形面板=新的三角形面板();
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架设置尺寸(新尺寸(400400));
frame.setLocationRelativeTo(空);
框架。添加(面板);
frame.setVisible(true);
}
公共三角板(){
}
公共组件(图形g){
这个.g=g;
宽度=此.getSize().width;
高度=此.getSize().height;
ArrayList队列=新建ArrayList();
添加(新行(新点(宽度/2,0),新点(高度));
添加(新行(新点(0,高度),新点(宽度,高度));
添加(新行(新点(宽度、高度)、新点(宽度/2、0));
抽绳(queue.get(0));
抽绳(队列获取(1));
抽绳(队列获取(2));
int计数器=0;
while(true){
如果(级别>6){
试一试{
《睡眠》(2000年);
}捕捉(中断异常e){
e、 printStackTrace();
}
打破
}
行[]toDraw=queue.get(0).getTriangelTodraw(级别、宽度、高度);
点[]toDrawPoints=toDraw[0]。getPoints();
如果(Math.sqrt(((Math.pow(toDrawPoints[1].x-toDrawPoints[0].x,2))+(Math.pow(toDrawPoints[1].y-toDrawPoints[0].y,2)))0{//负斜率
左点=新点(中点.x-(宽度/(整数)(数学功率(2,级别-1))),中点.y);
中点=新点(中点.x-(宽度/(整数)(数学功率(2级))),中点.y+(高度/(整数)(数学功率(2级,1级)));
直线[0]=新线(中点,左侧);
线[1]=新线(中点、中间);
行[2]=新行(中间,左侧);
}
如果(斜率<0){//正斜率
右点=新点(中点x+(宽度/(整数)(数学功率(2,1级))),中点y);
中点=新点(中点x+(宽度/(整数)(数学功率(2级))),中点y+(高度/(整数)(数学功率(2级-1级));
直线[0]=新线(中点,右侧);
线[1]=新线(中点、中间);
第[2]行=新行(中间,右侧);
}
else{///零斜率
左点=新点(中点.x-(宽度/(整数)(数学功率(2级))),中点.y-(高度/(整数)(数学功率(2级,1级)));
点右=新点(中点.x+(宽度/(整数)(数学功率(2级)),中点.y-(高度/(整数)(数学功率(2级,1级)));
直线[0]=新线(中点,左侧);
直线[1]=新线(中点,右侧);
行[2]=新行(左、右);
}
回流线;
}
}

您的代码存在一些严重的Swing线程问题。要解决这个问题,您确实应该从事件调度线程(EDT)中提取一个buffereImage,,然后在EDT上完成后显示图像。从BuffereImage中获取图形对象。我会在
SwingWorker
中执行此操作。或者,如果需要显示临时图像,则
SwingWorker

您的代码存在一些严重的Swing线程问题。要解决此问题,您确实应该绘制n一个BuffereImage,关闭事件调度线程(EDT),然后在EDT上完成后显示图像。从BuffereImage中获取图形对象。我会在
SwingWorker
中执行此操作。或者如果需要显示临时图像,则
SwingWorker

这采用与@Hovercraft建议的方法类似的方法,但交换
SwingWorker
对于
计时器
,它调用
repaint()
,而不是为标签设置新图标

import java.awt.*;
导入java.awt.event.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
导入java.util.ArrayList;
公共类TrianglePanel扩展了JPanel{
智力水平=2;
整数宽度;
内部高度;
定时器;
缓冲图像画布;
JLabel标签;
公共静态void main(字符串[]agrs){
三角形面板=新的三角形面板();
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(真);
框架。添加(面板);
frame.pack();
frame.setVisible(true);
}
公共三角板(){
最终整数宽度=400;
最终内部高度=400;
画布=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_RGB);
标签=新JLabel(新图像图标(画布));
添加(标签);
final Graphics2D g=canvas.createGraphics();
g、 setRenderingHint(RenderingHits.KEY\u ANTIALIASING,RenderingHits.VALUE\u ANTIALIAS\u ON);
g、 setColor(新颜色(255127,0));
最终ArrayList队列=新ArrayList();
添加(新行(新点(宽度/2,0),新点(高度));
添加(新行(新点(0,高度),新点(宽度,高度));
添加(新行(新点(宽度、高度)、新点(宽度/2、0));
抽绳(队列获取(0),g);
抽绳(队列获取(1),g);
抽绳(队列获取(2),g);
ActionListener al=新的ActionListener(){
int计数器=0;
已执行的公共无效行动(行动事件ae){
如果(级别>6){
timer.stop();
返回;
}
行[]toDraw=queue.get(0).getTrian
    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);
    }
}
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;
    }
}
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;
    }
}