Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

java - for loop issue when cycling through images for Jlabel with button click

in a java aplication I have a Jlabel which i want to assign a new image to every time i click a button, using a for loop i can get it to just display the last image skipping all in between images, i know there is a error in my logic here maybe i should not be using a for loop?? any advice

 private String imageList[];
 ImageIcon image;
 imageList =  new String[] {"src\Tour_Eiffel_Wikimedia_Commons.jpg","src\Ben.jpg", "src\Rio.jpg", "src\Liberty.jpg", "src\Pyramid.jpg"};

 //constructor setting first image to display on load
public GeographyGameGUI() {
       image = new ImageIcon(imageList[0]);
            imageLbl.setIcon(image);
 }

  //button method
   private void nextBtnActionPerformed(java.awt.event.ActionEvent evt) {                                        


      for (imgCount = 1; imgCount < imageList.length; imgCount++) {
            image = new ImageIcon(imageList[imgCount]);
            imageLbl.setIcon(image);

    }

if i dont use a for loop and simply use a counter (displayed below) which i declare outside of the button method it loops correctly displaying the images but runs into a ArrayIndexOutOfBoundsException. what is the best practice here? thanks

 image = new ImageIcon(imageList[imgCount]);
     imageLbl.setIcon(image);
    imgCount++;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're, essentially, blocking the Event Dispatching Thread, prevent it from updating the UI. See Concurrency in Swing for more details

Instead, you should use a javax.swing.Timer to loop over the images, allowing the UI to update before changing to the next one...

See How to use Swing Timers for more details.

Java arrays are zero indexed, this means that the first element in the array is a position 0, not 1

Don't reference src directly within your code, the src directory will not exist once the application is built and packaged

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

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

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

    public class TestPane extends JPanel {

        private JLabel label;
        private String[] imageList = new String[] {"/Tour_Eiffel_Wikimedia_Commons.jpg","/Ben.jpg", "/Rio.jpg", "/Liberty.jpg", "/Pyramid.jpg"};

        public TestPane() {
            setLayout(new BorderLayout());
            label = new JLabel();
            add(label);

            JButton btn = new JButton("Play");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    btn.setEnabled(false);
                    Timer timer = new Timer(1000, new ActionListener() {
                        private int count;
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            if (count < imageList.length) {
                                try {
                                    label.setIcon(
                                            new ImageIcon(
                                                    ImageIO.read(
                                                            TestPane.this.getClass().getResource(imageList[count]))));
                                } catch (IOException exp) {
                                    exp.printStackTrace();
                                }
                                count++;
                            } else {
                                ((Timer)e.getSource()).stop();
                            }
                        }
                    });
                    timer.stop();
                }
            });
        }

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

    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...