[英]Ambiguous and inconstant order of method call
我正在编写一个程序,该程序使用两种绘制方法来根据以前的“绘制”方法产生的“绘制”产生输出。 有两种方法,draw1和draw2,其初始配置使用draw1给出,然后使用draw2生成下一行的输出。 但是,当我执行代码时,遇到有关定义的方法调用顺序的奇怪错误。 为了理解这一点,我在代码中添加了几个print()语句,但这只会加剧问题,因为添加print()语句似乎会影响方法调用本身的顺序。
这是代码(仍然是非常基本的版本)-
import java.awt.*;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
public class Processor extends JFrame
{
static int x=1;
public Processor()
{
setTitle("Automaton");
setSize(1000,1000);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
System.out.println("In constructor");
}
public void paint(Graphics g)
{
if(x==1)
draw(g);
else if(x==2)
draw2(g);
}
public void draw(Graphics g)
{
g.setColor(Color.WHITE);
g.fillRect(0,0,1000,1000);
System.out.println("In Draw");
}//This is the initial setting.
public void draw2(Graphics g)
{
g.setColor(Color.BLACK);
g.fillRect(500,22,50,50);
System.out.println("In Draw2");
}
public static BufferedImage toBufferedImage(Component component)
{
BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
component.paint(g);
return image;
}
public static void main(String[]args)
{
System.out.println("Start");
BufferedImage image;
Processor t=new Processor();
System.out.println("Middle");
image=toBufferedImage(t);
System.out.println("End");
//Color myColor=new Color(image.getRGB(500,500));
x=2;
image=toBufferedImage(t);
}
}
运行此代码时,我得到以下输出以及空白的空白屏幕,
Start
In Draw
In constructor
Middle
In Draw
In Draw
End
In Draw2
我想到了两个问题
1)为什么执行
image=toBufferedImage(t);
导致draw()被调用两次?
2)从“ In draw2”行中可以看出,程序已进入draw2()。 那我为什么会出现黑屏和白屏? (没有广场)。
而且,当我尝试添加另一个print()语句时,方法调用本身的顺序也会更改。 由于问题的长度过长,我没有为此添加代码和输出,但是我想知道对此是否有一些解释。
PS我正在使用BlueJ环境来运行我的代码。
如果您想知道从何处调用了方法,则有一个简单的技巧。 像这样更改您的paint
方法:
public void paint(Graphics g)
{
System.out.println("paint called from " + Thread.currentThread().getName());
new Exception().printStackTrace(System.out);
if(x==1)
draw(g);
else if(x==2)
draw2(g);
}
输出将告诉您调用不是来自toBufferedImage
而是来自名为AWT-EventQueue-0
的线程:
这是我的执行之一的输出:
Start
In constructor
Middle
paint called from AWT-EventQueue-0
java.lang.Exception
at Processor.paint(Processor.java:22)
at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
In Draw
paint called from main
java.lang.Exception
at Processor.paint(Processor.java:22)
at Processor.toBufferedImage(Processor.java:47)
at Processor.main(Processor.java:57)
In Draw
End
paint called from main
paint called from AWT-EventQueue-0
java.lang.Exception
at Processor.paint(Processor.java:22)
at Processor.toBufferedImage(Processor.java:47)
at Processor.main(Processor.java:62)
In Draw2
java.lang.Exception
at Processor.paint(Processor.java:22)
at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
In Draw2
paint called from AWT-EventQueue-0
java.lang.Exception
at Processor.paint(Processor.java:22)
at javax.swing.RepaintManager$3.run(RepaintManager.java:822)
at javax.swing.RepaintManager$3.run(RepaintManager.java:794)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:794)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
In Draw2
顺便说一句:我可以看到你错过的广场。
您正在从两个线程执行draw
方法: EventDispatchThread
和main
线程。
为避免这种情况,请勿从构造函数中调用setVisible(true)
,以后再从main()
调用。
您的绘画代码错误。
不要重写JFrame的paint()。 但是,如果您这样做,那么至少需要一个super.paint()来确保绘画正确完成。
通过覆盖JPanel上的paintComponent(...)完成绘制。 然后将面板添加到框架。
不要直接调用paint(...)。 Swing将创建Graphics对象,并将其传递给paint()方法。 而是在组件上调用repaint()。
因此,除了说这幅画是错误的以外,我无法回答您有关正在发生的一切问题。 绘画也应如此,我敢肯定这种矛盾会消失。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.