         lbl (s-label color)]
     (doto frame
       (.setLayout (FlowLayout.))
-                                        ;(.setDefaultCloseOperation
-                   ;JFrame/EXIT_ON_CLOSE)
+      (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
       (.add (:jbutton red))
       (.add (:jbutton green))
       (.add lbl)

                             (.loop value (.hold s-update 0))
                             (doto view
                               (.setLayout (FlowLayout.))
                                        ;(.setDefaultCloseOperation
                                        ;JFrame/EXIT_ON_CLOSE)
                               (.add lbl-value)
                               (.add (:jbutton plus))
                               (.add (:jbutton minus))))))

        lbl-sum (s-label (.map sum (apply1 [i] (str i))))]
    (doto frame
      (.setLayout (FlowLayout.))
      (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
      (.add (:jtext txt-a))
      (.add (:jtext txt-b))
      (.add lbl-sum)
      (.setSize 400 160)
      (.setVisible true))))

(defmacro set-grid! [constraints field value]
  `(set! (. ~constraints ~(symbol (name field)))
         ~(if (keyword? value)
            `(. java.awt.GridBagConstraints
                ~(symbol (name value)))
            value)))

(defmacro grid-bag-layout [container & body]
  (let [c (gensym "c")
        cntr (gensym "cntr")]
    `(let [~c (new java.awt.GridBagConstraints)
           ~cntr ~container]
       ~@(loop [result '() body body]
           (if (empty? body)
             (reverse result)
             (let [expr (first body)]
               (if (keyword? expr)
                 (recur (cons `(set-grid! ~c ~expr
                                          ~(second body))
                              result)
                        (next (next body)))
                 (recur (cons `(.add ~cntr ~expr ~c)
                              result)
                        (next body)))))))))

(defn s-spinner
  [initial-value]
  (let [s-set-value (StreamLoop.)
        text-field (s-text-field (.map s-set-value (apply1 [v] (str v))) (str initial-value) 5)
        parse-int (fn [t] (try
                           (Integer/parseInt t)
                           (catch NumberFormatException e
                             0)))
        value (.map (:cell text-field) (apply1 [txt] (parse-int txt)))
        plus (s-button "+")
        minus (s-button "-")
        spinner (JPanel. (GridBagLayout.))
        s-plus-delta (.map (:s-clicked plus) (apply1 [u] 1))
        s-minus-delta (.map (:s-clicked minus) (apply1 [u] -1))
        s-delta (.orElse s-plus-delta s-minus-delta )]
    (doto spinner
      (grid-bag-layout
       :gridx 0 :gridy 0
       :gridwidth 1 :gridheight 2
       :fill :BOTH
       :weightx 1.0
       (:jtext text-field)
       :gridx 1 :gridy 0
       :gridwidth 1 :gridheight 1
       (:jbutton plus)
       :gridx 1 :gridy 1
       (:jbutton minus)))
    (.loop s-set-value (.snapshot s-delta value (apply2 [delta value]
                                                        (println (str delta ":" value))
                                                        (+ delta value))))
    {:jpanel spinner :cell value}))

(defn spinme
  []
  (let [view (JFrame.)]
    (Transaction/runVoid (fn []
                           (let [spnr (s-spinner 0)]
                             (.add view (:jpanel spnr)))))
    (doto view
      (.setLayout (FlowLayout.))
      (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
      (.setSize 400 160)
      (.setVisible true))))


(defn -main
  [& args]
  (spinme)
  (add)
  (spinner)
  (translate)
