0

私は clojure で小さなツールを書いていますが、クリップボードに変更があったときを知りたいです。これは、何が起こっているかの単純化されたバージョンです。

(:import java.awt.Toolkit)

(:import (java.awt.datatransfer Clipboard
                                ClipboardOwner
                                Transferable
                                StringSelection
                                DataFlavor
                                FlavorListener))

(defn get-clipboard [] (. (Toolkit/getDefaultToolkit)
                     (getSystemClipboard)))

(defn get-content []
  (.getContents (get-clipboard) nil))


(def content (agent (get-content)))


(defn watch [key f]
 (add-watch content key f))

(defn -main []
  (while (not= content "banana-man")
    (watch :watcher
           (fn [key agent old-state new-state]
             (prn "-- agent Changed --")
             (prn "key" key)
             (prn "atom" agent)
             (prn "old-state" old-state)
             (prn "new-state" new-state)))))

メイン関数がすぐにシャットダウンしないようにするためだけに、while ループを追加しました。

これはエラーをスローせずに実行されますが、クリップボードに変更が加えられたときに報告したり、bannan-man をクリップボードにコピーしたときに while ループを停止したりしません。私はこれに数週間苦労してきましたが、単純なものが欠けていると確信しています。誰かアドバイスがあれば、本当に感謝します!

4

1 に答える 1

0

まず、コンテンツはエージェントであるため、文字列と等しくなることはありません。@その比較を行うには、使用するエージェントを deref する必要があります。

終了を防ぐために while ループは必要ありません。エージェント スレッド プールを使用する場合、Clojure は明示的に実行するまでシャットダウンしませんshutdown-agents。ただし、エージェントの更新を管理するために必要になります。

contentsendまたはを使用して更新関数を明示的に送信しない限り、最初の割り当て後に変更されることはありませんsend-off。名前に惑わされないようにしてください。エージェントは自律的ではなく、スケジュールされたタスクや繰り返されるタスクではありません。次のようなことを試してください:

(defn -main []
  (watch :watcher
           (fn [key agent old-state new-state]
             (prn "-- agent Changed --")
             (prn "key" key)
             (prn "atom" agent)
             (prn "old-state" old-state)
             (prn "new-state" new-state)))
  (while (not= @content "banana-man")
    (send-off content (fn [& _] (get-content)))
    (Thread/sleep 250))
  (shutdown-agents))
于 2015-03-30T06:53:50.903 に答える