簡體   English   中英

使用按鈕單擊循環瀏覽 Jlabel 的圖像時出現 for 循環問題

[英]for loop issue when cycling through images for Jlabel with button click

在 Java 應用程序中,我有一個 Jlabel,我想在每次單擊按鈕時為其分配一個新圖像,使用 for 循環我可以讓它只顯示最后一個圖像,在圖像之間跳過所有圖像,我知道有錯誤在我的邏輯中,也許我不應該使用 for 循環?? 任何建議

 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);

    }

如果我不使用 for 循環而只是使用我在按鈕方法之外聲明的計數器(如下所示),它會正確循環顯示圖像,但會遇到 ArrayIndexOutOfBoundsException。 這里的最佳做法是什么? 謝謝

 image = new ImageIcon(imageList[imgCount]);
     imageLbl.setIcon(image);
    imgCount++;

您本質上是在阻塞事件調度線程,阻止它更新 UI。 有關更多詳細信息,請參閱Swing 中的並發

相反,您應該使用javax.swing.Timer來循環圖像,允許 UI 在更改為下一個之前更新...

有關更多詳細信息,請參閱 如何使用擺動計時器

Java 數組的索引為零,這意味着數組中的第一個元素是位置0 ,而不是1

不要在代碼中直接引用src ,一旦應用程序構建和打包, src目錄將不存在

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);
        }

    }

}

您的計數器到達數組的末尾,因此您會遇到越界異常。 每次遞增后,您應該檢查是否已到達數組末尾,如果已到達,請將計數器設置為 0。

如果您想通過單擊延遲迭代一些圖像,您需要使用SwingWorker 在您的動作偵聽器中使用延遲將掛起事件調度線程,這意味着沒有其他更新或與 Swing 組件的交互可用(刷新也可能無法正確完成)。

如果您在很短的時間內進行了幾次更新 ( setIcon ),Swing 通常會在最后一次更新后刷新組件,這意味着只有最后一張圖片是可見的。

看看這里: http : //docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM