在Processing中外部调用绘图命令

时间:2017-09-09 20:35:59

标签: user-interface event-handling processing

我正在尝试在Processing中使用g4p-controls库来创建一个在另一个窗口中执行绘图命令的按钮。在此库中,代码

创建子窗口
GWindow window = GWindow.getWindow(this, "Main", 100, 50, 500, 500, JAVA2D);

其中this是主applet,其他参数指定名称,位置和渲染器。 GWindow是PApplet的子类,所以我应该能够从我的代码中的任何地方调用绘图命令,例如window.background(0);,以将该窗口绘制为黑色。但是,这不起作用,我无法弄清楚原因。毕竟,当我把它放在一个处理函数中并将它添加到窗口时,相同的代码就可以工作了:

window.addDrawHandler(this, "windowDraw");

windowDraw方法

public void windowDraw(PApplet app, GWinData data) {
  app.background(0);
}

查看源代码,GWindow对象使用第一个参数windowDraw调用绘制处理程序方法this,这正是我尝试window.background(0);时引用的对象。所以window应该是调用background()方法将画布涂成黑色的对象。

如果我误解了事件驱动编程的基本信息,请告诉我。看起来处理程序似乎将相关的applet作为一个参数作为理由,但我真的看不出处理函数内外调用的不同之处。

其他一些注意事项:如果window.background(0);功能位于主draw()内,则可以调用setup()。它在public void handleButtonEvents(GButton button, GEvent event) { if (this.button == button) { if (event == GEvent.PRESSED) { window.background(0); } } } 函数中不起作用,不幸的是,如果它在按钮处理程序方法中它不起作用:

window

显然,当我按下按钮时,我已确保此代码实际运行。

更奇怪的是,如果我用window.strokeWeight(10)之类的内容将上述绘图调用替换为pri | grp ---------- 1 | 1 2 | 9 3 | 2 4 | 1 5 | 2 6 | 9 7 | 2 ,则实际发生了更改,并且该画布中的后续行被绘制得更厚。它只是没有真正画出东西。我只是不知所措。

1 个答案:

答案 0 :(得分:1)

将来,请尝试发布MCVE而不是一堆断开连接的代码段。这是一个例子:

import g4p_controls.*;

GWindow window;

void setup(){
  window = GWindow.getWindow(this, "Main", 100, 50, 500, 500, JAVA2D);
}

void draw(){
   background(255, 0, 0); 
   window.ellipse(mouseX, mouseY, 25, 25);
   window.draw();
}

void mousePressed(){
  window.background(0, 255, 0); 
}

我希望此代码在第二个窗口中绘制圆圈,并在第一个窗口中按鼠标时在第二个窗口中绘制绿色。然而,它似乎只是偶尔画出那些东西。

事实上,这是相同类型的程序,在“纯处理”中没有使用G4P库:

SecondApplet sa;

void setup() {
  String[] args = {"TwoFrameTest"};
  sa = new SecondApplet();
  PApplet.runSketch(args, sa);
}

void settings() {  
  size(200, 200);
}

void draw() {
  background(0);
  sa.ellipse(mouseX, mouseY, 25, 25);
}   

void mousePressed() {
  sa.background(255, 0, 0);
}

public class SecondApplet extends PApplet {

  public void settings() {
    size(200, 200);
  }

  void draw() {
  }
}

我也希望这可行,但我们会看到第二个草图的类似灰色窗口。我已经提交了一个错误here来获取Processing devs关于这是否是预期行为的反馈。

与此同时,如果你这样做,你会有更好的运气:

SecondApplet sa;

float drawMouseX;
float drawMouseY;
color drawBackground = #0000ff;

void setup() {
  String[] args = {"TwoFrameTest"};
  sa = new SecondApplet();
  PApplet.runSketch(args, sa);
}

void settings() {  
  size(200, 200);
}

void draw() {
  background(0);
  drawMouseX = mouseX;
  drawMouseY = mouseY;
}   

void mousePressed() {
  drawBackground = #00ff00;
}

public class SecondApplet extends PApplet {

  public void settings() {
    size(200, 200);
  }

  void draw() {
    background(drawBackground);
    ellipse(drawMouseX, drawMouseY, 25, 25);
  }
}

我们现在设置一些变量,然后在第二个applet的draw()函数中使用,而不是直接调用绘图函数。有很多方法可以做到这一点,但想法是一样的:只是不要直接调用draw函数,而是从draw()函数调用它们。

更新:我在Ben Fry(Processing的创始人)和codeanticode(Processing的开发人员)上回复the bug我在GitHub上提交了文章,我现在明白为什么这样做了不起作用。

它不起作用的原因是因为每个草图都有自己的UI线程,负责绘制和处理事件。你不能从不同的线程绘制草图,否则会发生奇怪的事情。但是你试图从第一个sketche的事件线程绘制第二个草图,这是第二个草图的绘图线程,这就是为什么它不起作用。

请参阅有关替代方法讨论的错误,但老实说,最好的选择可能是采用我在草图之间共享变量的方法。