2017-09-09 75 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請參閱我剛添加到我的答案的更新。 –