Fork me on GitHub
#beginners
<
2024-06-02
>
Melody07:06:02

Could anyone assist me with what I am sure is a very basic part of using seesaw to make guis? All I want to do is center my text.... I have tried many permutations of different containers and different functions and adjusting attributes of components, but nothing seems to be justifying the content center. I can get a border-panel to place text in the top-middle-or botom of the page, but not align it in the middle justified. This is the only file the code.

(ns class-reg-seesaw.core
  (:use seesaw.core)
  (:use seesaw.dev)
  (:require [ :as _io]
            [seesaw.font :as _f]))

(defn make-content []
  (border-panel
   :north (label :text "Class-Reg" :font (_f/font :size 24) :h-text-position :center)
   :center "Login Here"))

(defn main-frame []
  (let [frame (frame
               :id :m-frame
               :title "Class-Reg-Clj"
               :content (make-content)
               :minimum-size [600 :by 800]
               :on-close :exit)
        background-image (label :icon (_io/resource "field.jpg"))]
   frame))

(defn -main [& args]
  (invoke-later
   (-> (main-frame)
       pack!
       show!)))
I feel like I must definitely be overlooking something here...

Melody07:06:45

I have been using the code around line 111 here as a reference https://github.com/clj-commons/seesaw/blob/master/examples/gaidica/src/gaidica/core.clj as well as this code https://github.com/vascoferreira25/seesaw-gui-application/blob/master/src/seesaw_gui_application/core.clj and also the core seesaw docs here http://clj-commons.org/seesaw/ but none of it has helped much. I know I shouldn't get caught up in formatting before I even have anything working but I can't help it...

daveliepmann08:06:33

:center "Login Here"
have you tried wrapping the string here with a widget?

mrnhrd08:06:13

