我正在编写一个程序,它使用两种绘制方法来根据"绘制"生成输出。以前的#34; paint"方法。有两种方法,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()语句时,方法调用自身的顺序会发生变化。由于问题的篇幅过长,我没有在代码和输出中添加,但我想知道是否有一些解释。
P.S我正在使用BlueJ环境来运行我的代码。
答案 0 :(得分:0)
如果你想知道从哪里调用一个方法,那就有一个简单的伎俩。像这样更改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
顺便说一句:我可以看到你错过的广场。
答案 1 :(得分:0)
您正在从两个线程执行draw
方法:EventDispatchThread
和main
线程。
为避免这种情况,请勿从构造函数中调用setVisible(true)
- 稍后从main()
调用它。
答案 2 :(得分:0)
你的绘画代码错了。
不要覆盖JFrame的paint()。但是,如果你曾经这样做,那么至少你需要一个super.paint()来确保绘画正确完成。
通过覆盖JPanel上的paintComponent(...)来完成绘画。然后将面板添加到框架中。
不要直接调用paint(...)。 Swing将创建Graphics对象并将其传递给paint()方法。而是在组件上调用repaint()。
所以我无法回答你关于发生的事情的任何问题,除非说这幅画是错的。所以这幅画也是如此,我确信不一致性会消失。