不要为每个Image创建JLabel的新实例,只需使用JLabel的JLabel#setIcon(…)方法来更改图像.
一个小样本程序:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SlideShow extends JPanel
{
private int i = 0;
private Timer timer;
private JLabel images = new JLabel();
private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"),
UIManager.getIcon("OptionPane.errorIcon"),
UIManager.getIcon("OptionPane.warningIcon")};
private ImageIcon pictures1, pictures2, pictures3, pictures4;
private ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
i++;
System.out.println(i);
if(i == 1)
{
pictures1 = new ImageIcon("image/caIcon.png");
images.setIcon(icons[i - 1]);
System.out.println("picture 1 should be displayed here");
}
if(i == 2)
{
pictures2 = new ImageIcon("image/Keyboard.png");
images.setIcon(icons[i - 1]);
System.out.println("picture 2 should be displayed here");
}
if(i == 3)
{
pictures3 = new ImageIcon("image/ukIcon.png");
images.setIcon(icons[i - 1]);
System.out.println("picture 3 should be displayed here");
}
if(i == 4)
{
pictures4 = new ImageIcon("image/Mouse.png");
images.setIcon(icons[0]);
System.out.println("picture 4 should be displayed here");
}
if(i == 5)
{
timer.stop();
System.exit(0);
}
revalidate();
repaint();
}
};
public SlideShow()
{
JFrame frame = new JFrame("SLIDE SHOW");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.getContentPane().add(this);
add(images);
frame.setSize(300, 300);
frame.setVisible(true);
timer = new Timer(2000, action);
timer.start();
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new SlideShow();
}
});
}
}
既然您使用ImageIO,那么这是一个与JLabel using ImageIO相关的好例子
与您的案件有关的信息,关于发生的事情:
在你的createAndShowGUI()方法中初始化你的JLabel(swingImage),然后你通过它间接地将它添加到你的JPanel中的JFrame.
但是现在在updateImage()方法中,你正在初始化一个新的JLabel,现在它位于另一个内存位置,通过编写tempImage = new JLabel(new ImageIcon(scaledImage));然后你指向你的swingImage(JLabel)指向这个新创建的JLabel,但是这个新创建的JLabel从未在任何时候添加到JPanel.因此,即使您尝试revalidate()/ repaint()/ setVisible(…),它也不可见.因此,要么将updateImage(…)方法的代码更改为:
protected void updateImage(String name)
{
BufferedImage image = null;
Image scaledImage = null;
JLabel tempImage;
try
{
image = ImageIO.read(new File(name));
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// getScaledImage returns an Image that's been resized
// proportionally to my thumbnail constraints
scaledImage = getScaledImage(image, THUMB_SIZE_X, THUMB_SIZE_Y);
tempImage = new JLabel(new ImageIcon(scaledImage));
rightPane.remove(swingImage);
swingImage = tempImage;
rightPane.add(swingImage, BorderLayout.PAGE_START);
rightPane.revalidate();
rightPane.repaint(); // required sometimes
}
或者如前所述使用JLabel.setIcon(…):-)
更新了答案
这里看看New JLabel如何放置在旧JLabel的位置,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SlideShow extends JPanel
{
private int i = 0;
private Timer timer;
private JLabel images = new JLabel();
private Icon[] icons = {UIManager.getIcon("OptionPane.informationIcon"),
UIManager.getIcon("OptionPane.errorIcon"),
UIManager.getIcon("OptionPane.warningIcon")};
private ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
i++;
System.out.println(i);
if(i == 4)
{
timer.stop();
System.exit(0);
}
remove(images);
JLabel temp = new JLabel(icons[i - 1]);
images = temp;
add(images);
revalidate();
repaint();
}
};
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("SLIDE SHOW");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
this.setLayout(new FlowLayout(FlowLayout.LEFT));
add(images);
frame.getContentPane().add(this, BorderLayout.CENTER);
frame.setSize(300, 300);
frame.setVisible(true);
timer = new Timer(2000, action);
timer.start();
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new SlideShow().createAndDisplayGUI();
}
});
}
}
对于你的问题:在我尝试的两个选项中,一个比另一个好吗?
setIcon(…)比其他方式有优势,从某种意义上说,在添加/删除JLabel之后,你不必为revalidate()/ repaint()而烦恼.此外,您不需要每次都记住JLabel的位置,而是添加它.它保持在它的位置,你只需调用一种方法来改变图像,没有任何附加条件,工作就完成了,没有任何麻烦.
对于问题2:我有一点怀疑,关于什么是记录数组?