gpt4 book ai didi

java - JSlider changeListener 不会更新 - Java

转载 作者:行者123 更新时间:2023-11-30 08:52:39 25 4
gpt4 key购买 nike

我有一个分形树生成器,我试图让 slider 控制迭代次数,但我无法让它工作。此外,只要调用 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);
}
}

最佳答案

两个主要问题:

  1. 您正在覆盖 paint 而不是 paintComponent
  2. 您没有将 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);
}

其他需要考虑的事情:

  • 将 slider 添加到 BorderLayout.PAGE_START 位置的框架而不是面板。如果将其添加到面板,则可能会在 slider 所在的位置进行绘制。
  • 在面板而不是框架上设置背景颜色。
  • 无需在构造函数中调用super(),它是自动的。
  • setResizable(false) 通常应避免在框架上使用。无需限制用户的空间。
  • 在框架上调用 pack() 而不是 setSize(...)。后者过于依赖本 map 形配置。
    • 您需要重写面板的 getPreferredSize 方法以返回绘图的正确尺寸。
  • 您的像素计算应调整为使树与面板的左上角对齐,而不是从底部的任意位置开始,这会导致您损失大量屏幕空间:<

enter image description here

回复评论

Why paintComponent should be used?

查看这些:

public void paint(Graphics g)

This method actually delegates the work of painting to three protected methods: paintComponent, paintBorder, and paintChildren. They're called in the order listed to ensure that children appear on top of component itself. [...] A subclass that just wants to specialize the UI (look and feel) delegate's paint method should just override paintComponent.

您看到,如果您重写 paint 并将 slider 添加到面板,您会遇到 slider 绘制问题,因为您忽略了 paintChildren

What calling the superclass constructor does?

最好的答案是 JLS:

JLS 8.8.7. Constructor Body

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.

所以调用 super() 什么都不做。

关于java - JSlider changeListener 不会更新 - Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30116062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com