Hải*_*ong 61 java swing paintcomponent
这可能是一个非常无聊的问题.我刚刚开始学习Java
我不明白paintComponent方法的操作.我知道如果我想画一些东西,我必须覆盖paintComponent方法.
public void paintComponent(Graphics g)
{
...
}
Run Code Online (Sandbox Code Playgroud)
但它何时被称为?我从来没有看到像"object.paintComponent(g)"这样的东西,但它仍然是在程序运行时绘制的.
什么是Graphics参数?这个从哪里来?调用方法时必须提供参数.但正如我之前所说,似乎永远不会明确地调用此方法.那么谁提供这个参数呢?为什么我们必须将其转换为Graphics2D?
public void paintComponent(Graphics g)
{
...
Graphics2D g2= (Graphics2D) g;
...
}
Run Code Online (Sandbox Code Playgroud)
小智 38
对你的问题的(非常)简短回答paintComponent
是"当它需要时".有时将Java Swing GUI系统视为"黑盒子"更容易,其中许多内部构件在没有太多可见性的情况下处理.
有许多因素决定了何时需要重新绘制一个组件,包括移动,重新调整大小,改变焦点,被其他框架隐藏,等等.其中许多事件都是自动神奇地检测到的,并且paintComponent
在确定需要进行该操作时在内部调用.
我和Swing一起工作了很多年,我认为我没有paintComponent
直接打过电话,甚至没有直接打过电话.我最接近的是使用repaint()
方法以编程方式触发某些组件的重绘(我假设调用paintComponent
下游的正确方法).
根据我的经验,paintComponent
很少直接覆盖.我承认有些自定义渲染任务需要这样的粒度,但Java Swing确实提供了一套(相当)强大的JComponents和Layouts,可用于完成大部分繁重工作而无需直接覆盖paintComponent
.我想我的观点是确保在您尝试滚动自己的自定义渲染组件之前,您无法对本机JComponents和Layouts执行某些操作.
Gui*_*let 11
你可以在这做两件事:
仅供参考,以下是我在最后发布的代码示例中得到的堆栈跟踪:
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
Run Code Online (Sandbox Code Playgroud)
Graphics参数来自这里:
RepaintManager.paintDirtyRegions(Map) line: 781
Run Code Online (Sandbox Code Playgroud)
涉及的片段如下:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果你看一下它,你会发现它从JComponent本身(间接地javax.swing.JComponent.safelyGetGraphics(Component, Component)
)检索图形,它最终从它的第一个"重量级父级"(剪切到组件边界)中获取它,它自己从它获取它相应的原生资源.
关于你必须转换Graphics
为a 的事实,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);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
124520 次 |
最近记录: |