图像未从List 重新绘制

我正在尝试从指定的路径加载图像,文件列表存储在List 中。 在第一次初始化图像时它会显示但是当我试图从包含文件列表的List实例中显示下一个图像时,它不会重新绘制图像 。 什么是错误的是我在构造函数中第一次初始化图像覆盖新图像,现在在第一次初始化图像外部构造函数我不知道。

我的代码:

public void nextImage(int cnt) { System.out.println(cnt); if (cnt < imageFiles.size()) { System.out.println(imageFiles.size()); try { bg = ImageIO.read(new File((imageFiles.get(cnt)).toString())); scaled = getScaledInstanceToFit(bg, new Dimension(600, 600)); setBackground(Color.BLACK); } catch(Exception e) { e.printStackTrace(); } } MouseHandler handler = new MouseHandler(); addMouseListener(handler); addMouseMotionListener(handler); System.out.println(cnt); System.out.println(imageFiles.get(cnt).toString()); } 

菜单项点击代码:

 JMenuItem mntmRestoreImage = new JMenuItem("Next Image"); final ImagePane st = new ImagePane(); mntmRestoreImage.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { st.nextImage(k); k++; } }); mnEdit.add(mntmRestoreImage); 

类代码和构造函数:

 private BufferedImage bg; private BufferedImage scaled; java.util.List imageFiles= getFilesFromDirectory(FileSystems.getDefault().getPath("D:\\New folder")); public ImagePane() { try { bg = ImageIO.read(getClass().getResource("/images/src11.jpg")); scaled = getScaledInstanceToFit(bg, new Dimension(600, 600)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

计数器也递增,现在ImagePane()构造函数中的代码会覆盖nextImage()函数的图像,所以想想这个代码会发生什么

有什么建议吗?

我想我有完美的解决方案! 我为你写了一个小程序,所以更容易理解。

首先,我有一种方法可以检查文件是否是图片:

 public Stack getFilesInFolder(String startPath) { File startFolder = new File(startPath); Stack picturestack = new Stack(); String extension; int dotindex; // Go through the folder for (File file : startFolder.listFiles()) { extension = ""; dotindex = file.getName().lastIndexOf('.'); // Get the index of the dot in the filename if (dotindex > 0) { extension = file.getName().substring(dotindex + 1); // Iterate all valid file types and check it for (String filetype : validpicturetypes) { if (extension.equals(filetype)) { picturestack.add(file); } } } } return picturestack; } 

很容易! 拿起文件夹并迭代他的文件。 获取文件的扩展名并检查它是否是有效的文件类型。 在代码开头定义数组中的文件类型。

 String[] validpicturetypes = {"png", "jpg", "jpeg", "gif"}; 

最后,我将每个文件推入堆栈。 请记住将堆栈填充到变量中,不要多次读取文件,因为您遇到的问题与以前相同:

 Stack pictures = getFilesInFolder("C:\\Users\\Admin\\Desktop"); 

之后使用Action为您的JMenuItem! 在我的例子中,我没有太多,你必须把你的方法!

 Action nextpictureaction = new AbstractAction("Next Picture") { private static final long serialVersionUID = 2421742449531785343L; @Override public void actionPerformed(ActionEvent e) { if (!pictures.isEmpty()) { System.out.println(pictures.pop().getName()); } } }; 

在JMenu中添加Action并设置Frame的属性。

 /* * Add Components to Frame */ setJMenuBar(menubar); menubar.add(toolsmenu); toolsmenu.add(nextpictureaction); /* * Frame Properties */ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationByPlatform(true); setSize(1000, 700); setTitle("PictureEditor"); setVisible(true); 

最后用invokeLater方法执行你的程序!

 public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new PictureEditor(); } }); } 

概要

基本上你需要一个迭代的东西,因为像整数这样的值不会以你喜欢的方式保存。 在我的例子中,我使用了一个堆栈并在其中保存所有图片。 重要的是,如果您使用或完成了图片,则必须将其删除(对堆栈使用stack.pop())。 我没有找到一种方法,你检查文件是否是一张图片(如果它是ImageIO捕获它是坏的)。 如果你想要你可以使用它,我写了一个方法。

这不是答案 ,但我不能将这么多代码粘贴到评论中。

我会将您的代码更改为这段代码的内容。 这将分离来自gui更新逻辑的图像加载(如添加鼠标处理程序等,我只粘贴图像加载代码)。

 import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.File; import java.util.Arrays; import java.util.Iterator; import javax.imageio.ImageIO; public class ImageLoader { public static class ImageContainer { BufferedImage bg = null; BufferedImage scaled; } Iterator imageFiles = Arrays.asList( new File("D:\\New folder").listFiles()).iterator(); public ImageContainer nextImage(Dimension dimensionToFit) throws Exception { ImageContainer c = new ImageContainer(); if (imageFiles.hasNext()) { File file = imageFiles.next(); //you might not need this, if only images are in this directory if(file.isDirectory()) return null; c.bg = ImageIO.read(file); c.scaled = getScaledInstanceToFit(c.bg, dimensionToFit); return c; } else return null; } private BufferedImage getScaledInstanceToFit(BufferedImage bg, Dimension dimensionToFit) { //do the risizing } } 

但这尚未优化。