初学者挥动递归
第一次在这里发帖 这个编程任务让我难以接受,代码如下:
import java.awt.*; import javax.swing.*; public class HTree extends JPanel { private Color color = new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256)); public void draw(Graphics g, int n, double sz, double x, double y) { if (n == 0) return; double x0 = x - sz/2, x1 = x + sz/2; double y0 = y - sz/2, y1 = y + sz/2; // draw the 3 line segments of the H g.setColor(color); g.drawLine((int)x0, (int)y, (int)x1, (int)y); g.drawLine((int)x0, (int)y0, (int)x0, (int)y1); g.drawLine((int)x1, (int)y0, (int)x1, (int)y1); // recursively draw 4 half-size // H-trees of order n-1 g.setColor(color); draw(g, n-1, sz/2, x0, y0); draw(g, n-1, sz/2, x0, y1); draw(g, n-1, sz/2, x1, y0); draw(g, n-1, sz/2, x1, y1); repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); draw(g, 3, .5, .5, .5); } public static void main(String[] args) { HTree h = new HTree(); JFrame application = new JFrame("HTree"); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); application.add(h); application.setSize(1000, 1000); application.setVisible(true); } }
它编译正确,但在运行程序时,我得到的是一个空的JFrame。 我不太熟悉swing,但我认为问题是HTree构造函数是错误的,或者我可能需要在main中调用draw(),但不知道如何使用Graphics对象调用它。 任何帮助表示赞赏,谢谢!
一些观察:
-
使用相对于面板当前大小的整数坐标。
-
重写
getPreferredSize()
以建立初始几何。 -
使用
Color.getHSBColor()
获得明亮饱和的色彩; 例如,考虑创建色域,在每个级别选择不同的色调。 -
仅在事件派发线程上构造和操作Swing GUI对象。
-
考虑使用
JSpinner
或JSlider
以交互方式控制递归深度,如此处和此处所建议的那样。 -
不要递归地调用
repaint()
; 使用它来调度对paintComponent()
实现的调用,就像递归深度响应某些输入一样。 -
考虑使用
setStroke()
和渲染提示,如下所示。 -
考虑使用
javax.swing.Timer
,每次调用ActionListener
时,递归深度增加一级。
import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; /** * @see https://stackoverflow.com/a/37450393/230513 */ public class HTree { private void display() { JFrame f = new JFrame("HTree"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new Tree()); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } private static class Tree extends JPanel { private final Color color = Color.getHSBColor((float) Math.random(), 1, 1); public void draw(Graphics g, int n, double sz, double x, double y) { if (n == 0) { return; } double x0 = x - sz / 2, x1 = x + sz / 2; double y0 = y - sz / 2, y1 = y + sz / 2; // draw the 3 line segments of the H g.setColor(color); g.drawLine((int) x0, (int) y, (int) x1, (int) y); g.drawLine((int) x0, (int) y0, (int) x0, (int) y1); g.drawLine((int) x1, (int) y0, (int) x1, (int) y1); // recursively draw 4 half-size // H-trees of order n-1 g.setColor(color); draw(g, n - 1, sz / 2, x0, y0); draw(g, n - 1, sz / 2, x0, y1); draw(g, n - 1, sz / 2, x1, y0); draw(g, n - 1, sz / 2, x1, y1); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); draw(g, 3, getWidth() / 2, getWidth() / 2, getHeight() / 2); } @Override public Dimension getPreferredSize() { return new Dimension(500, 500); } public static void main(String[] args) { EventQueue.invokeLater(new HTree()::display); } } }