I wrote a program to demonstrate what you asked for, here is the code:
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;
}
}
Please note that this is not the most beautiful way of writing this tool, however it works.
What you should usually do:
Each class should be in its own .java file. The idea is to have a structure, that is easy to read even if you re-visit this code 3 years later.
You should not use variables from another scope like I did here with the window and imagePanel in the main function. Instead use constructors that store local variables with either the value given or a copy of the value (depending on your needs), like I did in the JImagePanel constructor.
Whether or not you need a copy of the value depends on what you do and how much risk you are willing to take. In this example changing the image list after JImagePanel is created would potentially mess things up.You should never use numbers like you did in your version of the key listener. You never know which key-code corresponds to which key! Whenever available use the provided constants or functions to get such a 'magic' number.
Always expect the worst when it comes to error handling. For once try to catch and handle all possible errors. For second always try to avoid potential issues. A bug you cannot make, is a bug you won't have to bother about.
In your version the image file is loaded from disk every time a button is pressed. What happens if the image is no longer present at that moment? In my version everything is checked before-hand, and once that is done, the program cannot fail anymore (at least not when trying to switch images). ;)In general: try to find a good book or online tutorial on Java for beginners. If you just hack away, you will miss all those nice things Java has already prepared for you, that will not only speed up developing a lot, it will as well prevent all bugs that you otherwise might code in.