将图片按照一定比率缩放成固定的大小,然后画在JComponent上。如果直接将JComponent添加到JFrame上,图片完美显示。如果先添加到JPanel再添加到JFrame内,将JFrame拖大之后,图片显示就有问题了。麻烦各位大侠帮忙看看是什么地方出了问题。代码如下
- Java code
import javax.imageio.*;import javax.swing.*;import java.awt.*;import java.awt.geom.*;import java.io.*;public class ImgP extends JFrame{ ImageCanvas ic; final double culculateRatio(int width, int height){//计算缩放比例 double ratio; if(getWidth()>=width && getHeight()>=height){ ratio = 1; return ratio; } if((double)getWidth()/width > (double)getHeight()/height) ratio = (double)getHeight() / height; else ratio = (double)getWidth() / width; return ratio; } public ImgP(){ Image image; double ratio; setSize(700, 500); try { image = ImageIO.read(new File("G:\\Image\\IMG_0783.jpg")); ratio = culculateRatio(image.getWidth(null),image.getHeight(null)); ic = new ImageCanvas(ratio); ic.setImage(image); //如果将add(ic)一行替换成以下代码,画图有误 //JPanel panel = new JPanel(); //panel.add(ic); //add(panel); add(ic); ic.concateZoom(ratio); } catch (IOException ex) { } } public static void main(String[] args) { ImgP ip = new ImgP(); ip.setVisible(true); ip.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }} class ImageCanvas extends JComponent{ Image img; double ratio; AffineTransform af = AffineTransform.getScaleInstance(1,1); public ImageCanvas(double ratio){ this.ratio = ratio; } void setImage(Image m){ img = m; paintImmediately(getBounds()); //concateZoom(0.3); } void concateZoom(double scale){ if (img==null)return; af.preConcatenate(AffineTransform.getScaleInstance(scale,scale)); paintImmediately(getBounds()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (img==null) { g.setColor(Color.BLACK); g.fillRect(0,0,getWidth(),getHeight()); } else { Graphics2D g2d = (Graphics2D)g; g2d.setTransform(af); g2d.drawImage(img, (int)(((getWidth()-img.getWidth(null)*ratio)/2)/ratio), (int)(((getHeight()-img.getHeight(null)*ratio)/2)/ratio), this); } } @Override public Dimension getPreferredSize() {return new Dimension(600, 400);} }
------解决方案--------------------
把JPanel panel = new JPanel();
修改成为
JPanel panel = new JPanel(new BorderLayout());试试看
------解决方案--------------------
FlowLayout是流布局,每个组件上下左右都有间隔,间隔太远就看不到了。
borderLayout是边框布局,每次放一个组件而又没有规定组件位置的话,默认放置到中间位置