seesaw
Seesaw turns the Horror of Swing into a friendly, well-documented, Clojure library
seesaw-clj - Google Groups
I've been using seesaw.tree/simple-tree-model to create my TreeModels, the docs say that this is read only. Originally I didn't need to edit the tree structure however now I do!
There is a pull request in seesaw for adding update-tree!
. Though this is 8 months old.
What is the best way to create and edit JTrees with seesaw / clojure?
Source: (StackOverflow)
here's what i'd like to do:
I've got a ref that represents a list of items. I'd like to have a listbox (seesaw?) that displays this lists contents, updating automatically (whenever i change the ref).
Source: (StackOverflow)
I want a simple timeline component (like in video editing software) for a clojure/seesaw app and I am wondering if it is a good approach to implement this directly with clojure and seesaw or if I should write it in java and make my clojure wrapper around it.
Or more generally: is a functional programming language optimal for writing UI widgets? I cannot imagine doing that without a lot of state involved. And wasn't OO invented for UI-development in the first place?
Source: (StackOverflow)
This is a noob question, so I'm sorry if I offend somebody.
But how do I install seesaw on a *nix computer?
Yes, I've read the README.MD file, but how does the project.clj know where to find the library jars (for seesaw for example)?
Source: (StackOverflow)
I'm using seesaw to program an interface in Swing.
I want to display a bulleted list of items. When an item is clicked I want an event handler to be called.
I have managed to get event handlers working for components/widgets, and I can display a bulleted list easily by inserting HTML into a Label. I figure that if nothing else is possible I may need to capture mouse click events for the parent and work out offsets.
What's the best way to have a clickable bulleted list with event handlers?
Source: (StackOverflow)
I want to set a custom image for the panel background in my clojure app. Using seesaw I can set some color for the background:
(defn make-panel []
(border-panel
:north (flow-panel :align :center
:items [(label :text "TEXT")])
:center (canvas :class :board
:background :black)
:border 5))
but how to choose an image using its url?
Source: (StackOverflow)
I have a list of files like so ("File1" "File2" "File3")
I want to turn this into a of radio-menu-items
like this
(menu :text "Lists" :items [(radio-menu-item :text "File 1")(radio-menu-item :text "File 2")(radio-menu-item :text "File 3")])
I have tried looping like this
(def Radios (for [ item '("File1" "File2" "File3")] (radio-menu-item :text item)))
but this does not work.
How can this be accomplished?
Source: (StackOverflow)
I'm building a program that's meant to allow users count either the number of letters or number of words in a string, however when running the program through the cmd, I'm getting a clojure.lang.ArityException, wrong number of args (1) passed to : core/-main/counter--5333
My code is
;;Create a GUI which allows user to input a string and to select "word count" or "letter count". When "Start" is clicked pass both the string and either (wordCount [string x]) or (letterCount [string x]) to
;;declare functions as variables
;;show function that takes functions as parameters
;;show function that returns another function
(ns firstclass.core
(:gen-class)
(:use seesaw.core))
(defn -main
[& args]
(def strInput (input "Please enter a string to be evaluated"))
(def groups (button-group))
(def s (selection groups))
(def letterRadio (radio :text "Letter" :group groups))
(def wordRadio (radio :text "Word" :group groups))
(defn letterCount
[string]
(loop [characters string
a-count 0]
(if (= (first characters) \a)
(recur (rest characters) (inc a-count))
a-count)))
(defn wordCount
[string]
(loop [characters string
a-count 0]
(if (= (first characters) \a)
(recur (rest characters) (inc a-count))
a-count)))
(def counter (fn [fn x, string strInput] (x [strInput])))
(defn handler [event]
(if-let [s letterRadio]
(counter [letterCount, strInput]))
(if-let [s wordRadio]
(counter [wordCount, strInput])))
(def start (button :text "Start Count" :listen [:action handler] ))
(def panel
(flow-panel :items [strInput, letterRadio, wordRadio, start]))
(invoke-later
(-> (frame :content panel :on-close :dispose)
pack! show!)))
Source: (StackOverflow)
I am working on a simple clojure minesweeper game, mainly to exercise the language a bit. The "core game engine" is ready and now I'd like to add a simple UI. I had a look into seesaw and so far it worked quite nicely.
The only thing I am struggling with is the mig layout which I'd like to use. My idea is to have kind of the following layout:
_______________________
[_________NORTH_________]
[ ][ ][ ]
[ W ][ FIXED ][ E ]
[ E ][ SIZE ][ A ]
[ S ][ BOARD ][ S ]
[ T ][ ][ T ]
[___][_____________][___]
[_________SOUTH_________]
The north, west, east and south should grow in case the window is resized. The main panel should have a fixed size with all the buttons that represent the game board.
Before I read about mig layout I considered using a border-panel containing a grid-panel but as mentioned on the seesaw github page:
Seesaw has rudimentary support for GridBagLayout in the seesaw.core/form-panel function. I don't recommend using this because it's half-baked and not as powerful as using MigLayout (seesaw.mig) or JGoodies (seesaw.forms).
I'd like to give MigLayout a try. My first try:
(defn make-border-panel
[]
(mig-panel
:constraints ["fill" "[grow][][grow]" "[grow][][grow]"]
:items [
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["X" "shrink 0" ]
["Minesweeper North" "dock north"]
["W" "dock west" ]
["E" "dock east" ]
["Minesweeper South" "dock south"]
]))
UPDATE 1
I'll ignore north, south, west, east for the moment and did the following to get at least the center board:
(defn make-button [x y]
(button :id (format "cell_%d_%d" x y)
:icon (clojure.java.io/resource "minesweeper/icons/button.png")))
(defn make-board
[w h]
(mig-panel
:constraints [(str "wrap" w) "[]" "[]" ]
:items (for [x (range w) y (range h)]
(vector (make-button x y) "w 24px!, h 24px!"))))
Source: (StackOverflow)
this program opens a file read it into a list
then asks the user to enter the word from the list one at a time
but I get an error right after it speaks
(ns EKS.Core)
(use '[speech-synthesis.say :as say])
(use '[clojure.java.shell :only [sh]])
(use 'seesaw.core)
(use 'seesaw.dev)
(use 'seesaw.chooser)
(use 'clojure.java.io)
(import 'java.io.File)
(native!)
(defn festival [x](sh "sh" "-c" (str "echo " x " | festival --tts")))
(defn espeak [x] (sh "espeak" x))
(defn mac-say[x] (sh "say" x))
(defn check-if-installed[x] (:exit(sh "sh" "-c" (str "command -v " x " >/dev/null 2>&1 || { echo >&2 \"\"; exit 1; }"))))
(defn env
"Returns the system property for user.<key>"
[key]
(System/getProperty (str "user." key)))
(defn get-lines [fname]
(with-open [r (reader fname)]
(doall (line-seq r))))
(defn engine-check[]
(def engines (conj["Google" ]
(if (= (check-if-installed "festival") 0) "Festival" )
(if (= (check-if-installed "espeak") 0) "ESpeak" )
(if (= (check-if-installed "say") 0) "Say" )))(remove nil? engines))
(engine-check)
(def ListDir (str (env "home") ))
(def speak say)
(defn setup-list[ file](
(def ListEntry (remove #{""} (get-lines (.getAbsolutePath file))))
(speak (str "Enter the word " (first ListEntry)))
(.getAbsolutePath file)
(def current 0)))
(def Open-Action (action :handler (fn [e] (choose-file :type :open :selection-mode :files-only :dir ListDir :success-fn (fn [fc file](setup-list file))))
:name "Open"
:key "menu O"
:tip "Open list"))
(def entry-text(text :id :entry :text "" ))
(defn check-word[] ((if (= (text entry-text) (nth ListEntry current))(speak "correct")(speak "incorrect"))(def current (+ current 1))(speak (str "Enter the word " (nth ListEntry current)))))
(def Main-Panel(grid-panel :vgap 7 :hgap 20 :border "Main" :items[ (top-bottom-split entry-text
(left-right-split (grid-panel :vgap 7 :items[(label :text "Correct: 0") (label :text "Incorrect: 0")]) (grid-panel :vgap 7 :items[(button :text "Next"
:mnemonic \N
:listen [:action (fn [e] (check-word))])
(button :text "Repeat!"
:mnemonic \\
:listen [:action (fn[e] (speak(nth ListEntry current)))])
]) :divider-location 1/3 )
:divider-location 1/3 )]))
(def Main-Window(frame :title "??????", :on-close :exit, :size[425 :by 172]:menubar(menubar :items[(menu :text "File" :items [Open-Action ])]) :content Main-Panel ))
(show! Main-Window)
this is the error message I get when opening a file
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn
at clojure.lang.Var.fn(Var.java:378)
at clojure.lang.Var.invoke(Var.java:409)
at EKS.Core$setup_list.invoke(NO_SOURCE_FILE:38)
at EKS.Core$fn__5794$fn__5795.invoke(NO_SOURCE_FILE:42)
at seesaw.chooser$choose_file.doInvoke(chooser.clj:173)
at clojure.lang.RestFn.invoke(RestFn.java:619)
at EKS.Core$fn__5794.invoke(NO_SOURCE_FILE:42)
at seesaw.action$action$fn__1218.invoke(action.clj:90)
at seesaw.action.proxy$javax.swing.AbstractAction$0.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:713)
at java.awt.EventQueue.access$000(EventQueue.java:104)
at java.awt.EventQueue$3.run(EventQueue.java:672)
at java.awt.EventQueue$3.run(EventQueue.java:670)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:686)
at java.awt.EventQueue$4.run(EventQueue.java:684)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:683)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
this is the test file I am using
this
here
word
Source: (StackOverflow)
I am aware of
(frame
:title "Example"
:on-close :exit)
but what I am supposed to do if I want to do some custom action after selecting Quit in the menu?
(fn [e] (System/exit 0) )
didn't work.
Edit 1
Oops, (fn [e] (System/exit 0) ) works, provided you do
:listen [:action ...
instead of :listen [:mouse-clicked..
Sorry for not noticing that before.
Source: (StackOverflow)
I am using Seesaw to interact with Swing.
I have some icons defined thus:
(def label :icon
(clojure.java.io/resource "some_image.png"))
I want to render "some_image.png" in a different resolution. If I simply set the bounds, I'll only get part of the image.
How do I achieve this?
Source: (StackOverflow)
I'm working on a GUI app in Clojure using Seesaw and am having trouble getting a listbox (JList in Java) to update when my custom ListModel gets updated.
Here's some of my code:
(deftype ActionHistoryListModel
[^{:unsynchronized-mutable true} listeners
^{:unsynchronized-mutable true} listening-to]
ListModel
(addListDataListener [this listener]
(set! listeners (conj listeners listener)))
(removeListDataListener [this listener]
(set! listeners (remove #(= % listener) listeners)))
(getSize [this]
(get-in (deref listening-to) [:count]))
(getElementAt [this index]
(get-in (deref listening-to) [:actions index]))
ActionHistoryListModelProtocol
(listen-to [this r]
(do
(set! listening-to r)
(add-watch r this (fn [_ _ _ new-state] (.notify this new-state)))))
(notify [this new-state]
(let [action ((meta new-state) :last-action)
const (cond
(= action :create) INTERVAL_ADDED
(= action :update) CONTENTS_CHANGED)
index (last ((meta new-state) :action-target))
event (ListDataEvent. this const index index)
notification (cond
(= action :create) #(.intervalAdded % event)
(= action :update) #(.contentsChanged % event))
]
(. (.. System out) print (str "Index: " index "\n" "Event: " event "\n"))
(map #(invoke-later (notification %)) listeners)))
)
(defn make-action-history-list-model []
(ActionHistoryListModel. #{} nil))
(def ahlm (make-action-history-list-model))
(.listen-to ahlm action-history)
(def undo-list (listbox :model ahlm))
; then put list in frame...
where action-history
is a ref
.
It goes to the point where the list should be updated because the System.out.print
is happening, but the listbox doesn't want to update
Any ideas on what might be going wrong? Is it something with the mix of using the EDT and watch callback?
Let me know if more code is needed.
Source: (StackOverflow)
I have a seesaw ui with a text editor. The editor content is backed by a record called 'Task' which is contained somewhere in an atom called 'state'. A key-released event on the editor should change the property :desc of the Task. I use the following code:
(def state
(atom {:tasks []
:interval nil
:style (style :foreground :black :background nil)}))
(defn on-text-edited [ui listener-fn]
(let [editor (select ui [:#editor])]
(listen editor :key-released
(fn [evt] (listener-fn (text editor))))))
(defn update-task! [task text]
(let [newtask (assoc task :desc text)
tasks (replace {task newtask} (:tasks @state))]
(swap! state
#(assoc % :tasks tasks))))
(def text-updates (on-text-edited frame #(update-task! selected-task %)))
selected-task is an atom referencing the current content model of the editor. Whenever the user edits text the update-task! function is supposed to be called. But nothing happens. The function seems not to be called at all. When I call it from the repl it behaves as expected.
I tested if the function would get called by letting it do a simple println:
(defn update-task! [task text]
(println (str task " " text)))
Now the function works fine when I edit text in the editor. Then I changed it to:
(defn update-task! [task text]
(let [newtask (assoc task :desc text)
tasks (replace {task newtask} (:tasks @state))]
(println (str task " " text))))
now again, it would do nothing at all. So it seems that somehow the accessing of the atoms get in the way of the event handling. Is there maybe a conflict between the ui thread and the thread the atoms were defined in?
Source: (StackOverflow)
I'm making a GUI for selecting regions to crop from images. I have been using Seesaw and cans select rectangular regions, but cannot find a way to set an image to the background of seesaw.canvas. This suggests using icons on labels. Can I make a label paintable and then use it as a canvas? Is there a way to overlap a label and a canvas or somehow use a panel that gives a background to its contents?
I think Quil has this functionality, but I'm not sure how to build a GUI around its draw, setup, sketch form if I want add widgets.
Existing solutions would appreciated as well, as long as I can decompose them. Using GIMP or Photoshop isn't an option for the workflow I want: multiple crops per photo, of different kinds on each page and different metadata added depending on the type of image outlined. Any suggestions for libraries for working with metadata for photos? I was planning on using a shell interface to exiftool, but a more portable option may be better.
Source: (StackOverflow)