我有一个分形树生成器,我正在尝试使滑块控制迭代次数,但我无法让它工作。此外,只要调用repaint()
方法,布局就会搞乱。关于如何解决这个问题的任何想法?
public class FractalTree extends JPanel implements ChangeListener {
static JSlider slider = new JSlider(0,12);
static int slideVal=7;
public FractalTree()
{
super();
slider.addChangeListener(this);
}
public void paint(Graphics g)
{
g.setColor(Color.green);
drawTree(g, 400, 750, 200, Math.toRadians(-90), Math.toRadians(45), slideVal); //Don't let # of iterations exceed 12, it is useless
}
private void drawTree(Graphics g, int x1, int y1, double l, double t, double dt, double iterations) {
if (iterations > 0) {
int x2 = x1 + (int) (l * Math.cos(t));
int y2 = y1 + (int) (l * Math.sin(t));
g.drawLine(x1, y1, x2, y2);
drawTree(g, x2, y2, l / 1.5, t + dt, Math.PI / 4, iterations - .5);
drawTree(g, x2, y2, l / 1.5, t - dt, Math.PI / 4, iterations - .5);
}
}
@Override
public void stateChanged(ChangeEvent e) {
slideVal=slider.getValue();
repaint();
}
public static void main(String[] args) {
JFrame t = new JFrame("Some swaggy fractal shit");
FractalTree tree = new FractalTree();
slider.setValue(slideVal);
slider.setMinorTickSpacing(1);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
tree.add(slider);
t.add(tree);
t.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
t.setResizable(false);
t.setLocationByPlatform(true);
t.setSize(800, 800);
t.setBackground(Color.black);
t.setVisible(true);
}
}
答案 0 :(得分:2)
两个主要问题:
paint
而不是paintComponent
。super.paintComponent(g)
(或者在您的情况下,super.paint(g)
)称为被覆盖方法中的第一件事。这是您需要的:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.green);
drawTree(g, 400, 750, 200, Math.toRadians(-90), Math.toRadians(45), slideVal);
}
需要考虑的其他事项:
BorderLayout.PAGE_START
上的框架而不是面板上。如果将其添加到面板,则可能会绘制滑块的位置。super()
,它是自动的。setResizable(false)
。无需限制用户的空间。pack()
而不是setSize(...)
。后者太依赖于本地图形配置。
getPreferredSize
方法,以便为图形返回正确的尺寸。
对评论的回应
为什么要使用
paintComponent
?
见这些:
public void paint(Graphics g)
此方法实际上将绘画工作委托给三个受保护的方法:
paintComponent
,paintBorder
和paintChildren
。它们按列出的顺序调用,以确保子项出现在组件本身之上。 [...]只想专门化UI(外观)委托的paint方法的子类应该覆盖paintComponent
。
您看到如果覆盖paint
并将滑块添加到面板,则滑块绘制出现问题,因为您忽略了paintChildren
。
调用超类构造函数的是什么?
最好回答的是JLS:
JLS 8.8.7。构造函数主体
如果构造函数体不是以显式构造函数调用开始并且声明的构造函数不是原始类Object的一部分,那么构造函数体隐式地以超类构造函数调用“super();”开头,调用它的直接超类的构造函数,不带参数。
所以调用super()
什么都不做。