处理语言在内部是如何工作的


注意:我在Eclipse上使用的是处理jar(core.jar)。

事实上,我想允许用户上传位置文件,在每一行都有城市名称和位置(纬度和经度坐标)。locFileSelected()是一个回调方法,当用户选择文件时就会调用它。

从上面的回调方法,控件转到另一个类的(DrawOnCanvas)方法readLocFileAndDraw(),该方法执行IO并从中创建Hashmap。该map用于迭代和绘制每个城市的点。

为了确保这一点,我在setup()方法中画了一个圆圈,它可以完美地工作。在解释完DrawOnCanvas类之后,我稍后将解释为什么使用sleep()。

import java.io.File;
import processing.core.PApplet;
public class TestingProcessing extends PApplet{
String locFilePath;
public static void main(String[] args) {
// Applet of Processing language
PApplet.main("TestingProcessing");
}
public void settings() {
size(800,900);
}
public void setup() {
background(255);
// Just a sample ellipse, it is drawn properly.
stroke(0);
fill(0);
ellipse(500,500,25,25);
selectInput("Select a file for Locations:", "locFileSelected"); 
// This will send control to call back method locFileSelected()
try {
Thread.sleep(10000); //10 sec
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("In setup()");
}
public void locFileSelected(File locFile) {
// I can't draw anything here too, I tried it
locFilePath = locFile.toString();
DrawOnCanvas draw = new DrawOnCanvas(this, locFilePath);
draw.readLocFileAndDraw();
System.out.println("In callback()");
} 

}

下面的这个文件做IO,我想在这个文件中为每个城市画点。在这个类的构造函数中,我已经传递了文件路径,以便分别进行IO。在readLocFileAndDraw()中,为了演示,我没有做IO,也没有创建Map。相反,我只是硬编码了一个椭圆。

import processing.core.PApplet;
public class DrawOnCanvas{
PApplet parent;
String locFilePath;
DrawOnCanvas(){ }
DrawOnCanvas(PApplet p, String locFilePath){
parent = p;
this.locFilePath = locFilePath;
}
/**
* Reading the locations file and storing them in map 
* @param locationsMap - Hash Map for the locations of each city in locations file
*/
public void readLocFileAndDraw() {
// Actually I create map here by doing Java IO for reading file
// I iterate each line and put in a map so that for each entry, I can
// draw a point on canvas
parent.stroke(0);
parent.fill(0);
parent.ellipse(200,200,15,10);
// Instead of reading from map which I have to do actually, I have hard-coded everything.

}
}

现在,在调试过程中,我注意到一旦用户得到浏览文件的提示,setup()方法的控制就会消失。例如,在没有sleep()的情况下,打印语句的顺序是

  • 在setup()中(首先打印,然后用户得到提示)
  • 在callback()中(这是在用户选择位置文件后打印的)

主要是readLocFileAndDraw()的椭圆从未绘制。

现在,我把sleep()放在setup()方法中,这样控制就保持在那里,现在代码流是

  • 用户得到提示,他选择文件
  • 打印"In callback()">
  • 10秒的总睡眠时间结束,然后"In setup()"和readLocFileAndDraw()中定义的椭圆一起打印:)

如果我超过了睡眠时间,那么它的工作原理与第一种没有睡眠的情况完全相同
内部发生了什么?我能感觉到一些线程正在被调度,但如何控制它?还有别的办法吗?谢谢

首先,在不同的类中拥有回调函数似乎有点奇怪。它可能会起作用,但它带来了很多奇怪之处:如果你有两个带有readLocFileAndDraw()函数的类呢?因此,我建议的第一件事是简化设计,并直接在TestingProcessing类中设置回调函数。

其次,没有args的DrawOnCanvas构造函数似乎也很奇怪。在这种情况下,parent的值将是null,当你尝试使用它时,这将导致NullPointerException。Procesing是在幕后使用反射,所以你必须非常小心这种事情。

最后,您可以尝试在回调函数中设置一些变量,并在draw()函数中使用这些变量。像这样的东西:

float x = 0;
float y = 0;
void setup() {
selectInput("Select a file.", "fileSelected");
}
void draw(){
background(64);
ellipse(x, y, 20, 20);
}
void fileSelected(){
x = 50;
y = 50;
}

最新更新