首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSlider changeListener不会更新- Java

JSlider changeListener不会更新- Java
EN

Stack Overflow用户
提问于 2015-05-08 04:56:39
回答 1查看 267关注 0票数 2

我有一个分形树生成器,我试图使滑块控制迭代的次数,但我无法使它工作。而且,每当调用repaint()方法时,布局就会变得一团糟。对如何解决这个问题有什么想法吗?

代码语言:javascript
复制
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);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-08 08:53:47

两个主要问题:

  1. 您正在重写paint而不是paintComponent
  2. 在重写的方法中,您不会首先调用super.paintComponent(g) (或者在您的例子中是super.paint(g))。

这就是你需要拥有的东西:

代码语言:javascript
复制
@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

见以下内容:

公共空隙涂料(图形g) 实际上,此方法将绘画工作委托给三种受保护的方法:paintComponentpaintBorderpaintChildren。它们按照列出的顺序被调用,以确保子组件出现在组件本身的顶部。..。一个只想专门化UI (外观和感觉)委托的paint方法的子类应该只覆盖paintComponent

您看到,如果覆盖paint并将滑块添加到面板中,则滑块绘制会出现问题,因为忽略了paintChildren

调用超类构造函数做什么?

最好的回答是JLS:

JLS 8.8.7.构造体 如果构造函数体不是以显式构造函数调用开始,并且被声明的构造函数不是原始类对象的一部分,那么构造函数体隐式地以超类构造函数调用"super();“开始,这是对其直接超类构造函数的调用,它不带参数。

因此,打电话给super()什么都不做。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30116062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档