我正在尝试按顺序显示图像,但显示困难(只有最后一张图像显示在屏幕上)。我尝试使用CardLayout,但因为我的JLabel(包含ImageIcon)的数量很高所以它给了我outofmemory异常。这是我的代码:
我有JFrame,我有JPanel,我试图逐个显示JLabel。
public class ImageMain extends JFrame implements ActionListener{
private static final long serialVersionUID = 2916361361443483318L;
private JFileChooser fc = null;
private JMenuItem item1,item2;
private BufferedImage image = null;
private JPanel panel = null;
private int width = 0;
private int height = 0;
private BorderLayout card;
private Container contentPane;
public ImageMain() {
JFrame frame = new JFrame("Image Extraction Tool");
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = frame.getContentPane();
panel = new JPanel();
card = new BorderLayout();
panel.setLayout(card);
panel.setBackground(Color.white);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
item1 = new JMenuItem("Browse an image");
item2 = new JMenuItem("Exit");
item1.addActionListener(this);
item2.addActionListener(this);
menu.add(item1);
menu.add(item2);
frame.setJMenuBar(menuBar);
contentPane.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ImageMain img = new ImageMain();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == item1){
if(fc == null)
fc = new JFileChooser();
int retVal = fc.showOpenDialog(null);
if(retVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
try {
image = ImageIO.read(file);
height = image.getHeight();
width = image.getWidth();
int[][] pixelData = new int[height * width][3];
int[] rgb;
int counter = 0;
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
rgb = getPixelData(image, i, j);
for(int k = 0; k < rgb.length; k++){
pixelData[counter][k] = rgb[k];
}
counter++;
}
}
for(int m=pixelData.length-10; m < pixelData.length; m++){
System.out.println(m);
int[] pix = new int[width*height*3];
for(int i=0;i< width*height*3; i+=3){
pix[i] = pixelData[m][0];
pix[i+1] = pixelData[m][1];
pix[i+2] = pixelData[m][2];
}
JLabel createImageLabel = createImageLabel(pix);
panel.add(createImageLabel);
// panel.revalidate();panel.repaint();
contentPane.revalidate();contentPane.repaint();
Thread.sleep(2000);
}
} catch (IOException e1) {
System.out.println("IO::"+e1.getMessage());
}catch(Exception e1){
System.out.println("Exception::"+e1.getMessage());
}
}
}
if(e.getSource() == item2){
System.exit(0);
}
}
private int[] getPixelData(BufferedImage image, int x, int y) {
int argb = image.getRGB(y, x);
int rgb[] = new int[] {
(argb & 0x00ff0000) >> 16 , //red
(argb & 0x0000ff00) >> 8, //green
argb & 0x000000ff //blue
};
return rgb;
}
private JLabel createImageLabel(int[] pixels){
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
WritableRaster raster = image.getRaster();
raster.setPixels(0, 0, width, height, pixels);
JLabel label = new JLabel(new ImageIcon(image));
return label;
}
}
请咨询。
提前致谢。
答案 0 :(得分:2)
请在本网站上查看类似的问题和答案,不要在Swing事件线程中调用Thread.sleep(...)
。正如他们所说,调用它会让你的整个Swing GUI进入睡眠状态,这不是你的意图,我敢肯定。由于您的问题与其他问题没有什么不同,解决方案也是一样的:使用Swing Timer进行间歇性操作,并使用后台线程(如SwingWorker生成的后台线程)进行长时间运行的后台操作 - 例如读取在图像中。
另外,如果您所做的只是交换图像,那么一个JLabel应该可以正常工作。只需交换它在Swing Timer中显示的ImageIcon。
修改强>
你说:
我不知道如何使用swing Timer迭代我的2D数组,每2秒我想迭代我的数组并执行一些操作。
建议: