2012-10-06 7 views
6

paintComponent (Graphics g) 메서드를 오버라이드 (override)하는 JComponent를 확장하는 커스텀 컴퍼넌트가 있습니다 만, JPanel에 추가하려고하면 (자) 아무것도 동작하지 않습니다. - 구성 요소가 JPanel에 추가되고 있지만, 얼마나 큰JComponent가 JPanel에 그리지 않습니다.

public class SimpleComponent extends JComponent{ 

int x, y, width, height; 

public SimpleComponent(int x, int y, int width, int height){ 
    this.x = x; 
    this.y = y; 
} 

@Override 
public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setColor(Color.BLACK); 
    g2.fillRect(x, y, width, height); 
} 
} 


public class TestFrame{ 
public static void main(String[] args){ 
    JFrame frame = new JFrame(); 
    JPanel panel = new JPanel(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    panel.setPreferredSize(new Dimension(400, 400)); 
    frame.add(panel); 
    frame.pack(); 
    frame.setResizable(false); 

    SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
    panel.add(comp); 
    frame.setVisible(true); 
} 
} 

답변

4

그것은 잘 작동 : 여기 내 코드?

public Dimension getPreferredSize() { 
    return new Dimension(width, height); 
} 
다음 GUI가 렌더링 된 후에 당신이 선택하면 구성 요소의 크기가 0 인 것을, 당신은 가능성이 0

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
panel.add(comp); 
frame.setVisible(true); 

System.out.println(comp.getSize()); 

당신의 JComponent에가로 getPreferredSize을 무시하고 의미가 치수를 반환 가진 고려 찾을 수 있습니다

x와 y를 사용하려는 경우 getLocation()도 무시할 수 있습니다.

편집
또한 너비와 높이 필드를 설정해야합니다!

public SimpleComponent(int x, int y, int width, int height) { 
    this.x = x; 
    this.y = y; 
    this.width = width; // *** added 
    this.height = height; // *** added 
} 
+0

정말 이상합니다. 윈도우와 맥에서 항상 똑같은 문제가 발생했습니다. – lilroo

+0

아, 너비와 높이가 0으로 설정되었습니다. – lilroo

+0

너비와 높이 필드를 설정 했는데도 작동하지 않았지만 getPreferredSize() 메서드를 재정의했을 때 작동했습니다. – lilroo

-2

Whoaa! 옳은 대답은 아닙니다!

첫 번째 절대 CARDINAL SIN은 EDT 이외의 스레드에서이 모든 작업을 수행하는 것입니다. 여기에 대해 설명 할 공간이 없습니다 ... 그물에 대해 배울 수있는 약 300 억 개의 장소가 있습니다. 이 모든 코드는 다음, 동부 서머 타임 (이벤트 발송 쓰레드)에 Runnable에서 실행되면

:

preferredSize (당신이 원하는 경우에 당신이 할 수 있지만) 오버라이드 (override) 할 필요가 없습니다 당신이

...하지만 당신은 그것을 설정해야합니다.

당신은 절대적으로 직접 크기 (heightwidth, 또는 setSize())을 설정하지한다! 당신이 할 수있는 필요 DO 무엇

가 얻을 수있는 java.awt.Container, panel, 당신의 예에서,이 방법 Container.doLayout()입니다,하지만 ... "자체를 배치"하기는 API 문서에서 말한대로 :

이 컨테이너가 구성 요소를 배치합니다. 대부분의 프로그램은 이 메서드를 직접 호출하지 말고 대신 메서드를 호출해야합니다. 나는이 모든 validate, invalidate, paintComponent, paint 등 물건을 이해하려고 내 머리를 찢어 시간과 시간을 보냈습니다 ... 그리고 내 경험에서 이익하시기 바랍니다 덧붙여

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
comp.setPreferredSize(new Dimension(90, 90)); 
panel.add(comp); 

// the key to unlocking the mystery 
panel.validate(); 

frame.setVisible(true); 

:

솔루션은 그러므로 나는 아직도 내가 단지 표면을 긁 었다고 느낀다.

+0

http://stackoverflow.com/questions/10866762/use-of-overriding-getpreferredsize-instead-of-using-setpreferredsize-for-fix?rq=1 –

+0

확인 감사 ...하지만 당신이 사람 이었다면 누가이 질문에 대한 미래의 방문자들에게별로 도움이되지 않았던 나의 대답을 downvoted : 나의 대답은 받아 들인 대답보다 훨씬 낫고'setPreferredSize' /'getPreferredSize'에 대한 뉘앙스는 그것을 바꾸지 않는다. –

+0

오 ... 당신이 받아 들여진 대답의 응답자 인 것을 나는 안다! 그러나 214k의 담당자와 함께 내가 말한 모든 요점이 옳았음을 분명히 알아야하며, 정말로 당신의 대답은, 음, 어떻게 표현해야할까요? 개선의 여지가 남았습니다! –

관련 문제