方法调用的模糊和不定的顺序

时间:2017-09-27 16:51:41

标签: java swing user-interface methods bluej

我正在编写一个程序,它使用两种绘制方法来根据"绘制"生成输出。以前的#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环境来运行我的代码。

3 个答案:

答案 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方法:EventDispatchThreadmain线程。

为避免这种情况,请勿从构造函数中调用setVisible(true) - 稍后从main()调用它。

答案 2 :(得分:0)

你的绘画代码错了。

  1. 不要覆盖JFrame的paint()。但是,如果你曾经这样做,那么至少你需要一个super.paint()来确保绘画正确完成。

  2. 通过覆盖JPanel上的paintComponent(...)来完成绘画。然后将面板添加到框架中。

  3. 不要直接调用paint(...)。 Swing将创建Graphics对象并将其传递给paint()方法。而是在组件上调用repaint()。

  4. 所以我无法回答你关于发生的事情的任何问题,除非说这幅画是错的。所以这幅画也是如此,我确信不一致性会消失。