2013-04-22 2 views
0

진화하는 BufferedImages를 JPanel에 표시해야합니다. 코드는 다음과 같은 형식으로 구성되어 있으며 SSCCE를 아래와 같이 컴파일했습니다.진화하는 BufferedImage를 JPanel에 표시하는 방법

다음 클래스는 이클립스에 SSCCE1 프로젝트에

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import javax.swing.JPanel; 

public class DisplayLattice extends JPanel { 

    private BufferedImage IMAGE = null; 
    private BufferedImage DISPLAY_IMAGE = null; 

    public DisplayLattice() 
    { 
     IMAGE = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); 
     render(); 
    } 

    public DisplayLattice(BufferedImage map) { 
     IMAGE = map; 
     render(); 
    } 

    public void paint(Graphics g) { 
     if (IMAGE == null) 
      super.paint(g); 
     else 
      g.drawImage(IMAGE, 0, 0, this); 
    } 

    public void render() { 

    int cellWidth = 5; 
    int cellHeight = 5; 

     int imgW = IMAGE.getWidth(); 
     int imgH = IMAGE.getHeight(); 
     DISPLAY_IMAGE = new BufferedImage(imgW*cellWidth, imgH*cellHeight, 1);   
     Graphics2D g2 = IMAGE.createGraphics(); 
     g2.clearRect(0,0,DISPLAY_IMAGE.getWidth(),DISPLAY_IMAGE.getHeight()); 

     for (int x=0; x<imgW; x++) { 
      for (int y=0; y<imgH; y++) { 
       g2.setColor(new Color(IMAGE.getRGB(x, y))); 
       g2.fillRect((int)(x*cellWidth), (int)(y*cellHeight), 
          (int)cellWidth, (int)cellHeight); 
      } 
     } 
     g2.setColor(Color.black); 
     g2.dispose(); 
     repaint(); 
     revalidate(); 
     System.out.println("XX"); 
    } 

    public void setImage(BufferedImage image) 
    { 
     IMAGE = image; 
    } 
} 

클래스 SelfOrganizingMap.java

import java.awt.Color; 
import java.awt.image.BufferedImage; 

public class SelfOrganizingMap { 

    public void methodTrain() 
    { 
     for(int i = 0; i < 100; i++) 
     { 
      new DisplayLattice(exportImageNorm()); 
     } 

    } 

    private BufferedImage exportImageNorm() 
    { 
     BufferedImage colorNodes = new BufferedImage(200, 200, 1); 
     double[][] normL2values = new double[200][200]; 
     float t = 0.0f; 
     for(int i = 0; i < normL2values.length ; i++){ 
      for(int j = 0; j < normL2values[0].length; j++){ 
       t = (float) Math.random(); 
       colorNodes.setRGB(i, j, (new Color(t,t,t)).getRGB()); 
      } 
     } 
     System.out.println("LL"); 
     return colorNodes; 
    } 

} 

다음 클래스는 SSCCE2 프로젝트에

클래스 DisplayLattice.Java 있습니다

나는 MapScreen 클래스에서의 JButton를 클릭하면

클래스 MapScreen.Java (메인 클래스)

import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 
import javax.swing.JButton; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 

public class MapScreen extends JFrame { 
    private int WIDTH = 0; 
    private int HEIGHT = 0; 
    private DisplayLattice pnlMap; 

    public MapScreen(int mapOption) { 


     setType(Type.UTILITY); 
     setResizable(false); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setTitle("Map"); 
     setSize(600, 600); 
     setLocation(150,150); 
     getContentPane().setLayout(null); 

     pnlMap = new DisplayLattice(); 
     pnlMap.setBounds(6, 130, 582, 440); 
     getContentPane().add(pnlMap); 

     JButton btnNewButton = new JButton("New button"); 
     btnNewButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       new SelfOrganizingMap().methodTrain(); 
      } 
     }); 
     btnNewButton.setBounds(10, 81, 89, 23); 
     getContentPane().add(btnNewButton); 

    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       MapScreen frame = new MapScreen(5); 
       frame.setVisible(true); 
      } 
     }); 

    } 
} 

내가 달성하고자하는 것은 동적으로을에 SSCCE1 프로젝트에 DisplayLattice의 인스턴스 인 JPanel의 필요 SelfOrganzingMap 클래스의 methodTrain()에 지정된대로 반복 횟수를 변경하십시오.

