-
Notifications
You must be signed in to change notification settings - Fork 1
Forms
Clarity includes a simple way to create forms. The simplest form syntax is:
> (use 'clarity.dev)
> (use 'clarity.form)
> (show-comp (form
:first-name "John"
:surname "Truant"
:occupation ["programmer" "tattoo artist"]))...which results in the following form:

String and numeric values result in text fields being added to the form. Human-readable labels are inferred from the keywords. If you need an empty text field use "". If the value is a vector, a combo box is added to the form.
Individual fields can be customised by passing a vector after the value element which will contain keyword flags mixed with keyword/value pairs as below (currently, you can only customize the labels):
(show-comp (form
:first-name "John" [:label "Name"]
:surname "Truant"
:occupation ["programmer" "tattoo artist"]))Apart from the vectors that customize the field itself, there are other special vectors that add text to the form. The two elements are :header and :text:
> (show-comp (form
[:header "Contact Details"]
[:header "Basic Information" :level 2]
:first-name "John" [:label "Name"]
:surname "Truant" [:category :important]
[:header "Employment Information" :level 2]
[:text "Please enter **all** the employment information below" :rich]
:occupation ["programmer" "tattoo artist"]
:years-in-last-job 1))
The :level parameter of the headers affects the category assigned to the header, but has no effect to the actual look until a style is applied (see next section).
As you can see above, the [:text] vector can be used to include some text in the middle of the form. This will be rendered using a simple JLabel, except if the :rich flag is passed, in which case a clarity.component/para component is used, which supports Markdown syntax.
It is possible to create forms that contain custom components to hold the fields. For example, the above form could be written as:
> (use 'clarity.component)
> (show-comp (form
:first-name "John"
:surname "Truant"
:occupation ["programmer" "tattoo artist"]
:years-in-last-job (make :spinner (:id :years) (:value 1))))Notice that because IDs in Clarity are immutable and because the spinner has already been constructed before being passed to the form, the form function cannot set the ID of the custom component, and it is up to the programmer to set it. This may change in the future.
The constructed form uses categories heavily to allow styling. The form's JPanel is assigned the :form category, all fields are assigned the :field category, and their labels the :label category. Headers are assigned the :header category or :header-X where X is the level that was passed with the :level flag while constructing the form. Text paragraphs are assigned the :text category (styling is not ready yet, so the categories are for future use).
Each field is given an ID which is the same as the keyword passed while creating the form. This makes it possible to call clarity.component/value on the whole form and collect the values of the fields in a map that looks very similar to the original parameters.
For example, with the original form:
> (use 'clarity.component)
> (def f (form
:first-name "John"
:surname "Truant"
:occupation ["programmer" "tattoo artist"]))
> (value f)
{:first-name "John", :surname "Truant", :occupation "programmer"}Try showing the form with show-comp, changing the values and calling (value f) again.
Similarly, you can call set-value and pass a map with values for each component (or just some of them):
(set-value f {:first-name "John", :surname "Smith"})Remember that any changes to Swing components should happen in the Event Dispatch Thread of Swing, so in full programs set-value should be called via the do-swing method of clojure-contrib.swing-utils.
Forms can be embedded into dialogs to easily collect input from the user. For example:
> (use 'clarity.dialog)
> (show-dialog (form :first-name "" :surname "") [:ok :cancel])
... user enters details and presses the OK button ...
{:value {:first-name "Joe", :surname "Smith"}, :response :ok}
This results in a modal dialog showing the passed form, plus the relevant buttons are added and the thread blocks while waiting for user input. After the dialog is closed, a map is returned, with two keys, :value and :response. The value of :value is the result of calling clarity.component/value on the form and the :response key represents the button that was clicked. This can be the text of the button or its ID, depending on what was passed in the buttons parameter. If no buttons are passed, the dialog will only have an "OK" button. If the dialog is closed by clicking on the close button of the window title bar, the :response will be :closed.
The passed keywords are converted to English text according to the contents of the clarity.dialog/response-map map.