Java 摆动,调整大小,然后绘制

Java 摆动,调整大小,然后绘制,java,image,swing,Java,Image,Swing,我有一张画在JFrame上的图片。图像的尺寸取决于JFrame的尺寸 绘制JFrame的频率明显高于实际重新调整JFrame的大小。因此,我将图像重新调整大小,然后将其存储在component re size事件中,并且仅在draw方法中绘制重新调整大小的图像 //called on componentResized private void scaleImage(){ if((this.getHeight() * this.getWidth()) != 0) scall

我有一张画在JFrame上的图片。图像的尺寸取决于JFrame的尺寸

绘制JFrame的频率明显高于实际重新调整JFrame的大小。因此,我将图像重新调整大小,然后将其存储在component re size事件中,并且仅在draw方法中绘制重新调整大小的图像

//called on componentResized
private void scaleImage(){
    if((this.getHeight() * this.getWidth()) != 0)
        scalledBackGroundImage = backGroundImage.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_FAST);
    else
    scalledBackGroundImage = null;
}

@Override
public void paint(Graphics g){
    if(scalledBackGroundImage != null)
        g.drawImage(scalledBackGroundImage, 0, 0, this);

    super.paint(g);
}
但是,当重新绘制组件时,似乎会在绘制之后调用“重新调整大小”事件。因此,显示的图像是前一帧大小的图像。对于像最大化或最小化这样的操作,这确实会成为一个问题

我正在寻找一种在调用paint之前检测JFrame重新调整大小的方法。 (我知道我可以在重新调整大小时调用repaint(),但在重新调整大小时要求绘制两次组件似乎有点粗鲁)


感谢您的帮助。

将组件侦听器添加到JFrame作为

 jFrame.addComponentListener(new ComponentAdapter() {

            public void componentResized(ComponentEvent e) {
               //Your resize method here
            }
        });

将组件侦听器添加到JFrame作为

 jFrame.addComponentListener(new ComponentAdapter() {

            public void componentResized(ComponentEvent e) {
               //Your resize method here
            }
        });
看。这真的不是一个很好的选择

您不仅遇到了上面描述的问题,而且我还看到很多闪烁:

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.*;
import java.io.*;

public class ResizeSSCCE extends JPanel
{
    Image original;
    Image scaled;

    public ResizeSSCCE()
    {
        original = new ImageIcon( "mong.jpg" ).getImage();
        scaled = original;
        scaleImage();

        ComponentListener cl = new ComponentAdapter()
        {
            @Override
            public void componentResized(ComponentEvent e)
            {
                scaleImage();
            }
        };

        addComponentListener(cl);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        if (scaled != null)
            g.drawImage(scaled, 0, 0, this);
//          g.drawImage(original, 0, 0, getWidth(), getHeight(), this);
    }

    private void scaleImage()
    {
        if (getHeight() * getWidth() != 0)
            scaled = original.getScaledInstance(getWidth(), getHeight(), Image.SCALE_FAST);
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("ResizeSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ResizeSSCCE() );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}
更改代码以使用图像,然后使用缩放版本运行以查看闪烁。然后更改代码以使用苍蝇缩放的原始图像来查看差异。正如文章所建议的,动态扩展是更好的方法。

请参阅。这真的不是一个很好的选择

您不仅遇到了上面描述的问题,而且我还看到很多闪烁:

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.*;
import java.io.*;

public class ResizeSSCCE extends JPanel
{
    Image original;
    Image scaled;

    public ResizeSSCCE()
    {
        original = new ImageIcon( "mong.jpg" ).getImage();
        scaled = original;
        scaleImage();

        ComponentListener cl = new ComponentAdapter()
        {
            @Override
            public void componentResized(ComponentEvent e)
            {
                scaleImage();
            }
        };

        addComponentListener(cl);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        if (scaled != null)
            g.drawImage(scaled, 0, 0, this);
//          g.drawImage(original, 0, 0, getWidth(), getHeight(), this);
    }

    private void scaleImage()
    {
        if (getHeight() * getWidth() != 0)
            scaled = original.getScaledInstance(getWidth(), getHeight(), Image.SCALE_FAST);
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("ResizeSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ResizeSSCCE() );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

更改代码以使用图像,然后使用缩放版本运行以查看闪烁。然后更改代码以使用苍蝇缩放的原始图像来查看差异。正如文章所建议的,动态缩放是更好的方法。

为了更快地获得更好的帮助,请发布一个。在这种情况下,我将避免每次调整组件大小时都尝试调整图像大小,因为可以想象,
componentresistized
可能会在实现组件的实际大小之前被多次调用。相反我添加了一个具有短延迟(可能是125毫秒)的
javax.swing.Timer
,并在每次调用该方法时重新启动它。当定时器被触发时,我实际上会调整图像的大小。这减少了我可能需要将图像调整到更合理大小的次数,节省了时间和内存。为了更快地提供帮助,请发布一篇文章。在这种情况下,我将避免每次调整组件大小时都尝试调整图像大小,这是可以想象的,
componentResistized
可以在实现组件的实际大小之前调用多次。相反我添加了一个具有短延迟(可能是125毫秒)的
javax.swing.Timer
,并在每次调用该方法时重新启动它。当定时器被触发时,我实际上会调整图像的大小。这减少了我可能需要将图像调整到更合理的大小的次数,节省了时间和记忆。这可能是错误的(问题有点不清楚),但我认为这就是OP所做的…我可能是错误的(问题有点不清楚),但我认为这就是OP所做的…同意。停止担忧,学会热爱(信任)Swing组件的双重缓冲。:-)专业提示:确保使用兼容的图像,否则无论以何种方式缩放都会很慢。同意。停止担忧,学会热爱(信任)Swing组件的双重缓冲。:-)专业提示:确保使用兼容的图像,否则无论以何种方式缩放都会很慢。