user2415141
user2415141

Reputation: 3

GUI window with images

I am creating a gui that has an image on top and a button below. Every time you click the button the image changes and it will be able to change the image 3 times and start back at the first I have run into an issue though and am hoping someone can answer it Here is my code

import java.awt.*;
import java.awt.event.*;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import java.io.*;


public class GUIExample extends Frame implements WindowListener,ActionListener {
Button b;
JLabel Picture;
ImageIcon pic,dup;
private int numClicks = 0;
int k = 0;
Image[] img = new Image[3];
public static void main(String[] args) throws IOException {
    GUIExample myWindow = new GUIExample("GUIExample");
    myWindow.setSize(500,500);
    myWindow.setVisible(true);
}

public GUIExample(String title) throws IOException {
    super(title);
    img[0] = ImageIO.read(new File("Earth1.jpg"));
    img[1] = ImageIO.read(new File("Earth2.jpg"));
    img[2] = ImageIO.read(new File("Earth3.jpg"));

    setLayout(new FlowLayout());
    addWindowListener(this);
    b = new Button("Change Image");
    Image i = img[0].getScaledInstance(300, 300, java.awt.Image.SCALE_SMOOTH);
    pic = new ImageIcon(i);
    Picture = new JLabel(pic);
    add(Picture);
    add(b);
    b.addActionListener(this);
}


public void actionPerformed(ActionEvent e) {
    numClicks++;
    System.out.println("a");
    System.out.println(numClicks);
    paint1();
}

public void paint1()
{
    System.out.println("b");
    switch(numClicks){
    case 1 : k = 1;
    break;
    case 2 : k = 2;
    break;
    case 3 : k = 0;numClicks = 0;
    break;
    }
    System.out.println(k);
    Image t = img[k].getScaledInstance(300, 300, java.awt.Image.SCALE_SMOOTH);
    pic.setImage(t);
    Picture.setIcon(pic);
}

public void windowClosing(WindowEvent e) {
    dispose();
    System.exit(0);
}

public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}

}

and here is the error im getting

Exception in thread "main" javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at gui.GUIExample.<init>(GUIExample.java:28)
at gui.GUIExample.main(GUIExample.java:21)

Is there an easier way to load my photos into this without using an IO, this is a new concept to me. Any other suggestions on how to get this running correctly would be appreciated.

Thanks

Upvotes: 0

Views: 58

Answers (1)

Joop Eggen
Joop Eggen

Reputation: 109623

There is a mix of two GUI frameworks,

  • AWT (Frame, Button)
  • Swing (JLabel)

Best to pick the newer swing.

The start:

public class SlideShow extends JFrame {

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            new SlideShow().setVisible(true);
        }});
}

Fields:

private Image[] imgs;
private int currentImgIndex;
private JLabel imageComponent = new JLabel();
private Action nextAction = new AbstractAction() {
    {
        putValue(NAME, "Next");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        currentImgIndex = (currentImgIndex + 1) % imgs.length;
        imageComponent.setIcon(new ImageIcon(imgs[currentImgIndex]));
        imageComponent.repaint(50L);
    }
};

The nextAction is a decoupled "action" which you might reuse, put on a button and at the same time place in a menu in the menu bar.

The constructor builds all:

public SlideShow() {

    String dir = "C:/.../media";
    try {
        imgs = new Image[3];
        imgs[0] = ImageIO.read(new File(dir + "/image2.png"));
        imgs[1] = ImageIO.read(new File(dir + "/image5.png"));
        imgs[2] = ImageIO.read(new File(dir + "/image12.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    setTitle("Slide Show");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setBounds(0, 0, 800, 600);

    add(imageComponent, BorderLayout.CENTER);

    JButton nextButton = new JButton(nextAction);
    nextButton.setPreferredSize(new Dimension(100, 30));
    add(nextButton, BorderLayout.SOUTH);

    imageComponent.setIcon(new ImageIcon(imgs[currentImgIndex]));        
}

By default the content pane to which those add(...)s refer, are in the border layout, as you did.

That's it.

The { ... } construct in the AbstractAction is an initializer block, like a constructor.

Upvotes: 1

Related Questions