2013-11-22 2 views
0

순차적으로 표시 이미지를 표시하려고하지만 표시가 어렵습니다 (마지막 이미지 만 화면에 표시됨). 나는 CardLayout을 사용하려했지만 JLabels (ImageIcon이 포함 된)의 수가 많아서 outofmemory 예외가 발생했습니다. 여기에 내 코드가 :JPanel/JFrame에서 JLabel을 동적으로 표시합니다.

내가 JLrame을 하나씩 표시하려고하는 JPanel을 가지고 있다는 내부에 JFrame이 있습니다.

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 차원 배열 내 배열을 반복하고 몇 가지 작업을 수행 할 2 초마다 반복하는 방법을 잘 모르겠습니다.

제안 :

  • 당신의 타이머를 (밀리 초) 2000 지연을 부여
  • 의 actionPerformed에서 0
  • 으로 초기화됩니다 타이머의 ActionListener를 하나 개 또는 두 개의 INT 카운터 필드주세요 방법을 사용하여 카운터를 사용하여 관심 항목을 가져온 다음 카운터를 진행하십시오.
  • Swing Timer Tutorial을 읽으십시오.
+0

스윙 타이머로 2D 배열을 반복하는 방법을 모르겠다. 매 2 초마다 배열을 반복하고 액션을 수행하고 싶다. – user2803495

+0

@ user2803495 : 답장 수정을 참조하십시오. –

관련 문제