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

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

  • 相关阅读:
    centos : 创建交换分区
    用法记录
    mysql日志清理
    mysql 通过查看mysql 配置参数、状态来优化你的mysql
    [WPF 自定义控件]Window(窗体)的UI元素及行为
    [WPF 自定义控件]为Form和自定义Window添加FunctionBar
    [WPF 自定义控件]让Form在加载后自动获得焦点
    [WPF 自定义控件]简单的表单布局控件
    [WPF 自定义控件]以Button为例谈谈如何模仿Aero2主题
    [WPF 自定义控件]自定义控件的代码如何与ControlTemplate交互
  • 原文地址:https://www.cnblogs.com/zhishan/p/2628193.html
Copyright © 2020-2023  润新知