我的程序显示图片库,不幸的是它一次加载所有内容。我正在寻找建议来实现一种方法来加载图像并在用户单击下一步按钮后释放先前加载的图像。
更新版本,其中我更改为 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);
}
}
最佳答案
删除实例变量
//初始化图像对象到它的总数 Image Pictures[] = new Image[total];
或者至少在 next 和 previous 上 - 删除距离当前 n 个位置以上的元素。您现在正在缓存所有图像。
而是使一些 Pictures 变量的索引为空。在绘画中检查它是否为 null - 如果它是单独加载该插槽的图像。
同时考虑阅读命名约定和驼峰命名法——命名实例变量是小写的,所以图片而不是图片。您已经为其他变量完成了此操作,所以这里可能只是拼写错误 :-)
并且不要将 java awt 组件与 swing 混合使用。可以用
java.awt.BorderLayout; java.awt.颜色; java.awt.图形; java.awt.图像;等等
但不是像 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
}
}
}
此代码可以被强制执行,但它显示你释放/使 null。
关于Java 小程序 : free up Graphics resources,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24542272/