【问题标题】:no repaint while resizing when using .setPaint(gradient)使用 .setPaint(gradient) 调整大小时不重绘
【发布时间】:2012-08-20 12:05:02
【问题描述】:

一旦我在我的代码中使用渐变,在调整大小时没有完成重绘我在调整大小时得到类似的东西(已调整大小的黑色矩形,请参见下面链接中的图像)。当我停止调整大小时,一切都会再次绘制,但只有那时。

如果我不使用g2d.setPaint(gradient);,我会快速重绘

http://gui-builder.com/C41142775162.rar

public void paintComponent(Graphics g)  
{  

        super.paintComponent(g);  

        Graphics2D g2d = (Graphics2D)g;  

        //sample of the code  
        GradientPaint gradient = new GradientPaint(startX, startY, greyColor1, endX, endY, new Color(120,120,120));  
        g2d.setPaint(gradient);  
        g.drawLine(i, startY, i, endY);  
}  

我尝试repaint() 调整大小,我尝试repaint() 拖动鼠标但没有。


这是一些 SSCCE(抱歉我之前没有发布过):

缓冲图像 aa;

@Override  
public void paintComponent(Graphics g)  
{  
        super.paintComponent(g);  

        Graphics gr = aa.getGraphics();  
        Graphics2D g2d = (Graphics2D)gr;  

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,  
                    RenderingHints.VALUE_ANTIALIAS_ON);  


        for (int i = 0; i < this.getWidth(); i++)  
        {  
            LinearGradientPaint lgp = new LinearGradientPaint(
            new Point2D.Float(0, 0),
            new Point2D.Float(0, this.getHeight()),
            new float[] {0f, 0.5f, 1f},
            new Color[] {Color.BLUE, Color.RED, Color.BLUE}
            ); 
            g2d.setPaint(lgp);  
            gr.drawLine(i, 0, i, this.getHeight());  
        }  
        g.drawImage(aa, 0, 0, frame);  
}  

在你的构造函数中:

aa = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);

我仍然需要一个答案,为什么当我调整窗口大小时没有完成重绘(当我移动窗口的调整大小角时)


好的,总结一下: 我尝试了三种主要的 Java 绘图方法,它们是 BufferStrategy、双 Swing 缓冲图像和没有图像缓冲区的简单 Swing。 我发现速度更快的是最后一个(令人惊讶)。

现在我使用的是快速的,我发现首先将窗口大小调整为小尺寸然后将窗口大小调整为大尺寸会使问题消失。别笑那是我的问题,这完全是个谜。 这是它的视频:C41142775162.rar

当我调整为小尺寸时会发生什么?我不知道。但如果您知道任何帮助将不胜感激。

谢谢

杰夫


我还发现最好尽可能少地使用 setPaint。您可以运行测试,您会发现不经常使用 setPaint() 会快得多。例如,而不是使用:

LinearGradientPaint gradient1 = new LinearGradientPaint(
        new Point2D.Float(0, 0),
        new Point2D.Float(0, 10),
        new float[] {0f, 1f},
        new Color[] {new Color(40,40,40), new Color(110,110,110)}
    );
LinearGradientPaint gradient2 = new LinearGradientPaint(
        new Point2D.Float(0, 10),
        new Point2D.Float(0, 20),
        new float[] {0f, 1f},
        new Color[] {new Color(110,110,110), new Color(190,190,190)}
    );
LinearGradientPaint gradient3 = new LinearGradientPaint(
        new Point2D.Float(0, 20),
        new Point2D.Float(0, 30),
        new float[] {0f, 1f},
        new Color[] {new Color(190,190,190), new Color(250,250,250)}
    );                        
for (int i = 0; i < this.getWidth(); i++)
{
    g2d.setPaint(gradient1);
    gr.drawLine(i, 0, i, 10);
    g2d.setPaint(gradient2);
    gr.drawLine(i, 10, i, 20);
    g2d.setPaint(gradient3);
    gr.drawLine(i, 20, i, 30);                            
}

使用:

LinearGradientPaint gradient1 = new LinearGradientPaint(
        new Point2D.Float(0, 0),
        new Point2D.Float(0, 10),
        new float[] {0f, 1f},
        new Color[] {new Color(40,40,40), new Color(110,110,110)}
    );
LinearGradientPaint gradient2 = new LinearGradientPaint(
        new Point2D.Float(0, 10),
        new Point2D.Float(0, 20),
        new float[] {0f, 1f},
        new Color[] {new Color(110,110,110), new Color(190,190,190)}
    );
LinearGradientPaint gradient3 = new LinearGradientPaint(
        new Point2D.Float(0, 20),
        new Point2D.Float(0, 30),
        new float[] {0f, 1f},
        new Color[] {new Color(190,190,190), new Color(250,250,250)}
    );                         

g2d.setPaint(gradient1);
for (int i = 0; i < this.getWidth(); i++)
     gr.drawLine(i, 0, i, 10);

g2d.setPaint(gradient2);
for (int i = 0; i < this.getWidth(); i++)
    gr.drawLine(i, 10, i, 20);

g2d.setPaint(gradient3);
for (int i = 0; i < this.getWidth(); i++)
    gr.drawLine(i, 20, i, 30); 

即使你有很多计算,它几乎每次都会更快!

【问题讨论】:

  • 1) 请学习如何使用代码格式化。选择代码并单击{} 按钮。 2) 为了尽快获得更好的帮助,请发帖SSCCE
  • 停止调整大小是什么意思?你释放鼠标了吗?
  • 停止调整大小我的意思是停止移动窗口的调整大小角

标签: java swing image-resizing repaint paintcomponent


【解决方案1】:

我做了一个测试,发现GradientPaint 的性能很差。平均渲染时间从 1.2 秒(400x400 像素)缩短到 20 多秒。

我将GradientPaint 更改为LinearGradientPaint,发现渲染时间约为1.3 秒。

LinearGradientPaint lgp = new LinearGradientPaint(
                new Point2D.Float(0, minY),
                new Point2D.Float(0, maxY),
                new float[] {0f, 0.5f, 1f},
                new Color[] {Color.BLUE, Color.RED, Color.BLUE}
                );
g2d.setPaint(lgp);
    // Render all your samples, don't reapply or change you paint...

抱歉,我的示例不太令人兴奋...

您可能会发现在后台线程中渲染到后备缓冲区并在完成后将整个图像绘制到屏幕上会更好。这将阻止屏幕“暂停”

【讨论】:

  • +1 一如既往的好。大到你积累的疯狂代表:O 没有双关语
  • @DavidKroukamp 我无法相信我在过去几个月中学到的数量。不仅来自人们的答案,还来自探索寻找答案的问题。仍然让我大吃一惊!
  • 感谢您的回答,非常棒。我试过了,但我仍然遇到“调整大小时不重绘”的问题。我在尝试 BufferStrategy 时使用了一个缓冲区(我也尝试过没有 BufferStrategy 和一个普通的 Swing 双缓冲区)。当我调整大小时,每 1 毫秒重绘一次的线程仍然会阻止重绘。
  • 我制作了一个小视频向您展示它在做什么:gui-builder.com/mov.rar
  • 首先我想说的是,我尝试了三种主要的Java绘图方法,即BufferStrategy、双Swing缓冲图像和无图像缓冲的简单摆动。我发现速度更快的是最后一个(令人惊讶)。现在我正在使用快速的,我发现首先将窗口调整为小窗口然后将窗口调整为大窗口会使问题消失。这完全是个谜。
【解决方案2】:

如果这是一个小程序,把那个东西放进去

public void start()
{
}

public void stop()
{
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多