Java绘制方法闪烁和消失

时间:2011-02-05 21:28:28

标签: java user-interface swing

您好我一直试图通过改变我制作的绘制mandelbrot集的程序来搞乱Java GUI,但是当我在paint方法中放置if语句时它会使图像在屏幕上闪烁然后擦除到黑屏。

这是我的绘画方法:

public void paintComponent(Graphics g)
{
    if (clicked == false && count == 0)
    {

        drawMandelbrot(g); //sends graphics object to the method that draws the Mandelbrot set
        clicked = !clicked;
    }

    zoom(g);
    repaint();

}

public void zoom(Graphics g)
{

    if (count > 0 && clicked == false)
    {
        g.setColor(Color.white);
        g.fillRect(0,0, 400, 400);

        clicked = !clicked;
    }
}

我知道drawMandelbrot()函数没有错,因为它之前有效,我知道它不应该是zoom()函数,因为只有在mousePressed时才会增加count。

任何想法?!我已经尝试过评论这么多的部分,有时它会留在屏幕上,但是我再次运行它并没有。 Swing / AWT这个不稳定吗?

更新:

我发现问题与设置背景颜色有关。我在主函数中设置了框架的背景颜色,但由于某些原因(我仍然不知道)在绘制图像后,它再次在其上设置背景颜色。

public Mandelbrot (int w, int h) //constructor method that is only utilized to bring in the size of the screen
{
    this.setBackground(Color.BLACK);
    addMouseListener(this);
    clicked = false;
    count = 0;
}

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (clicked == false && count == 0)
    {

        drawMandelbrot(g); //sends graphics object to the method that draws the Mandelbrot set
        clicked = !clicked;
    }

    zoom(g);

}

public void zoom(Graphics g)
{

    if (count > 0 && clicked == false)
    {
    }
}
public void mouseReleased(MouseEvent e) 
{
        zoomX = e.getX();
        count ++;
        clicked = !clicked;
        repaint();
        System.out.print(clicked);
}

更新2: 它仍然不起作用,它第一次工作,但我尝试再次运行它和之前发生的相同的事情,它以黑框结束。

2 个答案:

答案 0 :(得分:1)

调用方法调用顶部的super.paintComponent(),让Swing句柄绘制组件的其余部分。有关painting components in Swing的更多信息,请参阅此文章。但基本上,paintComponent()方法正在绘制您尝试显示的组件的实际工作,当您覆盖它时,所有组件都会被禁用。通过调用super.paintComponent(),您可以使用Swing执行正确绘制所有内容所需的操作,然后它也可以绘制您想要绘制的内容。

<强>更新 我想知道这与你关于“点击”的逻辑是否有关。当您致电repaint()时,它会从头开始重新绘制整个面板。这意味着如果你想要随着时间的推移持续存在,你要么需要a)不要调用重绘,也不要让Swing调用重绘,例如调整窗口大小;或b)确保您的重绘方法始终描绘您想要的内容。一般来说,b)是更好的方法,因为它更健壮。

所以我会尝试重构你的代码,使它在paintComponent()方法中没有任何条件,这样无论调用多少次,对象仍然会被绘制。

您可能遇到的问题(可能这就是您按照自己的方式构建代码的原因)是构建您想要绘制的对象所花费的时间可能太长而无法一直重新绘制。如果这是一个问题,您需要重做程序的逻辑,以便计算您想要在另一个线程中绘制的内容(请参阅SwingUtilities.invokeLater()),然后当您调用paintComponent()时,只需绘制先前计算的值。

答案 1 :(得分:0)

在每个方法的开头添加System.out.println( 列表相关变量 );,以便清楚了解其发生的顺序。

了解zoom(g)中发生的情况会很有用,因为您没有将其包括在内。

更正帖子以便正确格式化mouseReleased方法也很有用。我第一次错过了它! :)

有些逻辑似乎有点......不确定。

两个if语句都检查clicked==false,但只有在每次鼠标释放后才会出现第一个paintComponent。我不是Swing专家,我只能将我的知识建立在AWT上,但是不经常调用paintComponent函数吗?它可能是绘画一次,然后被召回,再次绘画 - 只有这次(clicked==false)才是真的。因此'闪现'。

我建议将mandlebrot绘制成图像,然后使用getGraphics().drawImage(img, 0, 0 null);将图像复制到组件中,然后您只需在每个颜料中点亮现成的图像。

以下代码完全未经测试。我对此不承担任何责任。 ; - )

BufferedImage mbrot = null;
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (mbrot==null || mbrot.getWidth()!=getWidth() || mbrot.getHeight()!=getHeight())
    {
        mbrot = new BufferedImage(getWidth(), getHeight(), null);
    }
    if (clicked == false)
    {
        Graphics mg = mbrot.getGraphics();
        if (count==0)
        {
            drawMandelbrot(mg); //sends graphics object to the method that draws the Mandelbrot set
            clicked = !clicked;
        }
        else
        {
            zoom(mg);
        }
        mg.dispose();
    }
    g.drawImage(mbrot, 0, 0, null);
}