From ad3230cf3c95de1f00a4e7c00e4792b1a0a856e8 Mon Sep 17 00:00:00 2001 From: Efrain Date: Mon, 24 Nov 2014 17:20:42 +0000 Subject: [PATCH 1/2] BugFix #23 Scene is using the default constructor when it should use the already define specific to Scene Scene needs the root in the constructor whereas the default constructor does not use any parameter. --- README.md | 2 +- project.clj | 4 ++-- src/clojurefx/core.clj | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 676ad67..537006f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Note that this library is brand-new and lacks a lot of features; I'm heavily wor Lots of neat features will follow soon! -Installation: `[clojurefx "0.0.12"]` +Installation: `[clojurefx "0.0.13"]` ### Short info about the state of the project Right now I'm rather busy and have a few things to do on a deadline. That's why there's little activity right now. Expect more activity in about one to two months. *I will not abandon this project*. Feel free to add stuff (including tests) and send pull requests - I will review them in about two days and accept them if they're allright. diff --git a/project.clj b/project.clj index 673ac3f..c8e13d5 100644 --- a/project.clj +++ b/project.clj @@ -1,11 +1,11 @@ -(defproject clojurefx "0.0.13-SNAPSHOT" +(defproject clojurefx "0.0.13" :description "Helper functions and probably a wrapper to simplify usage of JavaFX in Clojure. This is meant to be used with Java 8. If you add JavaFX 2.2 to your classpath it might still work, but that isn't tested. [This Project On GitHub](https://www.github.com/zilti/clojurefx) -**Installation: `[clojurefx \"0.0.11\"]`** +**Installation: `[clojurefx \"0.0.13\"]`** Navigation ---------- diff --git a/src/clojurefx/core.clj b/src/clojurefx/core.clj index 998e4ed..57a8d80 100644 --- a/src/clojurefx/core.clj +++ b/src/clojurefx/core.clj @@ -436,7 +436,7 @@ Don't use this yourself; See the macros \"fx\" and \"deffx\" below. `(defmethod construct-node '~clazz [cl# ar#] (apply constructor-helper cl# (for [k# ~keys] (get ar# k#))))) -(defmulti construct-node (fn [class args] (resolve class))) +(defmulti construct-node (fn [class args] class)) (defmethod construct-node :default [class _] (run-now (eval `(new ~class))) ) From 479f6c17d02a4871f61ad921a529828e6e1af718 Mon Sep 17 00:00:00 2001 From: Efrain Date: Tue, 31 Mar 2015 15:44:08 +0100 Subject: [PATCH 2/2] Added bind-simple-property in order to make it work with javafx.beans.property.SimpleStringProperty Added some swappers and constructors Added style-classes to the fx builder Bumped the version to 0.0.14 --- README.md | 2 +- project.clj | 6 +++--- src/clojurefx/core.clj | 45 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 537006f..669c964 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Note that this library is brand-new and lacks a lot of features; I'm heavily wor Lots of neat features will follow soon! -Installation: `[clojurefx "0.0.13"]` +Installation: `[clojurefx "0.0.14"]` ### Short info about the state of the project Right now I'm rather busy and have a few things to do on a deadline. That's why there's little activity right now. Expect more activity in about one to two months. *I will not abandon this project*. Feel free to add stuff (including tests) and send pull requests - I will review them in about two days and accept them if they're allright. diff --git a/project.clj b/project.clj index c8e13d5..49d59ed 100644 --- a/project.clj +++ b/project.clj @@ -1,11 +1,11 @@ -(defproject clojurefx "0.0.13" +(defproject clojurefx "0.0.14" :description "Helper functions and probably a wrapper to simplify usage of JavaFX in Clojure. This is meant to be used with Java 8. If you add JavaFX 2.2 to your classpath it might still work, but that isn't tested. [This Project On GitHub](https://www.github.com/zilti/clojurefx) -**Installation: `[clojurefx \"0.0.13\"]`** +**Installation: `[clojurefx \"0.0.14\"]`** Navigation ---------- @@ -18,7 +18,7 @@ Navigation :lein-release {:deploy-via :clojars} :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} - :dependencies [[org.clojure/clojure "1.5.1"]] + :dependencies [[org.clojure/clojure "1.6.0"]] :plugins [[lein-marginalia "0.7.1"] [lein-midje "3.1.3-RC2"] [lein-release "1.0.5"]] diff --git a/src/clojurefx/core.clj b/src/clojurefx/core.clj index 57a8d80..4e5c56c 100644 --- a/src/clojurefx/core.clj +++ b/src/clojurefx/core.clj @@ -100,6 +100,8 @@ Runs the code on the FX application thread and waits until the return value is d ;; ## Collection helpers ;; This probably isn't the ideal approach for mutable collections. Check back for better ones. +(defn list->observable [l] + (javafx.collections.FXCollections/observableArrayList l)) (defn seq->observable [s] (javafx.collections.FXCollections/unmodifiableObservableList s)) @@ -153,6 +155,25 @@ args is a named-argument-list, where the key is the property name (e.g. :text) a `(do ~@(for [entry# m#] `(bind-property!* ~obj ~(key entry#) ~(val entry#)))))) + +(defn bind-simple-property! [property at] + (let [listeners (atom []) + inv-listeners (atom []) + observable (reify javafx.beans.value.ObservableValue + (^void addListener [this ^javafx.beans.value.ChangeListener l] (swap! listeners conj l)) + (^void addListener [this ^javafx.beans.InvalidationListener l] (swap! inv-listeners conj l)) + (^void removeListener [this ^javafx.beans.InvalidationListener l] (swap! inv-listeners #(remove #{l} %))) + (^void removeListener [this ^javafx.beans.value.ChangeListener l] (swap! listeners #(remove #{l} %))) + (getValue [this] @at))] + (add-watch at :simple-listener + (fn [_ r oldS newS] + (run-now (doseq [listener @inv-listeners] (.invalidated listener observable)) + (doseq [listener @listeners] (.changed listener observable oldS newS))))) + (run-now (.bind property observable)) + (run-now (doseq [listener @inv-listeners] (.invalidated listener observable))) + property)) + + ;; ## Events (defn- prep-key-code [k] {:keycode k @@ -322,6 +343,8 @@ The listener gets a preprocessed event map as shown above. (def-simple-swapper javafx.scene.control.ContextMenu .getItems .setAll) (def-simple-swapper javafx.scene.control.ListView .getItems .setAll) (def-simple-swapper javafx.scene.control.Menu .getItems .setAll) +(def-simple-swapper javafx.scene.control.MenuButton .getItems .setAll) +(def-simple-swapper javafx.scene.control.CustomMenuItem .getItems .setAll) (def-simple-swapper javafx.scene.control.MenuBar .getMenus .setAll) (def-simple-swapper javafx.scene.control.TableColumn .getColumns .setAll) (def-simple-swapper javafx.scene.control.TabPane .getTabs .setAll) @@ -330,6 +353,14 @@ The listener gets a preprocessed event map as shown above. (def-simple-swapper javafx.scene.control.TreeItem .getChildren .setAll) (def-simple-swapper javafx.scene.control.TreeTableColumn .getColumns .setAll) (def-simple-swapper javafx.scene.shape.Path .getElements .setAll) +(def-simple-swapper javafx.scene.chart.PieChart .getData .setAll) +(def-simple-swapper javafx.scene.chart.XYChart .getData .setAll) +(def-simple-swapper javafx.scene.chart.LineChart .getData .setAll) +(def-simple-swapper javafx.scene.chart.BarChart .getData .setAll) +(def-simple-swapper javafx.scene.chart.AreaChart .getData .setAll) +(def-simple-swapper javafx.scene.chart.StackedAreaChart .getData .setAll) +(def-simple-swapper javafx.scene.chart.ScatterChart .getData .setAll) + (defmethod swap-content!* javafx.scene.control.SplitPane [obj fun] (let [data {:items (into [] (.getItems obj)) @@ -340,6 +371,8 @@ The listener gets a preprocessed event map as shown above. ;; TODO TreeTableView +(defmethod swap-content!* javafx.scene.control.CustomMenuItem [obj fun] + (.setContent obj (fun (.getContent obj)))) (defmethod swap-content!* javafx.scene.control.ScrollPane [obj fun] (.setContent obj (fun (.getContent obj)))) (defmethod swap-content!* javafx.scene.control.TitledPane [obj fun] @@ -442,6 +475,13 @@ Don't use this yourself; See the macros \"fx\" and \"deffx\" below. ) (construct javafx.scene.control.ColorPicker [:color]) +(construct javafx.scene.control.TableColumn [:items]) +(construct javafx.scene.control.cell.PropertyValueFactory [:property]) +(construct javafx.scene.chart.AreaChart [:x-axis :y-axis :ser-list]) +(construct javafx.scene.chart.StackedAreaChart [:x-axis :y-axis :ser-list]) +(construct javafx.scene.chart.LineChart [:x-axis :y-axis :ser-list]) +(construct javafx.scene.chart.BarChart [:x-axis :y-axis :ser-list]) +(construct javafx.scene.chart.ScatterChart [:x-axis :y-axis :ser-list]) (construct javafx.scene.layout.BackgroundImage [:image :repeat-x :repeat-y :position :size]) (construct javafx.scene.layout.BorderImage [:image :widths :insets :slices :filled :repeat-x :repeat-y]) ;; TODO Wrapper for BorderWidths, BorderRepeat and Insets @@ -461,7 +501,7 @@ Don't use this yourself; See the macros \"fx\" and \"deffx\" below. ;; ## Content creation (defn fx* [ctrl & args] (let [args# (if-not (and (nil? (first args)) (map? (first args))) (apply hash-map args) (first args)) - {:keys [bind listen content children]} args# + {:keys [bind listen content children style-classes]} args# props# bind listeners# listen content# (if (or (seq? content) (seq? children)) @@ -482,7 +522,8 @@ Don't use this yourself; See the macros \"fx\" and \"deffx\" below. (if (or (not (nil? content#)) (and (seq? content#) (not (empty? content#)))) (swap-content!* obj# (fn [_] content#))) - obj#))) + (if style-classes (.addAll (.getStyleClass obj#) (list->observable style-classes))) + obj#))) (defmacro fx " The central macro of ClojureFX. This takes the name of a node as declared in the pkgs atom and