Search code examples
clojureseesaw

How to use sliders in clojure seesaw


I'm new to clojure (and even newer to seesaw) but have a lot of Java experience and a fair amount of swing experience.

I'm trying to create a window with some drop-down text boxes and a slider on it. However, I'm having trouble getting all the pieces to be displayed on one window (rather than one at a time) and for some reason the slider isn't being displayed.

I cannot really find a lot of tutorials on this, so maybe I'm missing something obvious.

Here's what I'm trying to do...

    (defn window [cuisine-input rating-input location-slider]
        (seesaw/frame
        :title "Resturant Selector"
        :content (cuisine-input rating-input location-slider)
        :width 200
        :height 50
        :on-close :exit))


    (defn -main
    [& args]

        (def cuisine (seesaw/input "Please choose a type of cuisine: "
                           :choices ["Indian" "Japanese" "Chinese"
                                     "Burgers"]))

        (def rating (seesaw/input "Please choose the ideal rating: "
                        :choices ["1 star" "2 stars" "3 stars" "4 stars" 
                                  "5 stars"]))
        (def location (seesaw/slider 
                             :value 5 :min 0 :max 20 
                             :minor-tick-spacing 1 :major-tick-spacing 2 
                             :snap-to-ticks? true 
                             :paint-ticks? true :paint-labels? true))

        (def main-window (window cuisine rating location))
        (seesaw/pack! (window main-window))
        (seesaw/show! (window main-window))

)

I've also tried something like this:

    (seesaw/frame :title "Resturant Selector" :on-close :exit
            :content (:items [ 
                     (seesaw/input "Please choose a type of cuisine: "
                           :choices ["Indian" "Japanese" "Chinese"
                                    "Burgers"])

                     (seesaw/input "Please choose the ideal rating: "
                        :choices ["1 star" "2 stars" "3 stars" "4 stars" 
                                  "5 stars"])

                     (seesaw/slider
                       :value 5 :min 0 :max 20
                       :minor-tick-spacing 1 :major-tick-spacing 2
                       :snap-to-ticks? true
                       :paint-ticks? true :paint-labels? true)]
                              )
            )

Solution

  • seesaw/input creates an input dialog, while you want to create a JComboBox. The wiki has a nice help about how to create widgets and you can find a list of available widgets in the API doc.

    To have more than one widget in a frame you need a container.

    So for your particular example, you will need something similar to:

    (defn window [content]
      (seesaw/frame
        :title "Resturant Selector"
        :content content
        :width 200
        :height 50
        :on-close :close))
    
    (defn -main
      [& args]
      (let [rating-label (seesaw/label :text "Please choose rating:")
            rating (seesaw/combobox :model ["1 star" "2 star"])
            location (seesaw/slider
                       :value 5 :min 0 :max 20
                       :minor-tick-spacing 1 :major-tick-spacing 2
                       :snap-to-ticks? true
                       :paint-ticks? true :paint-labels? true)
    
            main-window (window (seesaw/vertical-panel :items [rating-label rating location]))]
        (seesaw/invoke-later
          (seesaw/pack! main-window)
          (seesaw/show! main-window))))