no message
This commit is contained in:
parent
f659e88fa8
commit
c26d449f66
7 changed files with 42 additions and 165 deletions
|
@ -10,7 +10,7 @@ import javafx.stage.Stage;
|
||||||
*/
|
*/
|
||||||
public class AppWrap extends Application {
|
public class AppWrap extends Application {
|
||||||
|
|
||||||
String ns, fn;
|
private String ns, fn;
|
||||||
|
|
||||||
public AppWrap(String ns, String fn) {
|
public AppWrap(String ns, String fn) {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -2,40 +2,41 @@
|
||||||
(:require [taoensso.timbre :as timbre]
|
(:require [taoensso.timbre :as timbre]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.zip :as zip]
|
[clojure.zip :as zip]
|
||||||
[clojurefx.protocols :as p]
|
[clojurefx.protocols :as p]))
|
||||||
[clojure.java.io :refer :all])
|
|
||||||
(:import (clojurefx AppWrap)))
|
;; Fuck you, whoever made that API design.
|
||||||
|
(defonce force-toolkit-init (javafx.embed.swing.JFXPanel.))
|
||||||
|
|
||||||
|
(timbre/refer-timbre)
|
||||||
|
|
||||||
|
(import '(clojurefx AppWrap)
|
||||||
|
'(javafx.scene.control Labeled Label TextField TextArea CheckBox ComboBox Menu MenuItem MenuBar
|
||||||
|
MenuButton ContextMenu ToolBar SplitPane ScrollPane Accordion
|
||||||
|
TitledPane TabPane Tab TableColumnBase Labeled ButtonBase)
|
||||||
|
'(javafx.scene Node Scene Parent)
|
||||||
|
'(javafx.scene.layout Pane VBox)
|
||||||
|
'(javafx.stage Stage)
|
||||||
|
'(javafx.collections FXCollections ObservableList)
|
||||||
|
'(javafx.css Styleable)
|
||||||
|
'(javafx.event Event ActionEvent EventTarget)
|
||||||
|
'(java.util Collection))
|
||||||
|
|
||||||
(defn gen-stage! [nspc fun]
|
(defn gen-stage! [nspc fun]
|
||||||
(let [appwrap (AppWrap. nspc fun)]
|
(let [appwrap (AppWrap. nspc fun)]
|
||||||
(.launch appwrap)))
|
(.launch appwrap nil)))
|
||||||
|
|
||||||
;; ## Threading helpers
|
;; ## Threading helpers
|
||||||
|
|
||||||
(defn run-later*"
|
(defmacro run-later "Simple wrapper for Platform/runLater." [& body]
|
||||||
Simple wrapper for Platform/runLater. You should use run-later.
|
`(javafx.application.Platform/runLater (fn [] ~@body)))
|
||||||
" [f]
|
|
||||||
(assert (instance? Runnable f))
|
|
||||||
(javafx.application.Platform/runLater f)
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(defmacro run-later [& body]
|
(defmacro run-now "Runs the code on the FX application thread and waits until the return value is delivered."
|
||||||
`(run-later* (fn [] ~@body)))
|
[& body]
|
||||||
|
`(if (javafx.application.Platform/isFxApplicationThread)
|
||||||
(defn run-now* "
|
(apply (fn [] ~@body) [])
|
||||||
A modification of run-later waiting for the running method to return. You should use run-now.
|
(let [result (promise)]
|
||||||
" [f]
|
(run-later (deliver result (try (fn [] ~@body) (catch Throwable e e))))
|
||||||
(if (javafx.application.Platform/isFxApplicationThread)
|
@result)))
|
||||||
(apply f [])
|
|
||||||
(let [result (promise)]
|
|
||||||
(run-later
|
|
||||||
(deliver result (try (f) (catch Throwable e e))))
|
|
||||||
@result)))
|
|
||||||
|
|
||||||
(defmacro run-now "
|
|
||||||
Runs the code on the FX application thread and waits until the return value is delivered.
|
|
||||||
" [& body]
|
|
||||||
`(run-now* (fn [] ~@body)))
|
|
||||||
|
|
||||||
(defn collize "
|
(defn collize "
|
||||||
Turns the input into a collection, if it isn't already.
|
Turns the input into a collection, if it isn't already.
|
||||||
|
@ -44,19 +45,6 @@
|
||||||
input
|
input
|
||||||
(list input)))
|
(list input)))
|
||||||
|
|
||||||
(timbre/refer-timbre)
|
|
||||||
|
|
||||||
(import (javafx.scene.control Labeled Label TextField TextArea CheckBox ComboBox Menu MenuItem MenuBar
|
|
||||||
MenuButton ContextMenu ToolBar SplitPane ScrollPane Accordion
|
|
||||||
TitledPane TabPane Tab TableColumnBase Labeled ButtonBase)
|
|
||||||
(javafx.scene Node Scene Parent)
|
|
||||||
(javafx.scene.layout Pane VBox)
|
|
||||||
(javafx.stage Stage)
|
|
||||||
(javafx.collections FXCollections ObservableList)
|
|
||||||
(javafx.css Styleable)
|
|
||||||
(javafx.event Event ActionEvent EventTarget)
|
|
||||||
(java.util Collection))
|
|
||||||
|
|
||||||
(defn pred-protocol [proto check]
|
(defn pred-protocol [proto check]
|
||||||
(let [impls (keys (proto :impls))
|
(let [impls (keys (proto :impls))
|
||||||
check (type check)]
|
check (type check)]
|
||||||
|
|
|
@ -53,10 +53,6 @@
|
||||||
(trace "Key:" k " " (type k) "Value:" v " " (type v))
|
(trace "Key:" k " " (type k) "Value:" v " " (type v))
|
||||||
(when (nil? translation)
|
(when (nil? translation)
|
||||||
(throw (Exception. (str "Property" k "not available in translation map."))))
|
(throw (Exception. (str "Property" k "not available in translation map."))))
|
||||||
;; (when-not ((pred-substitute argument) v)
|
|
||||||
;; (throw (Exception. (str "Input type" v "is not compatible with expected type for" k))))
|
|
||||||
;; (when-not ((pred-substitute parent) node)
|
|
||||||
;; (throw (Exception. (str "Property" k "not available for class" (class node)))))
|
|
||||||
((setter translation) node v)))
|
((setter translation) node v)))
|
||||||
node)
|
node)
|
||||||
|
|
||||||
|
@ -73,14 +69,6 @@
|
||||||
eval)
|
eval)
|
||||||
(apply dissoc props mandatory))))
|
(apply dissoc props mandatory))))
|
||||||
|
|
||||||
;; (ann resolv-o-matic [(U String Keyword Symbol Class) -> Class])
|
|
||||||
;; (defn resolv-o-matic [thing]
|
|
||||||
;; (cond
|
|
||||||
;; (symbol? thing) (ns-resolve (the-ns 'clojurefx.clojurefx) thing)
|
|
||||||
;; (keyword? thing) (recur (name thing))
|
|
||||||
;; (string? thing) (recur (symbol thing))
|
|
||||||
;; :else thing))
|
|
||||||
|
|
||||||
(defn compile
|
(defn compile
|
||||||
([args] (compile args []))
|
([args] (compile args []))
|
||||||
([[obj & other] accu]
|
([[obj & other] accu]
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
(ns clojurefx.clojurefx-test
|
|
||||||
(:refer-clojure :exclude [compile meta with-meta])
|
|
||||||
(:require [clojurefx.factory :as factory]
|
|
||||||
[clojurefx.protocols :refer :all])
|
|
||||||
(:use midje.sweet
|
|
||||||
clojurefx.clojurefx))
|
|
||||||
|
|
||||||
(import (javafx.scene.layout VBox)
|
|
||||||
(javafx.scene.control ScrollPane Button Label))
|
|
||||||
|
|
||||||
;;## Element testing
|
|
||||||
|
|
||||||
;;## Event testing
|
|
||||||
;;(def button (new Button))
|
|
||||||
(def button (atom nil))
|
|
||||||
(def fired? (atom false))
|
|
||||||
(facts "Events"
|
|
||||||
(fact "Creating button with event handler"
|
|
||||||
(class (reset! button (factory/compile [Button {:action (fn [_] (reset! fired? true))}]))) => javafx.scene.control.Button)
|
|
||||||
(fact "Firing the event and checking the result"
|
|
||||||
(do (fire! @button)
|
|
||||||
@fired?) => true))
|
|
||||||
|
|
||||||
;;## IdMapper
|
|
||||||
(def example-graph
|
|
||||||
(factory/compile
|
|
||||||
[VBox {:id "topBox"
|
|
||||||
:children [Button {:id "button"
|
|
||||||
:text "Close"}
|
|
||||||
ScrollPane {:content [Label {:id "label"
|
|
||||||
:text "This rocks."}]}]}]))
|
|
||||||
|
|
||||||
(facts "Id mapper"
|
|
||||||
(fact "Getting a top-level entry"
|
|
||||||
(type (get-node-by-id example-graph "topBox")) => javafx.scene.layout.VBox)
|
|
||||||
(fact "Getting an entry in an FXParent"
|
|
||||||
(type (get-node-by-id example-graph "button")) => javafx.scene.control.Button)
|
|
||||||
(fact "Getting an entry in an FXParent and an FXContainer"
|
|
||||||
(type (get-node-by-id example-graph "label")) => javafx.scene.control.Label)
|
|
||||||
(fact "Fetching the whole id map."
|
|
||||||
(map? (get-id-map example-graph)) => true)
|
|
||||||
(fact "Fetching label text from id-map."
|
|
||||||
(-> (get-id-map example-graph)
|
|
||||||
:label
|
|
||||||
get-value) => "This rocks."))
|
|
13
test/clojurefx/exampleWindow.fxml
Normal file
13
test/clojurefx/exampleWindow.fxml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
|
||||||
|
|
||||||
|
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="677.0" prefWidth="890.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
|
<children>
|
||||||
|
<TextField id="simpleTextField" layoutX="14.0" layoutY="14.0" />
|
||||||
|
<Button id="simpleButton" layoutX="163.0" layoutY="14.0" mnemonicParsing="false" text="Button" />
|
||||||
|
</children>
|
||||||
|
</Pane>
|
|
@ -1,52 +0,0 @@
|
||||||
(ns clojurefx.factory-test
|
|
||||||
(:refer-clojure :exclude [compile meta with-meta])
|
|
||||||
(:require [clojurefx.protocols :refer :all])
|
|
||||||
(:use midje.sweet
|
|
||||||
clojurefx.factory)
|
|
||||||
(:import (javafx.scene.control Button Label ScrollPane)
|
|
||||||
(javafx.scene.layout VBox)))
|
|
||||||
|
|
||||||
(def fxml-node (atom nil))
|
|
||||||
|
|
||||||
(facts "FXML loading"
|
|
||||||
(fact "Load the fxml file"
|
|
||||||
(type (reset! fxml-node (load-fxml "resources/test.fxml"))) => javafx.scene.layout.VBox)
|
|
||||||
(fact "Get VBox id"
|
|
||||||
(.getId @fxml-node) => "topBox"))
|
|
||||||
|
|
||||||
(def example-graph
|
|
||||||
[VBox {:id "topBox"
|
|
||||||
:children [Button {:id "button"
|
|
||||||
:text "Close"}
|
|
||||||
ScrollPane {:content [Label {:id "label"
|
|
||||||
:text "This rocks."}]}]}])
|
|
||||||
|
|
||||||
(def example-graph2
|
|
||||||
[VBox {:id "topBox"
|
|
||||||
:children [Button {:id "button"
|
|
||||||
:text "Close"}
|
|
||||||
(new javafx.scene.control.Label "Precompiled")
|
|
||||||
Button {:id "button2"
|
|
||||||
:text "OK"}
|
|
||||||
ScrollPane {:content [Label {:id "label"
|
|
||||||
:text "This rocks."}]}]}])
|
|
||||||
|
|
||||||
(def example-graph3
|
|
||||||
[VBox {:id "topBox"
|
|
||||||
:children [Button {:id "button"
|
|
||||||
:text "Close"}]}])
|
|
||||||
|
|
||||||
(def scene-graph (atom nil))
|
|
||||||
|
|
||||||
(facts "Vector compilation"
|
|
||||||
(fact "Simple element"
|
|
||||||
(type (compile [Label {:text "Hello ClojureFX"}])) => javafx.scene.control.Label)
|
|
||||||
(fact "Simple precompiled element"
|
|
||||||
(type (compile [(new Label "Hello Precompiled")])) => javafx.scene.control.Label)
|
|
||||||
(fact "Nested structure"
|
|
||||||
(type (reset! scene-graph (compile example-graph))) => javafx.scene.layout.VBox
|
|
||||||
(get-id @scene-graph) => "topBox")
|
|
||||||
(fact "Partially precompiled nested structure"
|
|
||||||
(type (reset! scene-graph (compile example-graph2))) => javafx.scene.layout.VBox)
|
|
||||||
(fact "Nested structure where FXParent only has one child"
|
|
||||||
(type (reset! scene-graph (compile example-graph3))) => javafx.scene.layout.VBox))
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import java.net.*?>
|
|
||||||
<?import javafx.geometry.*?>
|
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
|
||||||
<?import javafx.scene.text.*?>
|
|
||||||
<?language clojure?>
|
|
||||||
|
|
||||||
<VBox xmlns:fx="http://javafx.com/fxml" alignment="center" fx:id="topBox">
|
|
||||||
<Button fx:id="button" text="Close"/>
|
|
||||||
<ScrollPane>
|
|
||||||
<Label fx:id="label" text="This rocks."/>
|
|
||||||
</ScrollPane>
|
|
||||||
</VBox>
|
|
Loading…
Reference in a new issue