2017-08-17 23 views
0

短版工作:的System.out.println()用一個簡單的getter中使得擺動重繪不如預期

這個工程並更改屏幕矩形的顏色:

public void test(){ 

    tilePointer.setIcon(Color.RED); 

} 

這不:

public void test(){ 

    System.out.println("color: " + tilePointer.getIcon());     
    tilePointer.setIcon(Color.RED); 

} 

龍版本:

在用Arraylists和對象測試某些東西時,我注意到了一些非常奇怪的行爲。

我有一個Tiles的二維數組(類Tile只有一個叫做icon的Color屬性)。

使用擴展JPanel並覆蓋drawComponent()的類將Tiles的二維數組繪製到屏幕上。該類有另一個2D數組,這次是Colors。它爲該數組中的每個Color繪製一個矩形。

以下方法用於將icon從Tile分配給擴展JPanel。方法調用只是類似panel.place(x,y,tiles[y][x].getIcon())

public void place(int x, int y, Color color){ 
    colors[y][x] = color; 
} 

我有從類瓷磚,tilePointer,這是一個「指針」的瓷磚中的一個陣列中的另一個對象(像tilePointer =瓦片[Y] [X])。

以下簡單的代碼片段工作得很好,看起來確實如此。它只是改變tilePointer的顏色,和屏幕上的矩形對應。

public void test(){ 

    tilePointer.setIcon(Color.RED); 

} 

現在來了真正的奇怪的部分。如果我改變test方法是:

public void test(){ 

    System.out.println("color: " + tilePointer.getIcon());     
    tilePointer.setIcon(Color.RED); 

} 

矩形只是簡單地不改變顏色。但是,如果在setIcon()之後執行另一個System.out.println("color: " + tilePointer.getIcon()),則可以看到該值實際發生了變化。

不,沒有什麼奇怪的方法getIcon()和setIcon()。他們只是

public Color getIcon() { 
    return icon; 
} 

public void setIcon(Color icon) { 
    this.icon = icon; 
} 

有誰知道什麼可能是造成這種情況?提前致謝。

[編輯]我忘了提一些重要的東西:

test()方法被稱爲在另一個線程。原因是test()應該比只重新調色一個Tile有更大的工作量。

public void startup() { 

    new Thread(() -> { 
     qtd = test(); 
    }).start(); 

} 

如果我讓它在應用程序的其餘部分修復它的同一線程上運行。

public void startup() { 

    qtd = test(); 

} 

但是,仍然沒有解釋導致問題的原因。但是,這可能與此有關。我很抱歉沒有提到這一點。

+2

這是很難檢查什麼是不能夠重現問題。也許這是https://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without-a-print-statement中描述的問題的變體。爲了得到正確的答案,我們需要[mcve]。 – Pshemo

回答

0

我只是在這裏體驗我的經歷(絕不應該認爲這是一個經過良好研究的答案)。我對Swing(以及大多數其他框架)的經驗是,當你走出一個單一的線程時,你將需要自己管理這個狀態。 Swing並不真正知道它是否需要更新,直到事件循環引起更新。

如果沒有一個完整的例子,這將是難以重現,但因爲你已經跳進多線程你應該擺圖形中讀出了其中之一是SwingUtilities.invokeLater(Runnable)

在如果你的改變的代碼的情況下該GUI發生在另一個線程上,您需要通過SwingUtilities重新加入主Swing線程,以確保您的代碼正在發生在該事件循環中。

我懷疑如果你要添加一個處理程序來改變別的東西(比如一個按鈕)然後點擊它,你會看到你的紅色圖標隨着那個按鈕的改變而出現。

長話短說,你可能要與此類似:

/* Forgive me, I'm jumping between five languages 
right now and this might not be the correct syntax for 
creating an anonymous threads */ 

SwingUtilities.invokeLater(()-> { 
    //All this code will run on the Swing Thread 
    System.out.println("color: " + tilePointer.getIcon());     
    tilePointer.setIcon(Color.RED); 
}) 
相關問題