2013-11-22 99 views
0

我尝试以顺序方式显示图像,但显示有困难(只有最后一张图像在屏幕上显示)。我尝试使用CardLayout,但由于我的JLabels(包含ImageIcon)的数量很高,所以它给我的内存异常。这里是我的代码:在JPanel/JFrame中动态显示JLabels

我有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; 
    } 



} 

请指教。

在此先感谢。

回答

2

请检查本网站上有关类似的问题和解答,以免在Swing事件线程中调用Thread.sleep(...)。正如他们所说的,调用它会让你的整个Swing GUI进入睡眠状态,这并不是你的意图,我敢肯定。由于您的问题与其他问题没有什么不同,因此解决方案也是一样的:使用Swing Timer进行间歇性操作,并使用后台线程(例如SwingWorker生成的后台线程)进行长时间运行的后台操作,例如阅读在图像中。另外,如果你只是在交换图像,那么一个JLabel应该可以正常工作。只需交换它在Swing Timer中显示的ImageIcon即可。


编辑
幽州:

我不知道如何遍历我的摆动定时器二维数组,每2秒我想我遍历数组,并执行一些动作。

建议:

  • 给你的计时器2000的延迟(毫秒)
  • 给被初始化为0
  • 在actionPerformed定时器的ActionListener的一个或两个int计数器域方法,使用计数器获取感兴趣的项目,然后推进计数器。
  • 阅读Swing Timer Tutorial
+0

我不知道如何用swing Timer迭代我的2D数组,每2秒我想迭代我的数组并执行一些操作。 – user2803495

+0

@ user2803495:请参阅编辑以回答。 –