谢尔宾斯基三角:不显示
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。这可能会更有效率。
什么都没有出现.. 我已经尝试将 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。这可能会更有效率。