2012-01-31 41 views
2

我有一個應用程序,我有一個JPanel上繪製了一些矩形,根據從列表(ref())檢索的信息,後來我更改列表並需要重新繪製JPanel。自動和同時更改JPanel的組件

我不認爲我做的是正確的,它變得越來越慢。我可以以自治的方式繪製每個矩形,我的意思是,如果矩形'想'改變它的顏色,它會改變,矩形會自動在面板中改變。

任何人都可以幫助我嗎?以下是我正在使用的一些重要的代碼片段。

(defn fill [g x y c] 
    (doto g 
    (.setColor c) 
    (.fillRect 
     (+ *margin* (* y 15)) 
     (+ *margin* *margin-top* (* x 15)) 
       15 15))) 

(defn draw [g x y c] 
    (doto g 
    (.setColor c) 
    (.drawRect 
     (+ *margin* (* y 15)) 
     (+ *margin* *margin-top* (* x 15)) 
    15 15))) 

(defn make-panel 
     ([] 
     (proxy [JPanel] [] 
      (paintComponent 
      [g] 
      (doseq [i (range *size*) 
        j (range *size*)] 
       (let [ v (:color @(get-obj i j))] 
       (cond 
        (= v :blue) (fill g i j Color/BLUE) 
        (= v :red) (fill g i j Color/RED) 
        :else  (draw g i j Color/LIGHT_GRAY)))))))) 

;; This is how I repaint the frame, after changing the list 
(doto *frame* 
     (.setContentPane (make-panel)) 
     .repaint 
     (.setVisible true)) 

回答

3

首先,你並不需要更換面板(該(.setContentPane (make-panel))部分),只要重新粉刷舊面板。

做工作的最小量,只有當事情真正發生變化,你可以用手錶設施。如果你所有的矩形信息在一個單一的參考舉行,你可能會做這樣的事情:

(add-watch the-ref :update-rects 
    (fn [_ _ old new] 
    (update-rects-as-appropriate old new))) 

這裏update-rects-as-appropriate代表代碼,其計算基礎上,oldnew數據矩形的顏色和執行時更新 - 只有當 - 結果不同時。根據參考文獻中保存的數據的確切形式,在該過程的早期階段可能會變得很明顯,不存在差異,因此不需要執行整個計算。

如果每個矩形有一個裁判本身,你可以只更新基於新的狀態:

(add-watch the-ref :update-rect 
    (fn [_ _ _ new] 
    (update-rect the-rect new))) 

這裏the-rect是對應於the-refupdate-rect,其知道它的基礎上更新功能的矩形the-ref的狀態。

+0

真的不錯!我不知道這個手錶設施。這將有很大的幫助,我只有一個問題:在這個更新rects功能,我會改變長方形的狀態(顏色),但我將有另一個副作用是JPanel的重新粉刷,你知道如何只改變在面板中我想要的矩形,而不必重新繪製整個事物? – 2012-01-31 13:09:42

+0

@jonathancardoso:你必須適當地實現'paintComponent'並設計一個方法讓手錶註冊矩形的未決更新。在任何情況下手錶都需要'(.repaint panel)';爲他們一種可能的方法是添加'[[IJ]色]'條目(與'[IJ]'對應於它們的矩形),以在一個Atom /中Ref保持的地圖,然後'paintComponent'可遍歷這個地圖,例如'(doseq [[ij] color] updates-atom](cond(= color:blue)(fill g i j Color/BLUE)...))'。 – 2012-01-31 13:27:07

+0

或者,也許你可以*不*讓手錶調用'.repaint',但是從一個單獨的線程,例如每秒60次做到這一點...嗯,說實話,我沒有做任何GUI編程。也許一個更瞭解Swing繪圖的人會有更好的解決方案......如果他們碰巧是一個Java人,並且對我這樣做,我願意將它轉錄到Clojure中。 :-) – 2012-01-31 13:30:12