[英]JPanel background image not filling panel after resize
我正在尝试调整背景图像的大小,以使其始终适合其所驻留的JPanel。 程序运行时看起来很完美:
我遇到的问题是,在调整窗口大小后,它看起来像这样:
显然,图像正在调整大小,但由于某些原因并未完全绘制。 这是一个更大的应用程序的一部分,但是我隔离了导致问题的最小代码子集:
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?
问题是, scaledImage
的大小在后续scaledImage
不会更改。
这是因为您将scaledImage
的引用传递给filter
方法,该方法将其用作结果操作的基础,而不是生成新图像(大小合适)
代替
scaledImage = scaleOp.filter(originalImage, scaledImage);
尝试使用
scaledImage = scaleOp.filter(originalImage, null);
它第一次起作用的原因是因为scaledImage
为null
开头
当我尝试带有建议更改的代码时,我发现重新绘制有点混乱。 随着您增加框架的大小,在绘制面板背景之前,先导边缘上会绘制黑色背景(我在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会做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.