Java小程序:释放图形资源

Java小程序:释放图形资源,java,graphics,applet,Java,Graphics,Applet,我的程序显示图像库,不幸的是它一次加载所有内容。我正在寻找建议,以实现一种方法来加载一个图像和释放以前加载的图像一旦用户点击下一步按钮 更新了我更改为JApplet的版本,并更改了调用paint方法的方式。但是,它仍然不能解决内存使用问题。任何帮助都将得到高度赞赏 import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.Graphics; import java.aw

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

更新了我更改为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);
    }

}
导入java.awt.BorderLayout;
导入java.awt.Button;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.Panel;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.File;
导入javax.swing.JApplet;
公共类JAppletGallery扩展了JApplet实现ActionListener{
私人按钮优先;
私人按钮前;
私人按钮下一步;
私人按钮最后;
静态int-total=400;//初始图像总数
int imageIndex=0;//当前图像
//获取文件夹的位置
字符串folderName=“/Users/Martynas/Pictures/leicester/”;
文件夹=新文件(文件夹名称);
//初始化图像对象,使其达到其总数
图像图片[]=新图像[总数];
静态字符串[]imageName=新字符串[总计];
//建造师
公共图书馆{
}
公共void init(){
makeGui();
准备阶段();
}
私有void makeGui(){
挫折背景(颜色:深灰色);
设置前景(颜色:白色);
setLayout(新的BorderLayout());
设置大小(800600);
//初始化按钮
第一个=新按钮(“第一个”);
首先,设置前景(颜色为黑色);
previous=新按钮(“previous”);
设置前景色(颜色为黑色);
下一步=新按钮(“下一步”);
接下来,设置前景(Color.BLACK);
最后一个=新按钮(“最后一个”);
最后,设置前景(颜色为黑色);
//初始面板支架
面板btnPanel=新面板();
btnPanel.add(第一);
btnPanel.add(上一个);
btnPanel.add(下一步);
btnPanel.add(最后一个);
添加(BorderLayout.NORTH,btnPanel);
首先,addActionListener(这个);
previous.addActionListener(此);
next.addActionListener(这个);
last.addActionListener(这个);
}
下一个()的公共空间{
imageIndex=imageIndex+1;
//检查当前图像
如果(imageIndex==总计){
imageIndex=0;
}
//发送索引以显示图像
重新油漆();
}
公共图书馆{
imageIndex=imageIndex-1;
如果(imageIndex<0){
imageIndex=总计-1;
}
重新油漆();
}
公共部门优先{
imageIndex=0;
重新油漆();
}
公众假期{
imageIndex=总计-1;
重新油漆();
}
//管理按钮操作
已执行的公共无效操作(操作事件e){
如果(如getSource()==上一个){
drawPrevious();
}else if(e.getSource()==next){
drawNext();
}else if(例如getSource()==第一个){
drawFirst();
}else if(e.getSource()==last){
拉丝();
}
}
//从displayImage()的文件夹子方法获取文件
公用静态无效文件文件夹(文件文件夹){
File[]listOfFiles=folder.listFiles();
int指数=0;
//将图像名称放在数组的单独索引中
对于(文件:listOfFiles){
if(file.isFile()){
//System.out.println(file.getName());
//指定给字符串数组以进行进一步操作
imageName[index]=file.getName();
索引++;
}
}
//总图像计数校正
总数=指数;
}
私人作废准备页(){
//从文件夹中获取图像名称
文件夹(文件夹);
对于(int p=0;p
删除实例变量

//初始化图像对象,使其达到其总数 图像图片[]=新图像[总数]

或者至少在“下一个”和“上一个”-从当前位置移除元素n处以上。您现在正在缓存所有图像

相反,将一些图片变量的索引设为null。在画图中,检查其是否为空-是否仅加载该插槽的图像

还考虑读取命名约定和CAMEL CASE名称实例变量,它们是小写的,而不是图片。您已经为其他VAR完成了此操作,因此可能只需在此处键入:-)

不要将JavaAWT组件与swing混合使用。可以使用

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

但不是像面板、按钮这样的组件使用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
            }
    }
}
import java.net.URL;
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Image;
导入javax.swing.JPanel;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.File;
导入javax.imageio.*;
导入javax.swing.JFrame;
导入javax.swing.JButton;
导入javax.swing.JApplet;
导入javax.swing.JComponent;
公共类JAppletGallery扩展了JApplet实现ActionListener{
私人按钮优先;
私人JButton-previous;
下一个私人按钮;
最后一个私人按钮;
私有int cacheSize=2;
静态int-total=400;//初始图像总数
int imageIndex=0;//当前图像
斯特里