Java 自动同时更改JPanel的组件
我有一个应用程序,其中我有一个JPanel,上面画了一些矩形,基于从列表Java 自动同时更改JPanel的组件,java,multithreading,swing,clojure,Java,Multithreading,Swing,Clojure,我有一个应用程序,其中我有一个JPanel,上面画了一些矩形,基于从列表(ref())中检索到的信息,之后我更改了列表,需要重新绘制JPanel 我觉得我做得不对,速度越来越慢了。我可以用一种自主的方式画出每个矩形,我的意思是,如果矩形“想要”改变它的颜色,它就会改变,并且这个矩形会在面板中自动改变 有人能帮我吗?下面是我正在使用的一些重要代码片段 (defn fill [g x y c] (doto g (.setColor c) (.fillRect (+
(ref())
中检索到的信息,之后我更改了列表,需要重新绘制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))
首先,您不需要更换面板(
(.setContentPane(makepanel))
部分),只需重新绘制旧面板即可
只有当某些事情发生实际变化时,你才可以使用手表设备来完成最少量的工作。如果所有矩形的信息都保存在一个引用中,则可以执行以下操作:
(add-watch the-ref :update-rects
(fn [_ _ old new]
(update-rects-as-appropriate old new)))
此处,update rects as applicate
表示根据old
和new
数据计算矩形颜色的代码,并且仅在结果不同时执行更新。根据Ref中保存的数据的精确形式,在过程的早期可能很明显没有差异,因此不需要进行整个计算
如果每个矩形本身都有一个引用,则可以根据新状态进行更新:
(add-watch the-ref :update-rect
(fn [_ _ _ new]
(update-rect the-rect new)))
这里的
rect
是与ref
和update rect
相对应的矩形,一个知道如何根据ref
的状态进行更新的函数,真不错!我不知道这个手表厂。这将有很大帮助,我只有一个问题:在这个更新rects函数中,我将更改矩形的状态(颜色),但我会有另一个副作用,那就是重新绘制JPanel,你知道如何只更改面板中我想要的矩形,而不必重新绘制整个内容吗?@jonathancardoso:你必须适当地实现paintComponent
,并设计一种方法让手表注册矩形的待定更新。手表在任何情况下都需要(.重新喷漆面板)
;对于他们来说,一种可能的方法是将[[i j]color]
条目(与它们的矩形对应的[i j]
)添加到Atom/a Ref中保存的映射中,然后paintComponent
可以在该映射上迭代,例如(doseq[[i j]color]更新Atom](cond(=颜色:蓝色)(填充g i j颜色/蓝色)…)
。或者您可能无法让手表调用。重新绘制
,但可以从单独的线程执行,例如每秒60次。。。嗯,老实说,我根本没有做多少GUI编程。也许有人谁知道更多关于在秋千绘图将有一个更好的解决方案。。。如果他们碰巧是Java用户,我愿意将其转录到Clojure中,并同意我这样做。:-)你帮了我很多,这很有效,而且速度更快。通过重新绘制面板并调用(SwingUtilities/updateComponentTreeUI*frame*)