我有一个要在JFrame上绘制的图像。图像的尺寸取决于JFrame的尺寸。
更频繁地绘制JFrame,然后实际重新调整JFrame的大小。因此,我将图像重新调整大小,然后存储在组件重新调整大小事件中,并且仅在绘制方法中绘制重新调整大小的图像。
//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);
}
但是,我似乎在重绘组件时在绘制后调用re-size事件。因此,显示的图像是前一帧尺寸的图像。这实际上成为最大化或最小化等行为的问题。
我正在寻找一种方法来在调用paint之前检测JFrame重新调整大小。 (我知道我可以在re-size上调用repaint()但是在重新调整大小时要求将组件绘制两次似乎有点粗鲁)
感谢您的帮助。
答案 0 :(得分:3)
见The Perils of Image.getScaledInstance()。这真的不是一个很好的选择。
你不仅遇到了上面描述的问题,而且还有很多闪烁的问题:
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();
}
});
}
}
更改代码以使用您的图像,然后使用缩放版本运行以查看闪烁。然后更改代码以使用原始图像作为苍蝇的比例来查看差异。正如文章所说,即时扩展是更好的方法。
答案 1 :(得分:1)
将组件侦听器添加到JFrame
jFrame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
//Your resize method here
}
});