java - 单击箭头键时图片不刷新(keylistener)

标签 java image swing slideshow keylistener

我卡住了,当我点击箭头键时,我的图片无法加载。仅显示第一张图片。然后就什么都没有发生了。我希望能够通过单击箭头键来更改文件夹中的图片。这是代码。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;


class MyPanel extends JPanel implements KeyListener {
//public Image [] walkable;

    public Image walkable;
    int i = 0;
    public char c = 'e';
    public String p = "no";
    public ImageIcon icon;
//for (int s=0;s<3;s++){
//  ImageIcon  p[s] = ImageIcon("002.jpg");
//  }
//ImageIcon icon = new ImageIcon(p);

//ImageIcon  icon = ImageIcon("001.jpg");
    //ImageIcon icon = new ImageIcon();
    public MyPanel() {
        this.setPreferredSize(new Dimension(500, 500));

        String path = ".";
        String files;
        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();

        if (i < listOfFiles.length) {
            if (listOfFiles[i].isFile()) {
                files = listOfFiles[i].getName();
                if (files.endsWith(".jpg") || files.endsWith(".JPG") || files.endsWith(".png") || files.endsWith(".PNG")) {
                    ImageIcon icon = new ImageIcon(files);
                    walkable = icon.getImage();
       // return icon;
                }
            }
        }
        addKeyListener(this);
    }

    public void addNotify() {
        super.addNotify();
        requestFocus();
    }

    public void paintComponent(Graphics g) {
    //g.clearRect(0, 0, getWidth(), getHeight());
        //g.drawString("the key that pressed is " + c, 250, 250);
        //g.drawString("the key that pressed is " + p, 400, 250);
        g.drawImage(walkable, 0, 0, this);
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        c = e.getKeyChar();

        int keyCode = e.getKeyCode();
        switch (keyCode) {
            case KeyEvent.VK_UP:
                // handle up
                break;
            case KeyEvent.VK_DOWN:
                // handle down
                break;
            case KeyEvent.VK_LEFT:
                i = i - 1;
                //walkable = icon.getImage();
                break;
            case KeyEvent.VK_RIGHT:
                i = i + 1;
                //walkable = icon.getImage();
                break;

        }
        repaint();
    }

    public static void main(String[] s) {

        JFrame f = new JFrame();
        f.getContentPane().add(new MyPanel());
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
}

最佳答案

您正在更改 i 的状态,但您没有对它执行任何操作,walkable 从它加载到构造函数中时起就永远不会改变...

我还建议使用 Key Bindings优于 KeyListener,因为它不会遇到与 KeyListener 相同的焦点问题

更新了建议

首先,我过滤文件列表,以便列表中仅存在有效的图像文件。看看File#listFiles(FileFilter)这将允许在生成文件列表时应用过滤器。

其次,我会将文件列表作为实例变量提供给类,这样您就可以在需要时进行访问。

第三,我将使用ImageIO.read来读取图像。它支持多种文件格式,立即加载图像并在出现问题时抛出 IOException,而不是像 ImageIcon 那样默默失败。看看http://docs.oracle.com/javase/tutorial/2d/images/loadimage.html了解更多详情

以下是所提到的想法的一个非常简单的示例。它在事件调度线程的上下文中加载图像,因此在大图像上,它会“停止”您的程序。看看Concurrency in SwingSwingWorker特别是关于如何克服这个问题的建议......

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ImageWalker extends JPanel {

    public static void main(String[] args) {
        new ImageWalker();
    }

    public ImageWalker() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new MyPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyPanel extends JPanel {

        public Image walkable;
        private int i = 0;
        private File[] listOfFiles;

        public MyPanel() {

            String path = ".";
            File folder = new File(path);
            listOfFiles = folder.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    String name = pathname.getName().toLowerCase();
                    return name.endsWith("png") || name.endsWith("jpg");
                }
            });

            if (listOfFiles != null && listOfFiles.length > 0) {
                loadCurrent();
            }

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "next");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");

            am.put("next", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (listOfFiles != null && listOfFiles.length > 0) {
                        i--;
                        if (i < 0) {
                            i = listOfFiles.length - 1;
                        }
                        loadCurrent();
                    }
                }
            });
            am.put("right", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (listOfFiles != null && listOfFiles.length > 0) {
                        i++;
                        if (i >= listOfFiles.length) {
                            i = 0;
                        }
                        loadCurrent();
                    }
                }
            });

        }

        protected void loadCurrent() {

            if (listOfFiles != null && listOfFiles.length > 0) {
                File file = listOfFiles[i];
                try {
                    walkable = ImageIO.read(file);
                    repaint();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(walkable, 0, 0, this);
        }
    }
}

关于java - 单击箭头键时图片不刷新(keylistener),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19991975/

相关文章:

node.js - Nodejs 将图像分割成 block

java - 从另一个类中的监听器访问扩展 JPanel

java - 在外部单击时自动关闭 JFrame 窗口

java - 为什么 Netbeans 设计者将 JFrame 大小设置为与我指定的不同的值?

java - Android 通知设置ContentView

java - JSONObject 无法解析为类型

css - 如何在使用溢出时移动图像的 POV : hidden?

java - JVM 垃圾收集对象是否被不再使用的局部变量引用?

java - ProgressDialog不会显示 - 多线程

php - 我的链接图像有不可见的像素,我想通过编码将其删除