Permalink
Browse files

Merge branch 'release/1.4.1'

  • Loading branch information...
2 parents cf6c1ab + 5c905aa commit cf232ac3ce9cf76690d63283a6535d9dd9ba64a0 @daveray committed Apr 29, 2012
View
@@ -6,6 +6,8 @@ There's now a [Google Group] (https://groups.google.com/group/seesaw-clj) for di
[Here's a brief tutorial] (https://gist.github.com/1441520) that covers some Seesaw basics. It assumes no knowledge of Swing or Java.
+[Here's the slides] (http://darevay.com/talks/clojurewest2012/) from a Clojure/West 2012 talk on the Seesaw. Best viewed in Chrome or Safari.
+
# Seesaw: Clojure + UI
_*See [the Seesaw Wiki] (https://github.com/daveray/seesaw/wiki) and [the Seesaw API Docs] (http://daveray.github.com/seesaw/) for more detailed docs. Note that the docs in the code (use the `doc` function!) are always the most up-to-date and trustworthy.*_
@@ -55,8 +57,8 @@ Now edit the generated `src/hello_seesaw/core.clj` file:
(:use seesaw.core))
(defn -main [& args]
- (invoke-later
- (-> (frame :title "Hello",
+ (invoke-later
+ (-> (frame :title "Hello",
:content "Hello, Seesaw",
:on-close :exit)
pack!
Submodule autodoc updated from fd8b81 to a6d21e
View
@@ -1,5 +1,5 @@
# Seesaw Examples
-These are Seesaw example projects. They're here because they have external dependencies that I don't want in the main Seesaw project.
+These are Seesaw example projects. They're here because they have external dependencies that I don't want in the main Seesaw project.
The main body of Seesaw examples can be found in `../test/seesaw/test/examples`.
@@ -9,6 +9,6 @@ Example Seesaw application. Display weather data from weatherunderground.com
## License
-Copyright (C) 2010 FIXME
+Copyright (C) 2012 Dave Ray
Distributed under the Eclipse Public License, the same as Clojure.
@@ -0,0 +1,16 @@
+# substance
+
+This is an example of how to use Substance look and feels with Seesaw. There's really nothing to it, but since it's a little Java-y, it's nice to have a working example in Clojure.
+
+Run the example, or see src/substance/core.clj for details.
+
+## Usage
+
+ $ lein deps
+ $ lein run
+
+## License
+
+Copyright (C) 2012 Dave Ray
+
+Distributed under the Eclipse Public License, the same as Clojure.
@@ -0,0 +1,7 @@
+(defproject substance "1.0.0-SNAPSHOT"
+ :description "Example of using Substance Look and Feel with Seesaw"
+ :dependencies [[org.clojure/clojure "1.3.0"]
+ [seesaw "1.4.0"]
+ [com.github.insubstantial/substance "7.1"]]
+ :main substance.core)
+
@@ -0,0 +1,73 @@
+; Copyright (c) Dave Ray, 2012. All rights reserved.
+
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this
+; distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns substance.core
+ (:use [seesaw.core])
+ (:import org.pushingpixels.substance.api.SubstanceLookAndFeel)
+ (:gen-class))
+
+(defn laf-selector []
+ (horizontal-panel
+ :items ["Substance skin: "
+ (combobox
+ :model (vals (SubstanceLookAndFeel/getAllSkins))
+ :renderer (fn [this {:keys [value]}]
+ (text! this (.getClassName value)))
+ :listen [:selection (fn [e]
+ ; Invoke later because CB doens't like changing L&F while
+ ; it's doing stuff.
+ (invoke-later
+ (-> e
+ selection
+ .getClassName
+ SubstanceLookAndFeel/setSkin)))])]))
+
+(def notes " This example shows the available Substance skins. Substance
+is a set of improved look and feels for Swing. To use it in a project,
+you'll need to add a dep to your Leiningen project:
+
+ [com.github.insubstantial/substance \"7.1\"]
+
+In this example, the full class name of the current skin is shown the
+in the combobox above. For your own apps you could either use a
+selector like this example, or, more likely, set a default initial
+skin in one of the following ways:
+
+ Start your VM with -Dswing.defaultlaf=<class-name>
+
+ Call (javax.swing.UIManager/setLookAndFeel \"<class-name>\")
+ do this *after* (seesaw.core/native!) since that sets the L&F.
+
+See http://insubstantial.github.com/insubstantial/substance/docs/getting-started.html
+for more info. There you'll also find much more info about the
+skins along with much less crappy looking demos.")
+
+(defn -main [& args]
+ (invoke-later
+ (->
+ (frame
+ :title "Seesaw Substance/Insubstantial Example"
+ :on-close :exit
+ :content (vertical-panel
+ :items [(laf-selector)
+ (text :multi-line? true :text notes :border 5)
+ :separator
+ (label :text "A Label")
+ (button :text "A Button")
+ (checkbox :text "A checkbox")
+ (combobox :model ["A combobox" "more" "items"])
+ (horizontal-panel
+ :border "Some radio buttons"
+ :items (map (partial radio :text)
+ ["First" "Second" "Third"]))
+ (scrollable (listbox :model (range 100)))]))
+ pack!
+ show!)))
+
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="test"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="lib/clojure-1.3.0.jar"/>
+ <classpathentry kind="lib" path="lib/forms-1.2.1.jar"/>
+ <classpathentry kind="lib" path="lib/j18n-1.0.0.jar"/>
+ <classpathentry kind="lib" path="lib/miglayout-3.7.4.jar"/>
+ <classpathentry kind="lib" path="lib/seesaw-1.4.0.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-action-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-autocomplete-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-common-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-core-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-painters-1.6.3.jar"/>
+ <classpathentry kind="lib" path="lib/swingx-plaf-1.6.3.jar"/>
+ <classpathentry kind="lib" path="classes"/>
+ <classpathentry kind="output" path="classes"/>
+</classpath>
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>window-builder</name>
+ <comment>FIXME: write description</comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>ccw.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>ccw.nature</nature>
+ </natures>
+</projectDescription>
@@ -0,0 +1,15 @@
+# window-builder
+
+This example project shows how you can use Google Window Builder in Eclipse to layout and form and then use that form from Clojure with Seesaw.
+
+## Usage
+
+ $ lein deps
+ $ lein compile
+ $ lein run -m window-builder.core
+
+## License
+
+Copyright (C) 2012 Dave Ray
+
+Distributed under the Eclipse Public License, the same as Clojure.
@@ -0,0 +1,5 @@
+(defproject window-builder "0.0.0-SNAPSHOT"
+ :description "Example of using Google Window Builder to create Seesaw forms"
+ :dependencies [[org.clojure/clojure "1.3.0"]
+ [seesaw "1.4.0"]]
+ :java-source-path "src")
@@ -0,0 +1,147 @@
+package window_builder;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.JComboBox;
+
+public class MyForm extends JPanel {
+ private JTextField firstName;
+ private JTextField lastName;
+ private JLabel lblStreet;
+ private JTextField textField;
+ private JLabel lblCity;
+ private JTextField textField_1;
+ private JLabel lblState;
+ private JComboBox comboBox;
+ private JLabel lblState_1;
+ private JTextField textField_2;
+
+ /**
+ * Create the panel.
+ */
+ public MyForm() {
+ GridBagLayout gridBagLayout = new GridBagLayout();
+ gridBagLayout.columnWidths = new int[]{72, 134, 0, 0, 0, 0, 0};
+ gridBagLayout.rowHeights = new int[]{28, 28, 0, 0};
+ gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
+ gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
+ setLayout(gridBagLayout);
+
+ JLabel lblFirstName = new JLabel("First Name:");
+ GridBagConstraints gbc_lblFirstName = new GridBagConstraints();
+ gbc_lblFirstName.anchor = GridBagConstraints.WEST;
+ gbc_lblFirstName.insets = new Insets(0, 0, 5, 5);
+ gbc_lblFirstName.gridx = 0;
+ gbc_lblFirstName.gridy = 0;
+ add(lblFirstName, gbc_lblFirstName);
+
+ firstName = new JTextField();
+ firstName.setName("first-name");
+ firstName.setColumns(10);
+ GridBagConstraints gbc_firstName = new GridBagConstraints();
+ gbc_firstName.gridwidth = 2;
+ gbc_firstName.anchor = GridBagConstraints.NORTH;
+ gbc_firstName.fill = GridBagConstraints.HORIZONTAL;
+ gbc_firstName.insets = new Insets(0, 0, 5, 5);
+ gbc_firstName.gridx = 1;
+ gbc_firstName.gridy = 0;
+ add(firstName, gbc_firstName);
+
+ JLabel lblLastName = new JLabel("Last Name:");
+ GridBagConstraints gbc_lblLastName = new GridBagConstraints();
+ gbc_lblLastName.anchor = GridBagConstraints.WEST;
+ gbc_lblLastName.insets = new Insets(0, 0, 5, 5);
+ gbc_lblLastName.gridx = 3;
+ gbc_lblLastName.gridy = 0;
+ add(lblLastName, gbc_lblLastName);
+
+ lastName = new JTextField();
+ lastName.setName("last-name");
+ lastName.setColumns(10);
+ GridBagConstraints gbc_lastName = new GridBagConstraints();
+ gbc_lastName.gridwidth = 2;
+ gbc_lastName.fill = GridBagConstraints.HORIZONTAL;
+ gbc_lastName.insets = new Insets(0, 0, 5, 0);
+ gbc_lastName.anchor = GridBagConstraints.NORTH;
+ gbc_lastName.gridx = 4;
+ gbc_lastName.gridy = 0;
+ add(lastName, gbc_lastName);
+
+ lblStreet = new JLabel("Street:");
+ GridBagConstraints gbc_lblStreet = new GridBagConstraints();
+ gbc_lblStreet.anchor = GridBagConstraints.EAST;
+ gbc_lblStreet.insets = new Insets(0, 0, 5, 5);
+ gbc_lblStreet.gridx = 0;
+ gbc_lblStreet.gridy = 1;
+ add(lblStreet, gbc_lblStreet);
+
+ textField = new JTextField();
+ textField.setName("street");
+ GridBagConstraints gbc_textField = new GridBagConstraints();
+ gbc_textField.gridwidth = 5;
+ gbc_textField.insets = new Insets(0, 0, 5, 0);
+ gbc_textField.fill = GridBagConstraints.HORIZONTAL;
+ gbc_textField.gridx = 1;
+ gbc_textField.gridy = 1;
+ add(textField, gbc_textField);
+ textField.setColumns(10);
+
+ lblCity = new JLabel("City:");
+ GridBagConstraints gbc_lblCity = new GridBagConstraints();
+ gbc_lblCity.anchor = GridBagConstraints.EAST;
+ gbc_lblCity.insets = new Insets(0, 0, 0, 5);
+ gbc_lblCity.gridx = 0;
+ gbc_lblCity.gridy = 2;
+ add(lblCity, gbc_lblCity);
+
+ textField_1 = new JTextField();
+ textField_1.setName("city");
+ GridBagConstraints gbc_textField_1 = new GridBagConstraints();
+ gbc_textField_1.insets = new Insets(0, 0, 0, 5);
+ gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
+ gbc_textField_1.gridx = 1;
+ gbc_textField_1.gridy = 2;
+ add(textField_1, gbc_textField_1);
+ textField_1.setColumns(10);
+
+ lblState_1 = new JLabel("State:");
+ GridBagConstraints gbc_lblState_1 = new GridBagConstraints();
+ gbc_lblState_1.insets = new Insets(0, 0, 0, 5);
+ gbc_lblState_1.gridx = 2;
+ gbc_lblState_1.gridy = 2;
+ add(lblState_1, gbc_lblState_1);
+
+ comboBox = new JComboBox();
+ comboBox.setName("state");
+ GridBagConstraints gbc_comboBox = new GridBagConstraints();
+ gbc_comboBox.insets = new Insets(0, 0, 0, 5);
+ gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
+ gbc_comboBox.gridx = 3;
+ gbc_comboBox.gridy = 2;
+ add(comboBox, gbc_comboBox);
+
+ lblState = new JLabel("Zip:");
+ GridBagConstraints gbc_lblState = new GridBagConstraints();
+ gbc_lblState.anchor = GridBagConstraints.EAST;
+ gbc_lblState.insets = new Insets(0, 0, 0, 5);
+ gbc_lblState.gridx = 4;
+ gbc_lblState.gridy = 2;
+ add(lblState, gbc_lblState);
+
+ textField_2 = new JTextField();
+ textField_2.setName("zip");
+ GridBagConstraints gbc_textField_2 = new GridBagConstraints();
+ gbc_textField_2.fill = GridBagConstraints.HORIZONTAL;
+ gbc_textField_2.gridx = 5;
+ gbc_textField_2.gridy = 2;
+ add(textField_2, gbc_textField_2);
+ textField_2.setColumns(10);
+
+ }
+}
@@ -0,0 +1,46 @@
+(ns window-builder.core
+ (:use [seesaw.core])
+ (:require [seesaw.selector :as selector]))
+
+; This is the interesting part. Note that in MyPanel.java, the widgets we're
+; interested in have their name set with setName().
+(defn identify
+ "Given a root widget, find all the named widgets and set their Seesaw :id
+ so they can play nicely with select and everything."
+ [root]
+ (doseq [w (select root [:*])]
+ (if-let [n (.getName w)]
+ (selector/id-of! w (keyword n))))
+ root)
+
+(def states ["CA", "GA", "WA"])
+
+(def defaults
+ { :first-name "Laura"
+ :last-name "Palmer"
+ :street "123 Main St."
+ :city "Twin Peaks"
+ :zip "12345"
+ :state "WA" })
+
+; A helper to create an instance of the form, annotate it for Seesaw and do
+; some other initialization.
+(defn my-form
+ []
+ (let [form (identify (window_builder.MyForm.))]
+ ; initialize the state combobox
+ (config! (select form [:#state]) :model states)
+ form))
+
+; Now we just create the panel, initialize it to the defaults above with
+; seesaw.core/value! and show it in a dialog. Note how, besides setting the
+; names of the widgets, the code in MyForm.java is strictly for layout. All
+; behavior, etc is done in Clojure.
+(defn -main [& args]
+ (invoke-later
+ (let [form (value! (my-form) defaults)
+ result (-> (dialog :content form :option-type :ok-cancel) pack! show!)]
+ (if (= :success result)
+ (println "User entered: " (value form))
+ (println "User canceled")))))
+
Oops, something went wrong. Retry.

0 comments on commit cf232ac

Please sign in to comment.