Skip to content

Instantly share code, notes, and snippets.

@zilti
Created March 9, 2020 21:35
Show Gist options
  • Save zilti/7602e7c099c491734e2df9cf11e72fb4 to your computer and use it in GitHub Desktop.
Save zilti/7602e7c099c491734e2df9cf11e72fb4 to your computer and use it in GitHub Desktop.
Self-contained clojure program demonstrating how trying to edit a table cell causes infinite spam of CellEditEvents
#!/bin/sh
#_(
DEPS='
{:deps {org.clojure/clojure {:mvn/version "1.10.1"}
cljfx {:mvn/version "1.6.5"}}}
'
OPTS=''
exec clj $OPTS -Sdeps "$DEPS" "$0" "$@"
)
(require '[cljfx.api :as fx])
;; Table Data
(def tabledata
[{::index 0 :col_index 0 :col_a "Clojure" :col_b "rocks"}
{::index 1 :col_index 1 :col_a "JavaFX" :col_b "is awesome"}])
(def coldata
[:col_index :col_a :col_b])
;; Editable cell
(defn editable-cell [{:keys [fx/context data attr id value-converter]}]
(let [value (-> (fx/sub context :values)
(nth id)
(get attr)
str)]
(if (= (fx/sub context :edit) [attr id])
{:fx/type :text-field
:text-formatter {:fx/type :text-formatter
:value-converter value-converter
:value value}}
{:fx/type :label
:text (str value)})))
(defn editable-cell-factory [view data attr value-converter]
(fn [id]
{:text ""
:graphic {:fx/type view
:data data
:attr attr
:id id
:value-converter value-converter}}))
(defn generate-columns [data]
(reduce #(let [attr %2]
(cons {:fx/type :table-column
:cell-value-factory (fn [x] (get x ::index))
:cell-factory (editable-cell-factory editable-cell
data
attr
:default)
:on-edit-start {:event/type ::on-edit-start :attr attr}
:text (name %2)}
%1))
(list)
data))
;; Main UI data
(def *context
(atom
(fx/create-context {:values tabledata
:columns coldata
:edit nil})))
(defn mainwindow [{:keys [fx/context]}]
{:fx/type :stage
:showing true
:title "on-edit-start bug"
:scene {:fx/type :scene
:root {:fx/type :v-box
:children [{:fx/type :table-view
:editable true
:items (fx/sub context :values)
:columns (generate-columns (fx/sub context :columns))}]}}})
(defmulti event-handler :event/type)
(defmethod event-handler :default [_] nil)
(defmethod event-handler ::on-edit-start [{:keys [fx/context fx/event attr]}]
(when (instance? javafx.scene.control.TableColumn$CellEditEvent event)
(println event)
{:context (fx/swap-context context assoc :edit [attr (::index (.getRowValue event))])}))
(def app
(fx/create-app *context
:event-handler event-handler
:desc-fn (fn [_] {:fx/type mainwindow})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment