2013-11-22 2 views
0

Я пытаюсь отображать изображения в последовательном порядке, но с трудностями при отображении (только последнее изображение отображается на экране). Я попытался использовать CardLayout, но поскольку мое число JLabels (которое содержит ImageIcon) велико, это дает мне исключение outofmemory. вот мой код:Дисплей JLabels динамически в JPanel/JFrame

У меня есть 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

Пожалуйста, проверьте похожие вопросы и ответы на этом сайте о том, что вы не вызываете Thread.sleep(...) внутри потока событий Swing. Как они утверждают, вызов этого приведет к тому, что весь ваш Swing GUI будет спать, что не является вашим намерением, я уверен. Поскольку ваша проблема ничем не отличается от всех остальных, решение такое же: используйте таймер Swing для прерывистых действий и используйте фоновый поток, например, созданный SwingWorker для длительных фоновых действий - например, чтение в изображениях.

Кроме того, если все, что вы делаете, это обмен изображениями, то один JLabel должен работать нормально. Просто замените ImageIcon, который он отобразит в вашем таймере Swing.


Редактировать
Вы состояние:

Я не уверен, как перебрать мой 2D массив с свинг таймер, каждые 2 секунды я хочу итерацию мой массив и выполнить некоторые действия.

Предложения:

  • Дают таймер задержки 2000 (за миллисекунды)
  • Дайте ActionListener один или два ИНТ счетчика поля таймера, которые инициализируются в 0.
  • В actionPerformed метод, используйте счетчик, чтобы получить интересующий объект, а затем продвиньте счетчик (и).
  • Прочитать Swing Timer Tutorial.
+0

Я не уверен, как итератировать мой 2D-массив с помощью качания Таймер, каждые 2 секунды Я хочу перебрать мой массив и выполнить какое-то действие. – user2803495

+0

@ user2803495: см. Редактирование для ответа. –

Смежные вопросы