在JFrame中,如何在java中击键后显示/更新图像?

在JFrame中,如何在java中击键后显示/更新图像?,java,swing,keylistener,key-events,Java,Swing,Keylistener,Key Events,作为一名java非专家,我想知道如何更改下面的代码以使其正常工作。这是我想做的 当java代码被调用时,args包含多个图像文件名 我想看看这个列表中的第一张图片 然后,当我按下一个键时,索引被更改,并显示下一个图像 根据下面的建议,下面是一段可编译的运行代码: import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; impor

作为一名java非专家,我想知道如何更改下面的代码以使其正常工作。这是我想做的

  • 当java代码被调用时,
    args
    包含多个图像文件名
  • 我想看看这个列表中的第一张图片
  • 然后,当我按下一个键时,索引被更改,并显示下一个图像
根据下面的建议,下面是一段可编译的运行代码:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;


public class LoadImageApp extends Component {

    BufferedImage img;
    private static int index = 0;

    public void paint(Graphics g) {
        g.drawImage(img, 0, 0, null);
    }

    public LoadImageApp(String filename) {
        try {
            img = ImageIO.read(new File(filename));
        } catch (IOException e) {
            System.out.println(e.getMessage());
            System.exit(0);
        }
    }

    public Dimension getPreferredSize() {
        if (img == null) {
            return new Dimension(100,100);
        } else {
            return new Dimension(img.getWidth(null), img.getHeight(null));
        }
    }

    static public void changeImage(JFrame frame, String filename) {
        System.out.println("Using file "+filename);
        frame.add(new LoadImageApp(filename));
        frame.pack();
        frame.setVisible(true);
        frame.repaint();
    }

    public static void main(final String[] args) {

        char c=0;
        String filename = args[0];
        int numberImages = args.length;

        final JFrame f = new JFrame("Load Image Sample");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        f.addKeyListener(new KeyAdapter(){
                public void keyPressed(KeyEvent event) {
                    int key = event.getKeyCode();
                    if (key==81) {
                        System.exit(0);
                    } else if (key==89) {
                        System.out.println("yes");
                    } else if (key==78) {
                        System.out.println("no");
                    }
                    index += 1;
                    f.removeAll();
                    changeImage(f, args[index]);
                }
            });

        // show first image here
        changeImage(f, args[index]);

    }
}
如果我像这样使用代码

java LoadImageApp *.jpg
它只显示第一个图像。我可以按键,但显示的图像不变。我想换个形象

我找到了
revalidate()
repaint()
作为可能的解决方案。尽管
frame.revalidate()
根本不存在,
frame.repaint()
(在
changeImage
内)仍然不会改变任何东西。我仍然可以看到显示的第一个图像


这是正确的方法吗?有更优雅的方式吗?