I'm also newish to clj and seesaw, but maybe this is of help? https://docs.oracle.com/javase%2Ftutorial%2F/uiswing/components/label.html I'm also confused by the code, you want to display both the text "Class Reg" and "Login here"? I'm confused as to how they should position to each other. Perhaps post a screenshot of what it looks like and what you want it to look like. e: oh, I understand, in the border-panel one label is supposed at the top and one in the middle (no clue what "middle" means when there's only two elements). Well, as dave said both texts will need to be written as (labels as you have to override their h-text properties.

Melody14:06:55

@U05092LD5Since I am learning, this last iteration I shared had "Login here" outside of a widget because I wanted to see if it could print without one in this case. It does print, but with no formatting. With a widget around it such as a label, it will print but still I struggle to format it. Additionally something not shown here is actually that I was initially trying to do 3 lines of text, basically a title in large font "Class-Reg" with a 'subtitle' underneath it just like "Welcome to the app", and then the "Login here" in the center panel below (because I wanted to see if I could use a vertical panel inside of a border-panel. The code looks like the following (in my mind) lol -> but this does not compile and gives me lots of errors

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: class seesaw.core.proxy$javax.swing.JPanel$Tag$fd407141 does not support the seesaw.core.proxy$javax.swing.JLabel$Tag$fd407141[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=8388608,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=CENTER,iconTextGap=4,labelFor=,text=Class-Reg,verticalAlignment=CENTER,verticalTextPosition=CENTER] option
(defn make-content []
  (border-panel
   :north (vertical-panel
           (label :text "Class-Reg" :font (_f/font :size 24) :h-text-position :center)
           (label :text "Welcome to the app" :font (_f/font :size 18) :h-text-position :center))
   :center (label "Login Here")))
@U05N15QDUHX I actually did end up going to the java docs myself, and this is helpful what you shared I think; but unfortunately it is somewhat hard for me to parse. I know seesaw is developed specifically so you can "drop down to interop" when you want to do something less straight-forward, but I actually have little-to-no experience with java (although I know c# well enough), and it is a bit hard for me to parse the java in combination with seesaw which I also don't really have familiarity with.

Jason Bullers14:06:21

Try wrapping the label in the north section in a flow panel

👍 1
Jason Bullers15:06:26

With :align :centre

Jason Bullers15:06:10

Centering the text of the label will centre the text within the label itself, but you also need to centre the label "widget" within the space

Jason Bullers15:06:18

When you're fiddling with layouts, it's sometimes handy to set the background color of a GUI component to a glaring color so you can easily see where things are and what their bounds are

Melody15:06:48

I don't know if I am formatting it correctly, it is returning an error saying that the opts 'must be an even number'

(defn make-content []
  (flow-panel
   :items (vertical-panel
           :items (label :text "Class-Reg" :font (_f/font :size 24) :h-text-position :center)
           (label :text "Welcome to the app" :font (_f/font :size 18) :h-text-position :center)
           (label "Login Here" :h-text-position :center))
   :align :centre))
(I also tried :align :center) Your suggestion of using background colors is great, but I actually haven't been able to XD I have tried making background colors a lot to no avail

Melody15:06:23

(ns class-reg-seesaw.core
  (:use seesaw.core)
  (:use seesaw.dev)
  (:require [ :as _io]
            [seesaw.font :as _f]))

(def make-content
  (flow-panel
   :items (vertical-panel
           (label :text "Class-Reg" 
                  :font (_f/font :size 24)
                  :h-text-position :center)
           (label :text "Welcome to the app" 
                  :font (_f/font :size 18) 
                  :h-text-position :center)
           (label "Login Here" 
                  :h-text-position :center))
   (:align :centre)))

(defn main-frame []
  (let [frame (frame
               :id :m-frame
               :title "U Class-Reg-Clj"
               :content (make-content)          *LINE24
               :minimum-size [600 :by 800]
               :on-close :exit)
        background-image (label :icon (_io/resource "field.jpg"))]
   ;(config! :m-frame :position )
   frame))

(defn -main [& args]
  (invoke-later
   (-> (main-frame)
       pack!
       show!)))
The compilation error is suggesting it is happening at line 24 and I cannot figure out why. Maybe the make-content is allowed, but I am actually messing it up in the function I pass it to somehow where I use the frame.
Execution error (IllegalArgumentException) at seesaw.util/check-args (util.clj:24).
opts must be a map or have an even number of entries
I tried to put :content (label (make-content)) to see if the flow-panel needed to be wrapped in something, but it produces the same error
(def flow-panel-options default-options)

(defn flow-panel
  "Create a panel with a flow layout. Options:

    :items  List of widgets (passed through make-widget)
    :hgap   horizontal gap between widgets
    :vgap   vertical gap between widgets
    :align  :left, :right, :leading, :trailing, :center
    :align-on-baseline?

  See 
  "
  [& opts]
  (abstract-panel (FlowLayout.) opts))
This is an example from their docs, which I feel like I understand, but I must not since I can't get this to work proper.

daveliepmann15:06:26

The "opts must...have an even number of entries" could be this guy (label "Login Here" :h-text-position :center) which mixes the (label "foo") form with the (label :text "foo" :bar "baz") form

Melody15:06:25

That definitely could be contributing... I fixed it and it is producing the same error in this case

(def make-content
  (flow-panel
   :items (vertical-panel
           (label :text "Class-Reg" 
                  :font (_f/font :size 24)
                  :h-text-position :center)
           (label :text "Welcome to the app" 
                  :font (_f/font :size 18) 
                  :h-text-position :center)
           (label :text "Login Here" 
                  :h-text-position :center))
   (:align :centre)))

daveliepmann15:06:56

(:align :centre)
why is this in parentheses? and does seesaw accept centre as a UK synonym of center?

daveliepmann15:06:08

also I think the vertical-panel needs an :items key and the value for that key should be a single value with all three labels, I believe

Melody15:06:50

I changed it back to a defn instead of def and made the changes you suggested.

(defn make-content []
  (flow-panel
   :items (vertical-panel
           :items
           (label :text "Class-Reg"
                  :font (_f/font :size 24)
                  :h-text-position :center)
           (label :text "Welcome to the app"
                  :font (_f/font :size 18)
                  :h-text-position :center)
           (label :text "Login Here"
                  :h-text-position :center))
   :align :centre))
It does produce a different error but I don't know what it means
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Don't know how to create ISeq from: seesaw.core.proxy$javax.swing.JLabel$Tag$fd407141

daveliepmann15:06:12

OK, so when you see "Don't know how to create ISeq" you should look for places where the computer expects a sequence (like a list, vector, or seq) and it's getting something that's not sequential — in this case a seesaw Label.

daveliepmann15:06:38

I think this is because :items wants a sequence and is getting a label

daveliepmann15:06:07

this is what I meant by "the value for that key should be a single value with all three labels"

daveliepmann15:06:11

currently the value for :items is just one label, not all three, because these functions take key/value pairs for their arguments

Melody15:06:33

I definitely see what you are saying, I tried wrapping them in a vector and that produces the same result...

(defn make-content []
  (flow-panel
   :items (vertical-panel
           :items [(label :text "Class-Reg"
                          :font (_f/font :size 24)
                          :h-text-position :center)
                   (label :text "Welcome to the app"
                          :font (_f/font :size 18)
                          :h-text-position :center)
                   (label :text "Login Here"
                          :h-text-position :center)])
   :align :centre))
I also tried wrapping the vertical panel itself in a vector and that produces a separate error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: class clojure.lang.Keyword cannot be cast to class java.lang.Number (clojure.lang.Keyword is in unnamed module of loader 'app'; java.lang.Number is in module java.base of loader 'bootstrap')

daveliepmann16:06:41

those are beyond me, sorry

Melody16:06:15

That's fair, thank you very much for taking the time to try and help, hopefully I will figure it out soon. I feel like I am close to being able to just use the java to do it appropriately, but I think that would be the wrong "solution" even if I could.

👍 1
Jason Bullers16:06:21

That's all I can see there: the call to vertical panel needs to be all in a vector

Jason Bullers16:06:55

:items [(vertical-panel ...)]

Melody16:06:15

(defn make-content []
  (flow-panel
   :items [(vertical-panel
            :items [(label :text "Class-Reg"
                           :font (_f/font :size 24)
                           :h-text-position :center)
                    (label :text "Welcome to the app"
                           :font (_f/font :size 18)
                           :h-text-position :center)
                    (label :text "Login Here"
                           :h-text-position :center)])]
   :align :centre))
Yes that is what produces this one error
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: class clojure.lang.Keyword cannot be cast to class java.lang.Number (clojure.lang.Keyword is in unnamed module of loader 'app'; java.lang.Number is in module java.base of loader 'bootstrap')

Melody16:06:00

I thought so too lol. It seemed so intuitive when I was first looking at it, and I feel like maybe I have a syntax error somewhere else or am misunderstanding formatting my code another way. Like for example

(defn main-frame []
  (let [frame (frame
               :id :m-frame
               :title "U Class-Reg-Clj"
               :content (make-content)
               :minimum-size [600 :by 800]
               :on-close :exit)
        background-image (label :icon (_io/resource "field.jpg"))]
   ;(config! :m-frame :position )
   frame))
I have the frame returning here, and when I have a simpler example (like the inital one in this thread), this works and returns ^the thing is here is that I am returning the frame as a return of the function. Currently make-content doesn't return anything, but editing it to be the same way and saying (let content-panel [flow-panel....])) and returning content-panel, also does not seem to work 😞

Jason Bullers16:06:24

Not near a computer so can't check right now. I'd suggest just selectively commenting things out until it works, the reintroduce one property/form at a time

👍 2
Melody16:06:28

I had some amount of success :)

(defn make-content []
  (let [content-panel
        (flow-panel
         :items [(vertical-panel
                  :items [(label :text "Class-Reg"
                                 :font (_f/font :size 24)
                                 :h-text-position :center)
                          (label :text "Welcome to the app"
                                 :font (_f/font :size 18)
                                 :h-text-position :center)
                          (label :text "Login Here"
                                 :h-text-position :center)])]
         :align :center)]
    content-panel))
yields the following pic. Text is still left aligned, but at least I have the panel centered now and I can simplify and fix the code. Thank you for all the help everybody

👍 1
Jason Bullers17:06:07

You probably need to align the vertical panel in some way

mrnhrd20:06:51

I did play around with this a bit, fyi if you (:use seesaw.border) you can add :border (line-border :thickness 3 :color "#FF0000") to everything to see how big it is drawn. Together with :size [500 :by 500] added to the vertical panel I get this:

Melody20:06:00

I made a good chunk of progress earlier 🙂 I have a https://github.com/TheFakeLorLyons/clj-class-reg-1 if you want to see the changes I made

🙌 2
Melody20:06:31

The background colors for components is very helpful 😄

🙌 1
mrnhrd21:06:30

good luck then; getting vertical-panel to align stuff centrally looks non-trivial (i.e. require interop)

clojure-spin 1
wilcov14:06:20

Hi all, i puchased 'The joy of clojure, 2nd edition' almost 10 years ago. Life happened and i never got round to learning clojure but i want to give it a second try. The book targets clojure 1.6. I just wanted to know if it's still valid with 1.11.3 and is it a good first book for a clojure beginner?

Bob B14:06:25

it's generally still applicable, and I think it's a good first book... depending on your experience and how you take it in, it might be beneficial to spend extra time in chapter 2 (the "fire hose" chapter).

dpsutton14:06:43

Where did you get the version 1.13.3 though?

wilcov14:06:31

@U013JFLRFS8 Thank you! i'll spend some extra with with the second chapter

wilcov14:06:53

@U11BV7MTK i checked the releases page of the clojure website https://clojure.org/releases/downloads 1.13.3 is the latest stable release right?

wilcov14:06:13

Whoops, my bad. It's 1.11.3

Jason Bullers14:06:02

Personally, I found it exciting at first, but quickly got overwhelmed. It was my first book on Clojure and I hadn't really worked with a lisp before or done much in the way of fp beyond simple data pipelines with map, filter, and reduce. If you get lost like I did, look for some other sources: books, podcasts, watching experienced devs code something on YouTube, doing coding problems. Then come back to Joy and give it another go

👍 1
1
Ludger Solbach14:06:53

But learning clojure is definetly a good idea. 👍

2
wilcov15:06:00

@U04RG9F8UJZ Thank you, i'll keep that in mind 🙂

wilcov15:06:17

And yeah @U017HM6BG07 i'm planning to stick with it this time 😃

Ludger Solbach15:06:55

Go for it! 😄

jumar18:06:43

Agree with Jason. I would personally pick another - shorter and easier- book for the start Joy of Clojure is indeed a fantastic book - when you are ready for it

flowthing10:06:17

I’ve heard good things about Getting Clojure (https://pragprog.com/titles/roclojure/getting-clojure/) as a good first Clojure book.

👍 4
Vincent13:06:43

don't forget to use a REPL! 😉

1
Ludger Solbach19:06:56

> I’ve heard good things about Getting Clojure as a good first Clojure book. It's a really good book. I have a copy and bought it as a gift 3 times for friends. But I also like Programming Clojure. I think it depends a bit on experience in programming and personal preferences really.

wilcov20:06:58

Thank you guys i will check out Getting Clojure as well!

wilcov20:06:10

And oh a REPL? Is that what it's all about? 😉

3starblaze18:06:25

How do I run and echo a shell command that never returns? I tried to use shell/sh but it seems like I have to wait for the command to finish before I can use the output. Minimal example (shell/sh "watch" "date"). I'm using babashka but I'd like to know a way that also works for "normal" Clojure.

borkdude18:06:42

@U02S4QZAH61 (babashka.process/process {:inherit true} ...)

👍 1
borkdude18:06:23

This also works in normal Clojure