Skip to content
daveray edited this page Aug 3, 2011 · 31 revisions

I've set up a Google Group for Seesaw discussion and questions: https://groups.google.com/group/seesaw-clj

Also see the API docs here: http://daveray.github.com/seesaw/

Also, there are a number of blog posts on various Seesaw features here: http://blog.darevay.com/category/seesaw/

and Release Notes.

Usage

See tests and src/seesaw/examples. Seriously, there are a lot of tests and they're pretty descriptive of how things work.

Let's create a JFrame:

(show! (frame :title "Hello" :content "Hi there"))

This will create a JFrame with title "Hello" and a single label "Hi there". The :content property expects something that can be turned into a widget and uses it as the content pane of the frame. Any place where a widget is expected, one will be created depending on the argument (see Widgets). Note that by default a new frame is invisible. The show! function makes it visible. Same goes for dialogs.

There are several examples at the moment. They're all in the src/seesaw/examples and can be run with lein like this:

$ lein deps
$ lein run -m seesaw.examples.<name-of-example>

To run the tests:

$ ./autotest.sh

Hopefully you see a nice wall of green. This runs lazytest in "watch" mode. The tests will be re-run every time you modify a file. Basically all my development is like this:

  • Start the autotester and make sure everything's green
  • Write the test and watch for red or an exception
  • Write the code to make the test turn green again.
  • Refactor/cleanup, etc.

One nice thing is that if you have an example (like in src/seesaw/examples) if you call the main function there, lazytest will basically run the example over and over again. So you get a workflow like:

  • Write some of the example
  • Save
  • The window or whatever pops up automatically
  • Play with it, close it, and write some more

Of course, the examples should be tested, but they aren't :)

Topics

Here are topics covering most areas of Seesaw usage:

  • Project Setup - how to setup a project using Seesaw
  • Frames - How to create top-level frames/windows to contain your app.
  • Widgets - How to create widgets to populate your frames. Also how to integrate custom widget you create or get from 3d parties.
  • Containers - All about container widgets, i.e. UI elements that simply contain other widgets like buttons, labels, etc.
  • Selectors - Using selectors to find widgets in your app
  • Actions - Defining "actions" that can be reused throughout your app in menus, buttons, etc.
  • Handling Events - Handling widget events
  • Handling Selection - Handling the current selection in a widget
  • Dialogs - Tell the user stuff. Ask the user stuff.
  • Menus - Menu bars, context menus, etc
  • Colors, Fonts - Specifying colors and fonts
  • Borders - Put borders on widgets
  • Tables - Working with tables
  • Graphics - Drawing stuff on the screen and making custom widgets
  • Applets - How to jam Seesaw in an applet
  • Binding - Creating widget dataflows, for example hooking the value of a checkbox to the enabled state of another widget.

Native Look and Feel

Call the (native!) function early in your program (like before any other Swing or Seesaw function is called) to get a more "native" behavior. This includes correct menu bar placement in OSX, etc.

A Note on Threading

As noted [here] (http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threading) Swing is single threaded nearly all UI operations should be executed on the Swing UI dispatch thread. To facilitate this, Seesaw includes the (invoke-now) and (invoke-later) macros. The former executes forms on the UI thread and waits for their completion, while the latter simply schedules the forms for execution sometime in the future.

A typical use for (invoke-later) is to get things going in an app:

(defn -main [& args]
  (invoke-later
    (show! (frame :title "Hello" :content (button :text "Push me")))))
Clone this wiki locally