我有一个JScrollPanel,我向JPanel添加了一个包含图像的JScrollPanel,它可以工作,但是,如果JPanel中的图像大于JScrollPanel的宽度,高度或两者,然后将面板尺寸调整为约20x20。为什么这样做呢?我在GridBagLayout的视口上使用JScrollPanel。我所期望的是,如果JPanel大于JScrollPanel,它将添加滚动条,但事实并非如此。有什么建议么?

private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
    WebFileChooser wfc = null;
    if(wfc == null){
        wfc = new WebFileChooser(this, "Open an Image");
        wfc.setSelectionMode(SelectionMode.SINGLE_SELECTION);
        wfc.setAvailableFilter(GlobalConstants.IMAGES_AND_FOLDERS_FILTER);
        wfc.setChooseFilter(GlobalConstants.IMAGES_FILTER);
        wfc.setCurrentDirectory("/Users/Ryan/Desktop");
    }
    wfc.setVisible(true);

    if(wfc.getResult() == StyleConstants.OK_OPTION){
        String file = wfc.getSelectedFile().getPath();
        try{
            imagePane.remove(canvas);
        }catch(Exception e){
        }
        canvas = new Canvas();
        canvas.setVisible(true);
        canvas.setImage(file);
        //imagePane.getViewport().setLayout(new GridBagLayout());
        canvas.setSizeFromLoaded();
        imagePane.getViewport().add(canvas);
        imagePane.repaint();
        imagePane.revalidate();
    }
}


这是画布类:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pocketshop;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import pocketshop.util.ImageSync;

/**
 *
 * @author Ryan
 */
public class Canvas extends CanvasShadow{

    public static BufferedImage image = null, preview = null;
    public static int width, height;

    public void setImage(String filename){
        try{
            Canvas.image = ImageIO.read(new File(filename));
            Canvas.width = image.getWidth();
            Canvas.height = image.getHeight();
            ImageSync.originalPixels = new int[width * height];
            ImageSync.previewPixels = new int[width * height];
            Canvas.image.getRGB(0, 0, width, height, ImageSync.originalPixels, 0, width);
        }catch(IOException e){
        }
    }

    public static void setImage(BufferedImage image){
        Canvas.image = image;
        Canvas.width = image.getWidth();
        Canvas.height = image.getHeight();
        ImageSync.originalPixels = new int[width * height];
        ImageSync.previewPixels = new int[width * height];
        Canvas.image.getRGB(0, 0, width, height, ImageSync.originalPixels, 0, width);
    }

    public static void setPreview(BufferedImage img, Container parent){
        preview = img;
        parent.repaint();
    }

    public static BufferedImage deepCopy(){
        ColorModel cm = Canvas.image.getColorModel();
        boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
        WritableRaster raster = Canvas.image.copyData(null);
        return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
    }

    public void setSizeFromLoaded(){
        try{
            this.setPreferredSize(new Dimension(Canvas.width + 10, Canvas.height + 10));
            this.setSize(Canvas.width + 10, Canvas.height + 10);
        }catch(Exception e){
            e.getMessage();
        }
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        if(Canvas.preview != null){
            g.drawImage(Canvas.preview, 5, 5, width, height, Color.black, null);
        }else{
            g.drawImage(Canvas.image, 5, 5, width, height, Color.black, null);
        }
    }
}


这是CanvasShadow类:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pocketshop;

import java.awt.Color;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.border.DropShadowBorder;

public class CanvasShadow extends JXPanel{

    public CanvasShadow(){
        DropShadowBorder shadow = new DropShadowBorder();
        shadow.setShadowColor(Color.BLACK);
        shadow.setShowLeftShadow(true);
        shadow.setShowRightShadow(true);
        shadow.setShowBottomShadow(true);
        shadow.setShowTopShadow(true);
        this.setBorder(shadow);

        float[] hsb = new float[3];

        Color.RGBtoHSB(255, 255, 255, hsb);

        this.setBackground(Color.getHSBColor(hsb[0], hsb[1], hsb[2]));
    }
}




这是实际的图像:http://images2.fanpop.com/images/photos/4800000/Beach-beaches-4843817-1280-800.jpg

最佳答案

我已经告诉过您摆脱GridBagLayout的麻烦了。在JScrollPane上设置布局将调整面板的大小,使其永远不会比容器大。您的面板必须进行自我布局,使其具有图像的大小,以便JScrollPane看到它太大而无法显示。只有JScrollPane才添加滚动条。因此,如果您的图片是2000x2000,则您的面板需要将其首选尺寸设置为2000x2000,然后像它一样大。 JScrollPane将完成所有繁重的工作以进行裁剪,并确保面板仅基于滚动条使该部分可见。如果面板的大小始终与JScrollPane的视口相同,则滚动窗格会认为它适合并且不需要滚动条。

更新:快速的Google搜索显示了答案:http://chaosinmotion.com/blog/?p=168

10-05 18:06