我的程序显示图库,不幸的是它一次加载所有内容。我正在寻找建议,一旦用户点击下一个按钮,就可以实现一种方法来加载图像并释放以前加载的图像。
更新我更改为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);
}
}
答案 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。