[英]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.