2017-09-09 63 views
2

我想在Processing中使用g4p-controls库来创建一个按钮,该按钮在另一个窗口中执行绘图命令。在这个库中,由码在处理中调用外部绘图命令

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

其中this是主要的小应用程序,和其他参数指定的名称,位置和渲染创建一个子窗口。 GWindow是PApplet的一个子类,所以我应该可以从我的代码中的任何地方调用绘图命令,例如window.background(0);,以将该窗口绘制成黑色。但是,这不起作用,我不知道为什么。毕竟,同样的代码工作时,我把它放在一个处理函数,并把它添加到窗口:

window.addDrawHandler(this, "windowDraw"); 

其中windowDraw方法是

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

展望源代码,平局处理方法windowDraw由GWindow对象调用,第一个参数为this,这正是我尝试使用window.background(0);时提及的对象。所以window应该是其调用background()方法来将画布涂成黑色的对象。

如果我误解了事件驱动编程的基础知识,请告诉我。看起来好像处理程序将相关小程序作为参数出于某种原因,但我真的无法看到处理函数内部和外部的调用有什么不同。

一些额外的注意事项:调用window.background(0);如果它在主要draw()函数内,则适用。如果它在setup()功能不起作用了,可惜对我来说,它没有,如果它在一个按钮处理程序方法的工作:

public void handleButtonEvents(GButton button, GEvent event) { 
    if (this.button == button) { 
    if (event == GEvent.PRESSED) { 
     window.background(0); 
    } 
    } 
} 

很显然,我已经确定,当我按下这个代码实际运行按钮。

更奇怪的是,如果我用window.strokeWeight(10)之类的东西替换上述图形调用window,实际发生更改,并且该画布中的后续行会绘制得更厚。它只是没有真正画出东西。我只是处于亏损状态。

回答

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() { 
    } 
} 

我也希望它可以工作,但我们看到了类似的灰色窗口为第二草图。我已经提交了一个bug here以从Processing开发人员获得关于这是否是预期行为的反馈。

在此期间,你将有更好的运气,如果你做这样的事情:

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); 
    } 
} 

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

更新:我在the bug我在GitHub上提交听到本·弗莱回(加工的创始人)和codeanticode(加工的开发者),我现在好多了,为什么这不起作用理解。

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

查看关于替代方法的讨论的错误,但老实说,您最好的选择可能是采用我概述的在草图之间共享变量的方法。

+0

是的,在绘图函数中使用条件是我现在使用的解决方法。但是我也想在外部触发器上执行数千次绘图命令的计算量很大的序列,并且这种解决方案不太有助于确保它只发生一次。 – ShnitzelKiller

+0

@ShnitzelKiller你也可以使用'PGraphics'缓冲区。或者'noLoop()'函数可能派上用场。 –

+0

@ShnitzelKiller请参阅我刚添加到我的答案的更新。 –