1

我正在尝试从指定路径加载图像,并且文件列表存储在 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<Path> 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() 函数的图像,那么知道 这段代码会发生什么吗?

有什么建议吗?

4

2 回答 2

2

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

首先我有一个方法让你检查文件是否是图片:

public Stack<File> getFilesInFolder(String startPath) {
    File startFolder = new File(startPath);
    Stack<File> picturestack = new Stack<File>();

    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<File> pictures = getFilesInFolder("C:\\Users\\Admin\\Desktop");

之后为您的 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 捕获它是坏的)。我为此写了一个方法,如果你愿意,你可以使用它。

于 2013-08-13T13:21:10.540 回答
1

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

我会将您的代码更改为与这段代码相同的内容。这将图像加载与 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<File> 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
    }
}

虽然这还没有优化。

于 2013-08-13T07:35:37.950 回答