现在的位置: 首页 > 综合 > 正文

JScrollPane动态加载图片

2012年07月18日 ⁄ 综合 ⁄ 共 3326字 ⁄ 字号 评论关闭

最近用SWING做一个类似网页图片展示的程序,图片展示是用JLabel,但是由于一次加载多张图片,如果图片数目过大,一次加载后内存的占用率会随着图片的增多一下猛增。

所以思考后,我用动态加载方法来加载图片组件,一次加载2M左右的图片,当JScrollBar滑动到接近尾部时,再加载下一个2M大小的图片集合。这个思想在某些网站上有所应用,我将之改造用在SWING程序中。

动态加载的核心思想就是需要监听JScrollBar的滚动轴。详细代码如下:

用于图片存放的JPanel

package com.wq.ui;

import com.wq.cache.ListCache;
import com.wq.util.LightLog;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: wangq
 * Date: 12-8-2
 * Time: 下午4:02
 * 图床 ,对JAVA6.0,它支持得图象格式有[BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
 */
public class ViewContentPanel extends JPanel implements Page {
    private static ViewContentPanel ourInstance;
    private static LightLog logger = LightLog.getInstance(ViewContentPanel.class);
    private List<String> lastList = new ArrayList<String>(); //存储未显示的图片

    public static ViewContentPanel getInstance() {
        if (ourInstance == null) {
            ourInstance = new ViewContentPanel();
        }
        return ourInstance;
    }

    private ViewContentPanel() {
        constructPlate();
        constructPage();
    }

    @Override
    public void constructPlate() {
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(Box.createRigidArea(new Dimension(10, 10))); //构造一个指定长宽的二维Rigid组件。
    }


    @Override
    public void constructPage() {
        Map<String, java.util.List<String>> map = ListCache.getInstance().getMenu();
        int flag = 0;
        for (Map.Entry<String, java.util.List<String>> entry : map.entrySet()) {
            if (flag == 0) {
                java.util.List<String> list = entry.getValue();
                this.addPic(list);
            } else break;
            flag++;
        }
        addPanelListener();
    }

    private void addPanelListener() {
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0
                        && !e.isControlDown() && !e.isShiftDown()) {
                    ViewPanelMenu.getInstance().show(ViewContentPanel.getInstance(), e.getX(), e.getY()); //右键菜单显示
                }
            }
        });
    }


    public void addPic(List<String> list) {
        if (list == null) return;
        Long length = 0L;
        lastList.clear();
        for (final String path : list) {
            File file = new File(path);
            if (!file.exists()) continue;
            if (length == 0L || length < 1024 * 2) {  //显示最大2M的数据
                length = length + file.length() / 1024;
                dealPic(path);
                logger.debug("添加图片" + path);
            } else {
                lastList.add(path);
            }
        }
        this.validate();
    }

    public void clear() {
        this.removeAll();
        constructPlate();
    }

    private void dealPic(final String path) {
        final JLabel jLabel = new JLabel(new ImageIcon(path));
        jLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0
                        && !e.isControlDown() && !e.isShiftDown()) {
                    PicMenu.getInstance().show(jLabel, e.getX(), e.getY());
                    PicMenu.getInstance().setFilePath(path);
                }
            }
        });
        this.add(jLabel);
        this.add(Box.createVerticalStrut(7));
    }

    /**
     * 用于动态加载图片
     */
    public void loadNextPic() {
        if (!lastList.isEmpty()) {
            List<String> temList = new ArrayList<String>();
            temList.addAll(lastList);
            addPic(temList);
        }
    }
}

其中lastList中存放的是未加载到页面上的图片路径,当lastList为空时,所有的图片才全部加载到页面上。

滚动容器JScrollPane 滚动轴监听代码如下

 final JScrollBar jScrollBar = this.getVerticalScrollBar();
        jScrollBar.addAdjustmentListener(new AdjustmentListener() {
            private int height = 0;

            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                int cur = jScrollBar.getValue();
                int max = jScrollBar.getMaximum();
                if ((cur - height > 3500) && (max - cur) < 1800) {
                    System.out.println("开始加载新图片...........................");
                    ViewContentPanel.getInstance().loadNextPic();
                    ViewPanel.getInstance().updateUI();
                    height = cur;
                }
            }
        });

这里监听了JSrollBar的滚动轴,当滚动轴接近尾部时,调用加载方法,剩余的图片,将陆续被加载。

稍后我将会将整个程序放上来供大家参考。

抱歉!评论已关闭.