Java Applet:释放图形资源

时间:2014-07-02 22:46:08

标签: java graphics applet

我的程序显示图库,不幸的是它一次加载所有内容。我正在寻找建议,一旦用户点击下一个按钮,就可以实现一种方法来加载图像并释放以前加载的图像。

更新我更改为JApplet的版本并更改了paint方法的调用方式。但是,它仍然无法解决内存使用问题。任何帮助都会受到高度关注!

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JApplet;

public class JAppletGallery extends JApplet implements ActionListener {
    private Button first;
    private Button previous;
    private Button next;
    private Button last;

    static int total = 400; // initial total total images
    int imageIndex = 0; // current image

    // gets folder's location
    String folderName = "/Users/Martynas/Pictures/leicester/";
    File folder = new File(folderName);

    // initialise image object up to its total
    Image Pictures[] = new Image[total];
    static String[] imageName = new String[total];

    // constructor
    public JAppletGallery() {

    }

    public void init() {
        makeGui();
        prepareImages();
    }

    private void makeGui() {
        setBackground(Color.DARK_GRAY);
        setForeground(Color.WHITE);
        setLayout(new BorderLayout());
        setSize(800, 600);

        // init buttons
        first = new Button("First");
        first.setForeground(Color.BLACK);
        previous = new Button("Previous");
        previous.setForeground(Color.BLACK);
        next = new Button("Next");
        next.setForeground(Color.BLACK);
        last = new Button("Last");
        last.setForeground(Color.BLACK);

        // init panel holder
        Panel btnPanel = new Panel();

        btnPanel.add(first);
        btnPanel.add(previous);
        btnPanel.add(next);
        btnPanel.add(last);

        add(BorderLayout.NORTH, btnPanel);

        first.addActionListener(this);
        previous.addActionListener(this);
        next.addActionListener(this);
        last.addActionListener(this);
    }

    public void drawNext() {

        imageIndex = imageIndex + 1;
        // checks for current image
        if (imageIndex == total) {
            imageIndex = 0;
        }
        // sends index to display image
        repaint();
    }

    public void drawPrevious() {
        imageIndex = imageIndex - 1;

        if (imageIndex < 0) {
            imageIndex = total - 1;
        }
        repaint();

    }

    public void drawFirst() {
        imageIndex = 0;
        repaint();
    }

    public void drawLast() {
        imageIndex = total - 1;
        repaint();
    }


    // Manage button actions
    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == previous) {
            drawPrevious();
        } else if (e.getSource() == next) {
            drawNext();
        } else if (e.getSource() == first) {
            drawFirst();
        } else if (e.getSource() == last) {
            drawLast();
        }
    }

    // gets files from a folder - sub-method of displayImage()
    public static void filesFolder(File folder) {
        File[] listOfFiles = folder.listFiles();
        int index = 0;

        // puts image names in separate index of array
        for (File file : listOfFiles) {
            if (file.isFile()) {
                // System.out.println(file.getName());
                // assigning to String array for further manipulation
                imageName[index] = file.getName();
                index++;
            }
        }
        // total images count correction
        total = index;
    }

    private void prepareImages() {
        // gets image names from the folder
        filesFolder(folder);

        for (int p = 0; p < total; p++) {

            Pictures[p] = getImage(getDocumentBase(), folderName + imageName[p]);
        }       
    }

    public void paint(Graphics g) {
        g.drawImage(Pictures[imageIndex], 0, 0, this);
    }

}

1 个答案:

答案 0 :(得分:0)

删除实例变量

//将图像对象初始化为其总数     图像图片[] =新图像[总计];

或至少在下一个和上一个 - 删除超过n的元素远离当前。您现在正在缓存所有图像。

相反,将一些图片变量的索引设为null。在paint中检查它是否为null - 如果它只是该槽的加载图像。

还要考虑阅读命名约定和驼峰案例 - 名称实例变量是小写的,所以picutures而不是图片。你已经为其他变量做了这个,所以也许只是错字: - )

并且不要将java awt组件与swing混合。可以使用

java.awt.BorderLayout中; java.awt.Color中; java.awt.Graphics; java.awt.Image中;等

但不是Panel,Button等组件使用JButton ......

尝试释放时需要更多内存......直到垃圾收集发生。如果你有超过20个图像,我猜是个好主意,所以也许缓存大小可以是10。

示例代码 - 在应用程序中制作可以再次成为Japplet - getdocument base等

import java.net.URL;
import java.awt.BorderLayout;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.imageio.*;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JApplet;
import javax.swing.JComponent;

public class JAppletGallery extends JApplet implements ActionListener {
    private JButton first;
    private JButton previous;
    private JButton next;
    private JButton last;
    private int cacheSize = 2;
    static int total = 400; // initial total total images
    int imageIndex = 0; // current image
    String msg = "";

    // gets folder's location
    String folderName = "/Users/Martynas/pictures/leicester/";
    File folder = new File(folderName);

    // initialise image object up to its total
    Image pictures[] = new Image[total];
    static String[] imageName = new String[total];

