paintComponent는 어떻게 작동합니까?
이것은 매우 멍청한 질문 일 수 있습니다. Java를 배우기 시작했습니다.
paintComponent 메소드의 작동을 이해하지 못합니다. 무언가를 그리려면 paintComponent 메서드를 재정의해야합니다.
public void paintComponent(Graphics g)
{
...
}
그러나 언제 호출됩니까? 나는 "object.paintComponent (g)"와 같은 것을 본 적이 없지만 여전히 프로그램이 실행될 때 그려집니다.
그리고 그래픽 매개 변수는 무엇입니까? 그것이 어디에서 온 것인가? 메소드가 호출 될 때 매개 변수를 제공해야합니다. 그러나 앞서 말했듯이이 메서드는 명시 적으로 호출되지 않는 것 같습니다. 그렇다면 누가이 매개 변수를 제공합니까? 그리고 왜 그것을 Graphics2D로 캐스트해야합니까?
public void paintComponent(Graphics g)
{
...
Graphics2D g2= (Graphics2D) g;
...
}
귀하의 질문에 대한 (매우) 짧은 대답 paintComponent
은 "필요할 때"라는 것입니다. 때때로 Java Swing GUI 시스템을 "블랙 박스"로 생각하는 것이 더 쉬울 때가 있습니다.이 시스템에서는 많은 내부가 너무 많은 가시성없이 처리됩니다.
이동, 크기 조정, 초점 변경, 다른 프레임에 의해 숨기기 등 구성 요소를 다시 칠해야하는시기를 결정하는 여러 요소가 있습니다. 이러한 이벤트의 대부분은 자동으로 감지되며 paintComponent
해당 작업이 필요하다고 판단되면 내부적으로 호출됩니다.
나는 스윙과 수년 동안 일해 왔고 직접 전화를 걸거나 다른 곳에서 직접 전화 한 적이 없다고 생각 paintComponent
합니다. 가장 가까운 repaint()
방법 은 메서드를 사용하여 특정 구성 요소의 다시 그리기를 프로그래밍 방식으로 트리거하는 것입니다 (올바른 paintComponent
메서드를 다운 스트림으로 호출한다고 가정합니다 .
내 경험상 paintComponent
거의 직접 재정의되지 않습니다. 이러한 세분성을 요구하는 사용자 정의 렌더링 작업이 있다는 것을 인정하지만 Java Swing은 paintComponent
. 내 요점은 사용자 정의 렌더링 구성 요소를 롤링하기 전에 기본 JComponents 및 Layouts로 무언가를 할 수 없는지 확인하는 것입니다.
여기서 수행 할 수있는 두 가지 작업 :
- AWT 및 스윙에서 페인팅 읽기
- 디버거를 사용하고 paintComponent 메소드에 중단 점을 넣으십시오. 그런 다음 스택 추적으로 이동하여 Graphics 매개 변수를 제공하는 방법을 확인합니다.
정보를 위해 마지막에 게시 한 코드 예제에서 얻은 스택 트레이스가 있습니다.
Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 15 in TestPaint))
TestPaint.paintComponent(Graphics) line: 15
TestPaint(JComponent).paint(Graphics) line: 1054
JPanel(JComponent).paintChildren(Graphics) line: 887
JPanel(JComponent).paint(Graphics) line: 1063
JLayeredPane(JComponent).paintChildren(Graphics) line: 887
JLayeredPane(JComponent).paint(Graphics) line: 1063
JLayeredPane.paint(Graphics) line: 585
JRootPane(JComponent).paintChildren(Graphics) line: 887
JRootPane(JComponent).paintToOffscreen(Graphics, int, int, int, int, int, int) line: 5228
RepaintManager$PaintManager.paintDoubleBuffered(JComponent, Image, Graphics, int, int, int, int) line: 1482
RepaintManager$PaintManager.paint(JComponent, JComponent, Graphics, int, int, int, int) line: 1413
RepaintManager.paint(JComponent, JComponent, Graphics, int, int, int, int) line: 1206
JRootPane(JComponent).paint(Graphics) line: 1040
GraphicsCallback$PaintCallback.run(Component, Graphics) line: 39
GraphicsCallback$PaintCallback(SunGraphicsCallback).runOneComponent(Component, Rectangle, Graphics, Shape, int) line: 78
GraphicsCallback$PaintCallback(SunGraphicsCallback).runComponents(Component[], Graphics, int) line: 115
JFrame(Container).paint(Graphics) line: 1967
JFrame(Window).paint(Graphics) line: 3867
RepaintManager.paintDirtyRegions(Map<Component,Rectangle>) line: 781
RepaintManager.paintDirtyRegions() line: 728
RepaintManager.prePaintDirtyRegions() line: 677
RepaintManager.access$700(RepaintManager) line: 59
RepaintManager$ProcessingRunnable.run() line: 1621
InvocationEvent.dispatch() line: 251
EventQueue.dispatchEventImpl(AWTEvent, Object) line: 705
EventQueue.access$000(EventQueue, AWTEvent, Object) line: 101
EventQueue$3.run() line: 666
EventQueue$3.run() line: 664
AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method]
ProtectionDomain$1.doIntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) line: 76
EventQueue.dispatchEvent(AWTEvent) line: 675
EventDispatchThread.pumpOneEventForFilters(int) line: 211
EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 128
EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 117
EventDispatchThread.pumpEvents(int, Conditional) line: 113
EventDispatchThread.pumpEvents(Conditional) line: 105
EventDispatchThread.run() line: 90
Graphics 매개 변수는 여기에서 가져옵니다.
RepaintManager.paintDirtyRegions(Map) line: 781
The snippet involved is the following:
Graphics g = JComponent.safelyGetGraphics(
dirtyComponent, dirtyComponent);
// If the Graphics goes away, it means someone disposed of
// the window, don't do anything.
if (g != null) {
g.setClip(rect.x, rect.y, rect.width, rect.height);
try {
dirtyComponent.paint(g); // This will eventually call paintComponent()
} finally {
g.dispose();
}
}
If you take a look at it, you will see that it retrieve the graphics from the JComponent itself (indirectly with javax.swing.JComponent.safelyGetGraphics(Component, Component)
) which itself takes it eventually from its first "Heavyweight parent" (clipped to the component bounds) which it self takes it from its corresponding native resource.
Regarding the fact that you have to cast the Graphics
to a Graphics2D
, it just happens that when working with the Window Toolkit, the Graphics
actually extends Graphics2D
, yet you could use other Graphics
which do "not have to" extends Graphics2D
(it does not happen very often but AWT/Swing allows you to do that).
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
class TestPaint extends JPanel {
public TestPaint() {
setBackground(Color.WHITE);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(0, 0, getWidth(), getHeight());
}
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(300, 300);
jFrame.add(new TestPaint());
jFrame.setVisible(true);
}
}
The internals of the GUI system call that method, and they pass in the Graphics
parameter as a graphics context onto which you can draw.
Calling object.paintComponent(g)
is an error.
Instead this method is called automatically when the panel is created. The paintComponent()
method can also be called explicitly by the repaint()
method defined in Component
class.
The effect of calling repaint()
is that Swing automatically clears the graphic on the panel and executes the paintComponent
method to redraw the graphics on this panel.
참고URL : https://stackoverflow.com/questions/15544549/how-does-paintcomponent-work
'developer tip' 카테고리의 다른 글
GNU autotools : 디버그 / 릴리스 타겟? (0) | 2020.12.10 |
---|---|
명령 줄 출력 업데이트 (예 : 진행률) (0) | 2020.12.10 |
Android ViewGroup 충돌 : null 개체 참조의 'int android.view.View.mViewFlags'필드에서 읽기 시도 (0) | 2020.12.09 |
JS가있는 웹 사이트는 개발자 도구가 활성화 될 때까지 IE9에서 작동하지 않습니다. (0) | 2020.12.09 |
복잡한 데이터 구조 Redis (0) | 2020.12.09 |