Две вещи, которые вы можете сделать здесь:
- Прочитайте Рисование в AWT и Swing
- Используйте отладчик и поставьте точку останова в методе 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
Используемый фрагмент выглядит следующим образом:
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();
}
}
Если вы посмотрите на него, вы увидите, что он извлекает графику из самого JComponent (косвенно с помощью javax.swing.JComponent.safelyGetGraphics(Component, Component)
), который сам в конечном итоге берет его из своего первого «тяжеловесного родителя» (обрезанного до границ компонента), из которого он сам берет его. соответствующий родной ресурс.
Что касается того факта, что вы должны преобразовать Graphics
в Graphics2D
, так получилось, что при работе с Window Toolkit Graphics
фактически расширяет Graphics2D
, но вы можете использовать другие Graphics
, которые "не должны" расширять Graphics2D
(это не случается очень часто, но AWT/Swing позволяет вам это делать).
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);
}
}
person
Guillaume Polet
schedule
21.03.2013