    public static void main(String[] args){
        final JAppletGallery ap = new JAppletGallery();
        if(args.length > 0){
            ap.folderName = args[0];

        }
        ap.folder = new File(ap.folderName);

        final JFrame f = new JFrame("Gal ");

        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
            //f.setDefaultCloseAction
                f.getContentPane().setLayout(null);
                f.getContentPane().add(ap);
                f.setBounds(0, 0, 700, 700);
                ap.setBounds(15, 15, 675, 675);//not a good way but fine for testing/ local
                //slp(1500)
                f.setVisible(true);

                ap.init();
                ap.start();
                f.invalidate();
                f.repaint();
            }
        });
    }

    // constructor
    public JAppletGallery() {

    }

    public void init() {
        makeGui();
        prepareImages();
    }

    private void makeGui() {
        setBackground(Color.DARK_GRAY);
        setForeground(Color.WHITE);
        setLayout(new BorderLayout());
        setSize(800, 600);

        // init buttons
        first = new JButton("First");
        first.setForeground(Color.BLACK);
        previous = new JButton("Previous");
        previous.setForeground(Color.BLACK);
        next = new JButton("Next");
        next.setForeground(Color.BLACK);
        last = new JButton("Last");
        last.setForeground(Color.BLACK);

        // init panel holder
        JPanel btnPanel = new JPanel();
        btnPanel.setLayout(new java.awt.FlowLayout());
        btnPanel.add(first);
        btnPanel.add(previous);
        btnPanel.add(next);
        btnPanel.add(last);

        add(BorderLayout.NORTH, btnPanel);
        ImgShow imgs = new ImgShow();
        imgs.parent = this;
        add(BorderLayout.CENTER, imgs);

        first.addActionListener(this);
        previous.addActionListener(this);
        next.addActionListener(this);
        last.addActionListener(this);
    }

    public void drawNext() {

        imageIndex = imageIndex + 1;
        // checks for current image
        if (imageIndex == total) {
            imageIndex = 0;
        }
        picsLoadAndTrim();
        // sends index to display image
        repaint();
    }

    public void drawPrevious() {
        imageIndex = imageIndex - 1;

        if (imageIndex < 0) {
            imageIndex = total - 1;
        }
        picsLoadAndTrim();
        repaint();

    }

    private void picsLoadAndTrim() {

        int before = imageIndex - cacheSize;
        int before2 = total;
        if(before < 0){
            before2 = total + before;
        }
        int after = imageIndex + cacheSize;
        int after2 = -1;
        if(after >= total){
            after2 = after - total;
        }
        System.out.println("total " + total + " imageIndex " + imageIndex  + ", before " + before + ", after " + after + ", before2 " + before2+ ", after2 " + after2);
        for(int i =0; i < total ; i++){
            if((i >= before && i <= after) ||  (i <= after2) || (i >= before2)){
                System.out.println("CHECK " + i);
                if(pictures[i] ==null){//load only if not currently loaded

                    try {
                        pictures[i] = ImageIO.read(new File(folder, imageName[i]));
                    //loadImage(getDocumentBase()  , imageName[i]);
                    } catch (Exception e) {
                        msg = msg + " " + imageName[i];
                    }
                }else{
                }
            }else{
                System.out.println("rel " + i);
                pictures[i] = null; //release if loaded before
            }
        }
    }

    public URL getDocumentBase(){
        URL u = null;//super.getDocumentBase();
        try{
            if(u==null)u = new URL("file://" + folderName);
        }catch(Exception e){
            System.out.println(e);
        }
        return u;
    }
    public void drawFirst() {
        imageIndex = 0;
        picsLoadAndTrim();
        repaint();

    }

    public void drawLast() {
        imageIndex = total - 1;
        picsLoadAndTrim();
        repaint();
    }


    // Manage button actions
    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == previous) {
            drawPrevious();
        } else if (e.getSource() == next) {
            drawNext();
        } else if (e.getSource() == first) {
            drawFirst();
        } else if (e.getSource() == last) {
            drawLast();
        }
    }

    // gets files from a folder - sub-method of displayImage()
    public  void filesFolder(File folder) {
        File[] listOfFiles = folder.listFiles();
        int index = 0;

        // puts image names in separate index of array
        for (File file : listOfFiles) {
            String s = file.getName().toLowerCase();
            if (file.isFile() && (s.endsWith(".png") || s.endsWith("jpg"))) {
                // System.out.println(file.getName());
                // assigning to String array for further manipulation
                imageName[index] = file.getName();
                index++;
            }
        }
        // total images count correction
        total = index;
        if(cacheSize > total)cacheSize = total;
    }

    private void prepareImages() {
        // gets image names from the folder
        filesFolder(folder);
        picsLoadAndTrim();
        //for (int p = 0; p < 1; p++) {

          //  pictures[p] = getImage(getDocumentBase(), folderName + imageName[p]);
        //}
    }



}

class ImgShow extends JComponent{
    JAppletGallery parent;


    public void paint(Graphics g) {
            if(parent.pictures[parent.imageIndex] != null){
                g.drawImage(parent.pictures[parent.imageIndex], 0, 35, this);
            }else{
                g.drawString(parent.msg, 10, 35);
                //err
            }
    }
}

此代码可以是impvoed,但它会显示您释放/生成null。