내가 가진 현재 문제는 각 반복시 SelfOrganizingMap 클래스에서 설정 한 bufferedImage가 표시된 JPanel에 설정되어 있지 않다는 것입니다.

이 문제를 해결하는 방법은 무엇입니까? 이러한 유형의 시각화를 수행하는 가장 좋은 방법은 실제로 여기에 제시된 세 가지 클래스가 모두 실제 응용 프로그램에서 많은 메소드를 사용하여 크기면에서 꽤 큰 것을 명심하십시오.

+1

에서 살펴하실 수 있습니다, 당신은 [사용자 정의 도장을 수행]의 읽기 (http://docs.oracle.com/javase을하는 것 같아서/tutorial/uiswing/painting /)'paint'를 권장하지 않으므로 추천하지 않습니다;) – MadProgrammer

+0

DisplayLattice 클래스의 요점을 이해하지 못합니다. render() 메서드를 호출하면 이미지가 생성되지만 어디에서나 이미지를 사용하는 위치는 표시되지 않습니다. revalidate()를 수행 할 필요가 없습니다. 패널에서 구성 요소를 추가/제거 할 때 다시 유효성을 검사합니다. 또한 getPreferredSize() 메서드를 재정 의하여 이미지 크기를 반환해야 패널을 다른 패널에 추가하고 적절한 크기로 표시 할 수 있습니다. – camickr

+0

@camicker 당신은 더 구체적 일 수 있습니까? DisplayLattice를 만들려는 의도는 이미지가 전달되는 것을 확대하여 각 배열 요소를 사각형으로 나타낼 수있게하는 것입니다. 일부 값을 계산하는 render 메소드의 또 다른 부분이 있습니다. 내 문제가 있었던 곳이 아니기 때문에 나는 그것을 포함시키지 않았다. 미안, 내가 너를 오도 해. – Synex

답변

2

주된 문제는 귀하의 methodTrain 방법에 있습니다.

new DisplayLattice(exportImageNorm()); 

이 단순히 실제로 화면에 표시되어있는 한 사람과 아무 상관이없는 DisplayLattice의 새로운 인스턴스를 생성한다 ...

내가 생각할 수있는 가장 간단한 해결책이다 단순히 이것은 당신이 뭔가 같이 할 수있는 것

new SelfOrganizingMap().methodTrain(pnlMap); 

당신이 methodTrain 방법 MapScreen에서 만든 참조를 ... ... 통과

public void methodTrain(DisplayLattice map) { 
    for (int i = 0; i < 100; i++) { 
     map.setImage(exportImageNorm()); 
    } 
} 

이미지를 다시 할당 한 후에 을 setImage 메서드에 추가해야합니다.

니트는

  • setBounds를 사용하지 마십시오, 사용하십시오 LayoutManager, 심각, 단지 노력을, 그것은
  • paint을 무시하지 마십시오 ... 끝없이 당신을 보상 할 것이다, paintComponent을 사용하여 선택합니다 대신. 이것은 사용자 정의 페인팅을 제공하는 권장 방법입니다. 또한 절대적으로 구체적인 이유가 없으면 반드시 super.paintXxx으로 전화해야합니다. 그렇지 않으면 무엇이 잘못 될지 알기 때문에 고칠 수 있습니다.
  • repaint 뒤에 revalidate을 호출 할 필요가 없습니다. revalidaterepaint을 예약합니다.
  • 또한 내가 더 깊이 살펴 동안 Code Conventions for the Java Programming Language
+0

+1, 방금 methodTrain() 메서드를 사용하려고했지만 이제는 걱정할 필요가 없습니다. – camickr

+0

@MadProgrammer, 빠른 답장을 보내 주셔서 감사합니다. 한 번 JPanel 업데이트에서 이미지를 얻을 수 있습니다. 그러나 위의 수정은 모든 반복이 완료된 후에 만 ​​이미지를 표시합니다. 그러나 모든 반복 끝에 각 반복마다 생성 된 이미지를 표시해야합니다. – Synex

+0

애니메이션을 적용 하시겠습니까? 아니면 출력 창에 그리드와 같이 각 이미지가 표시되기를 원하십니까? – MadProgrammer

관련 문제