这或多或少是你想要的。我建议你从头开始学习Java,填补你的空白

    public class LoadImageApp extends JPanel {

        //Current image the Canvas shows
        private Image currentImage;

        //change the current image and repaint
        public void setCurrentImage(Image currentImage) {
                this.currentImage = currentImage;                
                repaint();
        }

        @Override
        public void paintComponent(Graphics g) {
                g.clearRect(0, 0, getWidth(), getHeight());
                if (currentImage != null)
                g.drawImage(currentImage, 0, 0, null);
        }

        @Override
        public Dimension getPreferredSize() {
                if (currentImage == null) {
                        return new Dimension(100, 100);
                } else {
                        return new Dimension(currentImage.getWidth(null), currentImage.getHeight(null));
                }
        }

        public static void main(final String[] args) throws IOException {

                if (args.length > 0){
                        final Image [] images = new Image[args.length];

                        for (int i = 0; i < images.length; i++){
                                images[i] = ImageIO.read(new File(args[i]));
                        }

                        //It is a goog practice to attach your code to AWT thread.
                        SwingUtilities.invokeLater(new Runnable() {                                
                                @Override
                                public void run() {
                                        LoadImageApp app = new LoadImageApp();
                                        JFrame f = new JFrame("Load Image Sample");

                                        f.getContentPane().setLayout(new BorderLayout());
                                        f.getContentPane().add(app, BorderLayout.CENTER);

                                        f.addKeyListener(new MyKeyAdapter(app, images));
                                        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                                        f.setVisible(true);
                                }
                        });
                }
        }        
    }

    // We create another class for the KeyAdapter
    class MyKeyAdapter extends KeyAdapter{

        //The canvas so we can tell it that the current  image has change
        private LoadImageApp canvas;

        //index of the current image
        private int index;

        //All the images
        private Image [] images;

        public MyKeyAdapter(LoadImageApp canvas, Image[] images) {
                super();
                this.canvas = canvas;
                this.images = images;                    
                rotateRight();
        }

        @Override
        public void keyPressed(KeyEvent event) {
                int key = event.getKeyCode();                    
                if (key == 81) {
                        System.exit(0);
                } else if (key == KeyEvent.VK_LEFT) {
                        rotateLeft();
                } else if (key == KeyEvent.VK_RIGHT) {
                        rotateRight();
                }
        }

        private void rotateRight() {
                //change the image in the canvas
                canvas.setCurrentImage(images[index]);                    
                //increment index
                index++;                    
                //last element + 1, set it to 0
                if (index >= images.length) index = 0;
        }

        private void rotateLeft() {
                //change the image in the canvas
                canvas.setCurrentImage(images[index]);                    
                //decrement index
                index--;                    
                //< 0, set it to last image
                if (index < 0) index = images.length - 1;
        }
}
公共类LoadImageApp扩展了JPanel{
//画布显示的当前图像
私人形象;
//更改当前图像并重新绘制
公共无效setCurrentImage(图像currentImage){
this.currentImage=currentImage;
重新油漆();
}
@凌驾
公共组件(图形g){
g、 clearRect(0,0,getWidth(),getHeight());
如果(currentImage!=null)
g、 drawImage(currentImage,0,0,null);
}
@凌驾
公共维度getPreferredSize(){
如果(currentImage==null){
返回新维度(100100);
}否则{
返回新维度(currentImage.getWidth(null)、currentImage.getHeight(null));
}
}
公共静态void main(最终字符串[]args)引发IOException{
如果(args.length>0){
最终图像[]图像=新图像[args.length];
对于(int i=0;i=images.length)index=0;
}
私有void rotateLeft(){
//更改画布中的图像
canvas.setCurrentImage(图像[索引]);
//减量指数
索引--;
//<0,将其设置为最后一个图像
如果(指数<0)指数=images.length-1;
}
}

关键字
final
表示变量在初始化后不会更改。为了在匿名内部类(即
KeyAdapter
中使用变量,必须将其声明为final

因此,您需要:

 public static void main(final String[] args) {

但这对
索引不起作用,因为您正计划更改它。因此,我建议在类级别(即函数外部)将其声明为静态变量

private static int index = 0;

我编写了一个程序来演示您的要求,下面是代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ImageShow {

  /** Inner class: JPanel that displays images. **/
  static class JImagePanel extends JPanel {

    protected final LinkedList<BufferedImage> images;
    protected BufferedImage currentImage;
    protected int currentIndex;

    public JImagePanel(final LinkedList<BufferedImage> images) {
      super(true);
      this.setFocusable(false);
      this.images = images;
      this.setIndex(0);
    }

    /** Has to be private to not cause issues when used in the constructor. **/
    private void setIndex(final int index) {
      if (index >= this.images.size()) {
        this.currentIndex = 0;
      } else if (index < 0) {
        this.currentIndex = this.images.size() - 1;
      } else {
        this.currentIndex = index;
      }

      this.currentImage = this.images.get(this.currentIndex);
      this.setPreferredSize(new Dimension(this.currentImage.getWidth(), this.currentImage.getHeight()));
      this.repaint();
    }

    public void shiftIndex(final int amount) {
      this.setIndex(this.currentIndex + amount);
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(this.currentImage, 0, 0, null);
    }
  }

  public static void main(final String[] args) {
    final LinkedList<BufferedImage> images = loadImages(args);
    if (images.size() > 0) {
      final JFrame window = new JFrame("Image Show");
      window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      final JImagePanel imagePanel = new JImagePanel(images);
      window.add(imagePanel);

      window.addKeyListener(new KeyAdapter() {
        private void shiftIndex(final int amount) {
          imagePanel.shiftIndex(amount);
          window.pack();
          window.setLocationRelativeTo(null);
        }

        @Override
        public void keyReleased(KeyEvent e) {
          switch (e.getKeyCode()) {
            case KeyEvent.VK_ESCAPE:
              window.dispose();
              e.consume();
              break;
            case KeyEvent.VK_LEFT:
            case KeyEvent.VK_NUMPAD4:
              shiftIndex(-1);
              e.consume();
              break;
            case KeyEvent.VK_RIGHT:
            case KeyEvent.VK_NUMPAD6:
              shiftIndex(+1);
              e.consume();
              break;
          }
        }
      });

      window.pack();
      window.setLocationRelativeTo(null);
      window.setVisible(true);
    } else {
      System.err.println("No image could be loaded.\nPlease provide a list of image files as parameters.");
    }
  }

  private static LinkedList<BufferedImage> loadImages(final String[] filenames) {
    final LinkedList<BufferedImage> result = new LinkedList<>();
    for (String filename : filenames) {
      try {
        final File file = new File(filename);
        final BufferedImage image = ImageIO.read(file);
        if (image == null) {
          throw new IOException("Unknown image format");
        }
        result.add(image);
      } catch (IOException e) {
        System.err.println("Unable to load image \"" + filename + "\": " + e.getMessage());
      }
    }
    return result;
  }
}
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.LinkedList;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公开课影像展览{
/**内部类:显示图像的JPanel**/
静态级JIma
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ImageShow {

  /** Inner class: JPanel that displays images. **/
  static class JImagePanel extends JPanel {

    protected final LinkedList<BufferedImage> images;
    protected BufferedImage currentImage;
    protected int currentIndex;

    public JImagePanel(final LinkedList<BufferedImage> images) {
      super(true);
      this.setFocusable(false);
      this.images = images;
      this.setIndex(0);
    }

    /** Has to be private to not cause issues when used in the constructor. **/
    private void setIndex(final int index) {
      if (index >= this.images.size()) {
        this.currentIndex = 0;
      } else if (index < 0) {
        this.currentIndex = this.images.size() - 1;
      } else {
        this.currentIndex = index;
      }

      this.currentImage = this.images.get(this.currentIndex);
      this.setPreferredSize(new Dimension(this.currentImage.getWidth(), this.currentImage.getHeight()));
      this.repaint();
    }

    public void shiftIndex(final int amount) {
      this.setIndex(this.currentIndex + amount);
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(this.currentImage, 0, 0, null);
    }
  }

  public static void main(final String[] args) {
    final LinkedList<BufferedImage> images = loadImages(args);
    if (images.size() > 0) {
      final JFrame window = new JFrame("Image Show");
      window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      final JImagePanel imagePanel = new JImagePanel(images);
      window.add(imagePanel);

      window.addKeyListener(new KeyAdapter() {
        private void shiftIndex(final int amount) {
          imagePanel.shiftIndex(amount);
          window.pack();
          window.setLocationRelativeTo(null);
        }

        @Override
        public void keyReleased(KeyEvent e) {
          switch (e.getKeyCode()) {
            case KeyEvent.VK_ESCAPE:
              window.dispose();
              e.consume();
              break;
            case KeyEvent.VK_LEFT:
            case KeyEvent.VK_NUMPAD4:
              shiftIndex(-1);
              e.consume();
              break;
            case KeyEvent.VK_RIGHT:
            case KeyEvent.VK_NUMPAD6:
              shiftIndex(+1);
              e.consume();
              break;
          }
        }
      });

      window.pack();
      window.setLocationRelativeTo(null);
      window.setVisible(true);
    } else {
      System.err.println("No image could be loaded.\nPlease provide a list of image files as parameters.");
    }
  }

  private static LinkedList<BufferedImage> loadImages(final String[] filenames) {
    final LinkedList<BufferedImage> result = new LinkedList<>();
    for (String filename : filenames) {
      try {
        final File file = new File(filename);
        final BufferedImage image = ImageIO.read(file);
        if (image == null) {
          throw new IOException("Unknown image format");
        }
        result.add(image);
      } catch (IOException e) {
        System.err.println("Unable to load image \"" + filename + "\": " + e.getMessage());
      }
    }
    return result;
  }
}