谢尔宾斯基三角:不显示

Sierpinski Triangle: not displaying

什么都没有出现.. 我已经尝试将 Random rand = new Random() 移到循环之外,但它仍然根本不起作用。 框架也不会在关闭时退出。

public class myMain {

    public static void main(String args[]) {
        Frame frame = new Frame();
    }
}


public class Frame extends JFrame {

    public Frame(){
        super("Fancy Triangle");
        setSize(1024, 768);

        myPanel panel = new myPanel();
        add(panel);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

}

public class myPanel extends JPanel {

    int x1 = 512;

    int y1 = 109;

    int x2 = 146;
    int y2 = 654;

    int x3 = 876;
    int y3 = 654;

    int x = 512;
    int y = 382;

    int dx, dy;

    Random rand;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        for (int i = 0; i < 50000; i++) {

            g.drawLine(x, y, x, y);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            rand = new Random();
            int random = 1 + rand.nextInt(3);

            if (random == 1) {
                dx = x - x1;
                dy = y - y1;

            } else if (random == 2) {
                dx = x - x2;
                dy = y - y2;

            } else {
                dx = x - x3;
                dy = y - y3;

            }

            x = x - (dx / 2);
            y = y - (dy / 2);

        }
    }
}

这个:

Thread.sleep(300);

没有按您的意愿行事。我认为您正在尝试延迟绘制,但这不是它的作用。相反,您在 Swing 事件线程上调用 sleep 会使整个应用程序进入睡眠状态,因为该线程无法执行它需要执行的操作,包括绘制应用程序和与用户交互。更糟糕的是,您是在绘画方法中执行此操作,这种方法需要非常快,因为 Swing 应用程序的感知响应能力通常由绘画速度决定。

改为使用 Swing 定时器 (Swing Timer tutorial) 来更改 class 字段的状态,然后调用重绘。让您的 paintComponent 使用那些更改的字段来决定要绘制什么以及在哪里绘制。由于 Sierpinski 三角形是由点组成的,请考虑创建一个 ArrayList<Point>,摆脱绘画方法中的 for 循环,并使用 Swing Timer 替换此 for 循环。在 Timer 的 ActionListener 中,将 semi-random 点放入 ArrayList 并调用重绘。然后在 paintComponent 中,遍历 ArrayList,绘制它包含的每个点。

或者,您可以在 Swing Timer 中将这些点绘制到 BufferedImage 上,然后让您的 paintComponent 通过 g.drawImage(...) 方法调用显示 BufferedImage。这可能会更有效率。