2012-10-02 3 views
3

안녕이라고하지 다시 칠 나는 다음과 같은 코드 패키지 com.vf.zepto.view있다; 는 내가 검색 좀 내 paintComp 방법 밤은이 <p></p>을 호출되는 이유를 파악 할 수

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.util.Properties; 

import javax.imageio.ImageIO; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

import com.vf.zepto.view.interfaces.ProcessorPanel; 

public class CountryDetailsPanel extends JPanel implements ProcessorPanel, Runnable { 
    private GridBagConstraints c = new GridBagConstraints(); 
    private String countryName; 
    private Properties prop = new Properties(); 
    private BufferedImage image; 

    public CountryDetailsPanel() { 
     try { 
      prop.load(new FileInputStream("country.props")); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     //this.setLayout(new GridBagLayout()); 

     c.gridx = 0; 
     c.gridy = 0; 
     c.fill = GridBagConstraints.BOTH; 
     c.insets = new Insets(5, 5, 5, 5); 

     this.setPreferredSize(new Dimension(200, 200)); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     try { 
      if(countryName != null) { 
       String asset = prop.getProperty(countryName+".flag"); 

       if(!asset.equals(null)) { 
        image = ImageIO.read(new File(asset)); 
        g.drawImage(image, 0, 0, null); 
       } 
      } 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void updateDetails(Object o) { 
     countryName = (String)o; 
     SwingUtilities.invokeLater(this); 
    } 

    @Override 
    public void run() { 
     this.repaint(); 
    } 
} 

this.repaint()를 호출 할 때 paintComponent 메서드가 호출하지만 사랑도 돈이 밤은 될 것으로 기대합니다.

문제가 아니지만 EDT를 사용하도록 강요했습니다.

어떤 아이디어가 있습니까?

+0

1 ** 사랑도 돈을 밤은을 위해 **. 문제의 이미지가 정확히 무엇입니까? –

+0

paint가 paintComponent를 호출해야하는 것처럼 보입니다. http://www.leepoint.net/notes-java/GUI-lowlevel/graphics/15who-calls-paintcomponent.html 도움이 될 수 있습니다. –

답변

5
  • 당신은 paintComponent()repaint() 방법은 모든 요청 구성 요소를 변경하는 통합 전화를해서는 안됩니다 (화면 새로 고침 사이의 여러 다시 그리기 요청이있을 수 있습니다). GUI 이벤트 큐에 갱신 요구를 추가해, 갱신이 다른 GUI 액션 (Swing 및 AWT는 thread 세이프가 아닌)과 올바르게 조화되도록 (듯이)합니다. 이 업데이트 요청을 처리 할 때, paint()를 호출하여 호출하는있는 update()를 호출하여 paintComponent()

  • 왜이 있습니다 : 그것은에 새로운 쓰레드를 생성 (모든 사용의 보이지 않는

    @Override 
    public void run() { 
        this.repaint(); 
        } 
    

스레드가 EDT에 있지 않고 repaint() 인스턴스 (인스턴스)를 호출해야합니다 (외부 적으로 수정해도 걱정할 필요는 없습니다).그러나 modifeis 스레드를 시작하는 UI를 잡습니다 사용의 SwingTimer/SwingWorker 또는 SwingUtilities#invokeXXX()

  • 이 관련되지 않을 수 있지만, 코드에서 나는이 참조 :

     if(!asset.equals(null)) { 
          image = ImageIO.read(new File(asset)); 
          g.drawImage(image, 0, 0, null); 
         } 
    

equals()을 사용하지 말아 값과 비교하십시오. null 포인터를 참조하려고 시도했기 때문에 NullPointerException을 던질 수 있습니다 (예 :이 코드는을 던졌습니다).:

String s=null; 
    if(!s.equals(null)) {//throws NPE 
     System.out.println("Here");//is never printed 
    } 
    또한
  • mKorbel가 말한대로 (그에게 +1) 당신이 Image 세계적으로 생성자에서 할당 한 후 paintComponent()에서 사용할 선언 paintComponent()에서 장기 실행 작업을 수행 해달라고. F.i

오히려 수행에 대한

public class TestPanel extends JPanel { 

private Image image; 

public TestPanel() { 
image = ImageIO.read(new File(asset)); 
} 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
       if(asset!=null) { 
        g.drawImage(image, 0, 0, null); 
       } 
    } 
} 
+1

+1 훌륭한 정보에 대한 repaint() 전화하지만, 페인팅 관련 항목을 수행하는 동안 paintComponent() 메서드가 사용되었으므로 paintComponent() 내에서 좋은 생각은 아닙니다. 다시 여기에 다시 스윙을 보내서 아무 이유없이 다시 페인팅합니다. 페인트는 무거운 작업입니다. Filthy Rich Client의 견적은 조금만 정당화 할 수 있습니다 –

+1

** 다시 칠하기 요청은 "합쳐 지거나"결합되어야합니다. 예를 들어 다시 칠하기를 요청하고 아직 서비스되지 않은 대기열에 이미있는 경우 두 번째 요청은 무시됩니다. 다시 칠하기 요청은 이전 요청에 의해 이미 완료되어 있기 때문입니다. 이 동작은 매우 다른 상황과 구성 요소로 인해 많은 다시 그리기 요청이 생성되는 상황에서 특히 유용합니다. 스윙은 중복 요청을 처리하고 노력을 낭비하지 않아야합니다. ** –

+1

@ gagandeepbali +1 감사합니다. 다시 칠하는 것에 대한 사실. smilin을 유지하십시오 :) –

5
  1. 하지로드 이미지 또는 로컬 변수로 paintComponent

  2. 하중이 Object에서 다른 하드 또는 장기 실행 코드라고

  3. paintComponent() 한 번만 수행

    • 암시 적으로,예를 들어 paintComponent()MouseMotionListener에서 호출 할 경우 모든 마우스 이벤트에 대해 다시 그리기가 필요하거나

    • 과 같이 명시 적으로 마우스 이벤트가 필요합니다. 애니메이션이있을 경우

  4. , 다음 스윙 타이머를 사용하고 repaint()를 호출합니다.

+1

+1 멋진 팁 –

+1

@m 코벨 : e.i의 의미를 설명해주세요. 요점 3에서와 같이 :-) ** 즉 **는 **를 의미합니까? –

+2

추측 : 예를 들어 gratia_와 _for instance_가 혼합되어 있습니까? – trashgod