java - JPanel Image仅在paintComponent循环结束后更新

标签 java swing timer paintcomponent graphics2d

目前,我的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) {}

        }
    }

}

当我忘记循环并仅使用固定的缩放值时,代码可以工作,但我希望它是动画的而不是立即缩放。我尝试过使用计时器替代方案,但没有任何显示,并且在触发 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();  
         }
    }

这是我的类属性的片段:

 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();  
     }
}    

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

最佳答案

当您从 JPanel 创建绘图面板时,paintComponent 方法将进行绘图或绘图。句号。 PaintComponent 方法不执行任何其他操作。没有线程。 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 值。

关于java - JPanel Image仅在paintComponent循环结束后更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32784514/

相关文章:

javascript - 窗口最小化时,计时器 JavaScript 在 Chrome 和 Mozilla 中不运行

java - 创建 REST/JSON API

Java:ImageIcon 与图像差异

未识别该类型的 Java 方法

C# 休眠 500 毫秒

Javascript:如何更新我的事件监听器以仅在用户停止输入时进行更改?

java - 如何构建一个正则表达式来匹配包含子字符串中所有字符的任何字符串?

java - XPath 中的循环?

java - 如何让jtable成为jtree的一个节点

java - 遇到编译器错误 : Exception in Application start method.(这是简单的 JavaFX 程序)