0

Inside an ActionListener i am adding an image to a JPanel, which afterwards pops up. After a specific time that JFrame will be disposed.

This is what my mainFrame class looks like:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;


public class mainFrame {
    JFileChooser chooser = new JFileChooser();
    File[] files;
    FileFilter filter = new FileNameExtensionFilter("Bilder", "gif", "png","jpg");

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    mainFrame window = new mainFrame();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public mainFrame() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 300, 119);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JButton btnStart = new JButton("Start !");
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                try{
                    final imageFrame imageFrame = new imageFrame();
                    imageFrame.getContentPane().add(new JLabel(new ImageIcon(files[0].getAbsolutePath())));
                    imageFrame.setVisible(true);
                    new Timer().schedule(new TimerTask() {
                        public void run() {
                                imageFrame.dispose();
                            }
                    }, (Integer) 3000);
                }catch(Exception e){
                    e.printStackTrace();
                }

            }
        });
        btnStart.setBounds(6, 62, 117, 29);
        frame.getContentPane().add(btnStart);

        JButton btnChooseFiles = new JButton("Choose Files !");
        btnChooseFiles.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                /* JFileChooser deklarieren */
                chooser = new JFileChooser();
                chooser.setMultiSelectionEnabled(true);
                chooser.addChoosableFileFilter(filter);
                chooser.showOpenDialog(null);

                /* FileList erstellen */
                files = chooser.getSelectedFiles();

                /* Displaying String containing chosen files */
                String fileList = "";
                for (int i = 0; i < files.length; i++) {
                    fileList += files[i].getName() + "\n";
                }
                System.out.println("Chosen Files:\n" + fileList);
            }
        });
        btnChooseFiles.setBounds(6, 6, 117, 29);
        frame.getContentPane().add(btnChooseFiles);
    }
}

And this is what my imageFrame looks like:

import java.awt.BorderLayout;


public class imageFrame extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    imageFrame frame = new imageFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public imageFrame() {
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        setBounds(100, 100, 623, 472);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
    }

}

So far everything works great for one file, but what i got is a list of files, so i decided to make use of a for-loop wrapping the try-catch block in the mainFrame "Start"-ActionListener, which unfortunately does not work, as every image apart from the last one pops up immediately and only the last one stands to the delay of the timer.

All in all i just want to change the image inside the imageFrame Object, after a specific time. Let's say every 3 seconds the image inside the Pane should change, until we're through all chosen files.

  • 1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). 2) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/a/9554657/418556) 3) Use a Swing based `Timer` for GUI related tasks. – Andrew Thompson Apr 04 '14 at 23:48
  • What exactly are you trying to do? Do you want a different image to show every time a different frame pops up? Do you want the images to loop while the same frame is up? You need to be more clear on your requirements. – Paul Samsotha Apr 05 '14 at 01:18
  • Here's a [reason against doing this](http://stackoverflow.com/q/6309407/230513). – trashgod Apr 05 '14 at 01:54
  • I edited my question and an MCVE. I realize that the way i am trying to implement my aim is not the most efficient way, because all in all i just want to change the image inside the imageFrame object after every (for example) 3 seconds (3000 ms) or so. Disposing the whole corresponding object everytime is not the best idea, i realize. Changing the Image and repainting the GUI did unfortunately not work. –  Apr 05 '14 at 08:50

1 Answers1

0

Here's some ideas you can think about.

  • keep a currentIndex variable you can use to determine the index of the next image

  • Use a javax.swing.Timer instead of a java.util.Timer. You can see more at How to Use Swing Timers. The basic construct is easy to folow.

    Timer (int delayInMillis, ActionListener listener)
    

    As you can see the delayInMillis is the delay, and the listener is what listens for each timer event fired every delay tick, and carries with it the normal actionPerformed call back. In the actionPerformed you can use the currentIndex to get the image, then increase the currentIndex. Something like. You can call timer.start() when ever you want it to start. You can also use timer.setDelay(int)

    private int currentIndex = 0;
    private int delay = 2000;
    ...
    Timer timer = new Timer(delay, new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            if (current index is equal to array size) {
                ((Timer)e.getSource()).stop();
                MyDialog.this.dispose();
            } else {
                showImageByIndex(currentIndex);
                currentIndex++;
            }
        }
    });
    

    That just an example, Try and play with it.

  • You'll also notice MyDialog. It is preferred to use a JDialog if you need to use multiple frames. So try and work it out with a JDialog.

  • Also you should create your images and keep them in memory, instead of creating the new image every tick. Also just keep one JLabel, and just use label.setIcon(imageArray[currentIndex]);


There's some things you can do off of. Try and work it out. If you're having problems at something, ask, or update your post with your progress.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720