【问题标题】:JPanel Image only updates after the paintComponent loop endsJPanel Image 仅在paintComponent 循环结束后更新
【发布时间】:2015-09-25 14:31:05
【问题描述】:

目前,我的paintComponent 看起来是这样的:

    @Override
    public void paintComponent(Graphics g) {
    super.paintComponent(g);
    System.out.println(choice);
    if(choice == 1)
    {   
        g.drawImage(img, 0, 0, getWidth(), getHeight(), this);

        System.out.println("\nImgWidth: " + img.getWidth()
                + "\nFrameWidth: " + getWidth()
                + "\nImgHeight: " + img.getHeight()
                + "\nFrameHeight: " + getHeight()
        );
    }
    else if (choice == 2)
    {
        scale = 3.0;
        while(currScale < scale){
            currScale += .1;
            System.out.println(currScale + "-" + scale);

            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            int w = getWidth(); 
            int h = getHeight(); 
            int imageWidth = img.getWidth(); 
            int imageHeight = img.getHeight(); 
            double x = (w - currScale * imageWidth)/2;
            double y = (h - currScale * imageHeight)/2; 
            AffineTransform at = AffineTransform.getTranslateInstance(x,y);
            at.scale(currScale, currScale);
            g2.drawRenderedImage(img, at); 
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {}

        }
    }

}

当我忘记循环并且只使用固定的比例值时,该代码可以工作,但我希望它具有动画效果而不是立即缩放。我尝试使用 Timer 替代方案,但没有显示任何内容,并且图像在触发 paintComponent 并且选择为 2 的那一刻消失。

使用 sleep 方法,缩放后的图像会显示出来,但只会在循环之后显示。在循环之前和循环期间,它仍然显示原始完整图像。它的运行就像循环的整个点(动画)是毫无意义的,因为更改仅在它退出时发生。

感谢任何帮助。

另外,如果你们中有人想知道我是如何弄乱计时器的,这是我的代码(它删除了原始图像并且根本没有显示任何内容,但计时器确实终止了)

   else
    {
        scale = 3.0;
            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

        if(currScale < scale){
            System.out.println(currScale + "-" + scale);
            currScale += .1;
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        int w = getWidth();
        int h = getHeight();
        int imageWidth = img.getWidth();
        int imageHeight = img.getHeight();
        double x = (w - currScale * imageWidth)/2;
        double y = (h - currScale * imageHeight)/2;
        AffineTransform at = AffineTransform.getTranslateInstance(x,y);
        at.scale(currScale, currScale);
        g2.drawRenderedImage(img, at);
        }
                }


            });

         if(currScale > scale)
        {
             timer.stop();
        }
         else
         {
             timer.setRepeats(true);
             timer.setCoalesce(true);
             timer.start();  
         }
    }

这是我的类属性的sn-p:

 class loadImage extends JPanel {
 private int choice;
 double scale;
 double currScale = 1.0;
 BufferedImage img;
 //Timer timer; (if using the timer)

修复: 为了添加一些上下文,我使用了 Netbean 的 GUI-Builder。每次我需要使用 loadImage 的方法时,我都会选择手动将面板类型转换为 loadImage 类。

    public void ZoomIn() {
    double scale = 3.0;
    double scaleAddOn = 0.1;
    Timer timer;
    timer = new Timer(40, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) 
        {
            double currScale;
            currScale = ((loadImage)imageArea).getCurrScale();
            if(currScale < scale)
            {
                ((loadImage)imageArea).setCurrScale(currScale + scaleAddOn);
            }
        }
    });

    if(((loadImage)imageArea).getCurrScale() > scale)
    {
         timer.stop();
    }
     else
     {
         timer.setRepeats(true);
         timer.setCoalesce(true);
         timer.start();  
     }
}    

再次感谢您的帮助。希望此页面对其他人也有用。

【问题讨论】:

    标签: java swing timer paintcomponent graphics2d


    【解决方案1】:

    当您从 JPanel 创建绘图面板时,paintComponent 方法会进行绘制或绘制。句号。 paintComponent 方法不做任何其他事情。没有 Thread.sleep。没有计算。随便画。

    由于你刚刚提供了一个paintComponent方法,我只提供了DrawingPanel类。

    package com.ggl.testing;
    
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JPanel;
    
    public class DrawingPanel extends JPanel {
    
        private static final long serialVersionUID = 506794466435048661L;
    
        private double currScale;
    
        private int choice;
    
        private BufferedImage img;
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            System.out.println(choice);
            if (choice == 1) {
                g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
                System.out.println("\nImgWidth: " + img.getWidth()
                        + "\nFrameWidth: " + getWidth() + "\nImgHeight: "
                        + img.getHeight() + "\nFrameHeight: " + getHeight());
            } else if (choice == 2) {
                Graphics2D g2 = (Graphics2D) g;
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                int w = getWidth();
                int h = getHeight();
                int imageWidth = img.getWidth();
                int imageHeight = img.getHeight();
                double x = (w - currScale * imageWidth) / 2;
                double y = (h - currScale * imageHeight) / 2;
                AffineTransform at = AffineTransform.getTranslateInstance(x, y);
                System.out.println("Pass");
                at.scale(currScale, currScale);
                System.out.println("Pass");
                g2.drawRenderedImage(img, at);
                System.out.println("Pass");
            }
        }
    
        public double getCurrScale() {
            return currScale;
        }
    
        public void setCurrScale(double currScale) {
            this.currScale = currScale;
            repaint();
        }
    
        public int getChoice() {
            return choice;
        }
    
        public void setChoice(int choice) {
            this.choice = choice;
        }
    
        public BufferedImage getImg() {
            return img;
        }
    
        public void setImg(BufferedImage img) {
            this.img = img;
        }
    
    }
    

    您可以使用 Runnable 类或 Swing Timer 来更新 currScale 值。

    【讨论】:

    • 所以避免添加除了paintComponent所做的之外的任何东西?在阅读了 setter 方法之后,我想我现在有了这个想法。我想知道计时器如何调用油漆。此外,您还为选择做出了我没有做出的选择,所以这是您回答的另一个优点。 实施后编辑:神圣的烟雾。我能够做到。非常感谢你的帮助。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多