调整大小后JPanel背景图像不填充面板

时间:2013-12-11 23:25:40

标签: java swing user-interface resize jpanel

我正在尝试使背景图像调整大小以始终适合它所在的JPanel。当程序运行时,它看起来不太好:

enter image description here

我遇到的问题是,在调整窗口大小后,它看起来像是这样:

enter image description here

显然,图像正在调整大小,但由于某种原因,图像并未完全绘制。这是一个更大的应用程序的一部分,但我已经隔离了产生问题的最小代码子集:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ScaleTest extends JPanel {
static JFrame window;
static JPanel mainPanel;

BufferedImage originalImage;
BufferedImage scaledImage;

ScaleTest() {
    setPreferredSize(new Dimension(320, 200));
    try {
        originalImage = ImageIO.read(new File("cat.jpg"));
    } catch(Exception e){}

    addComponentListener(new ResizerListener());
}

public void resize() {
    double widthScaleFactor = getWidth() / (double)originalImage.getWidth();
    double heightScaleFactor = getHeight() / (double)originalImage.getHeight();
    double scaleFactor = (widthScaleFactor > heightScaleFactor)? heightScaleFactor : widthScaleFactor;

    AffineTransform at = new AffineTransform();
    at.scale(scaleFactor, scaleFactor);

    AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
    scaledImage = scaleOp.filter(originalImage, scaledImage);

    repaint();
}

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

    g.drawImage(scaledImage, 0, 0, null);
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run(){
            window = new JFrame("Scale Test");
            window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

            mainPanel = new ScaleTest();
            window.getContentPane().add(mainPanel);

            window.pack();
            window.setLocationRelativeTo(null);  // positions window in center of screen
            window.setVisible(true);
        }
    });
}

class ResizerListener implements ComponentListener {
    @Override
    public void componentResized(ComponentEvent e) {
        resize();
    }

    @Override public void componentHidden(ComponentEvent e) {}
    @Override public void componentMoved(ComponentEvent e) {}
    @Override public void componentShown(ComponentEvent e) {}
}
}

如何绘制图像并填充整个JPanel?

2 个答案:

答案 0 :(得分:2)

问题是,scaledImage的大小在后续重新调整时没有改变。

这是因为您正在将scaledImage的引用传递给filter方法,该方法将其用作生成操作的基础,而不是生成新图像(大小合适) )

而不是

scaledImage = scaleOp.filter(originalImage, scaledImage);

尝试使用

scaledImage = scaleOp.filter(originalImage, null);

它第一次运作的原因是因为scaledImage null开头是

答案 1 :(得分:1)

当我尝试使用建议的更改代码时,我发现重新绘制有点不稳定。当您增加框架的大小时,在绘制面板背景之前在前缘绘制黑色背景(我在Windows 7上使用JDK7_10)。缩小框架不会导致问题。我认为这是因为ComponentListener和图像的重新创建。

不需要ComponentListener。您可以使用以下代码动态调整图像大小:

super.paintComponent(g);

double widthScaleFactor = getWidth() / (double)originalImage.getWidth();
double heightScaleFactor = getHeight() / (double)originalImage.getHeight();
double scaleFactor = (widthScaleFactor > heightScaleFactor)? heightScaleFactor : widthScaleFactor;

int width = (int)(originalImage.getWidth() * scaleFactor);
int height = (int)(originalImage.getHeight() * scaleFactor);

g.drawImage(originalImage, 0, 0, width, height, null);

不知道图像质量是否相同,因为我不知道BILINEAR是做什么的。