JScrollPane动态加载图片

最近用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的滚动轴,当滚动轴接近尾部时,调用加载方法,剩余的图片,将陆续被加载。

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

你可能感兴趣的:(scroll)