Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (2)

Pavel Tišnovský 9. 6. 2015

Ve druhé části článku o programovacím jazyce Clojure a o knihovnách dostupných pro tento jazyk se již podruhé budeme zabývat knihovnou nazvanou Seesaw, která je určena pro tvorbu grafického uživatelského rozhraní. Na několika demonstračních příkladech si ukážeme další zajímavé vlastnosti této knihovny použitelné v praxi.

Obsah

1. Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (2)

2. Tvorba formulářů s použitím mřížky (grid)

3. Zdrojový kód dnešního prvního demonstračního příkladu

4. Použití barev

5. Zdrojový kód dnešního druhého demonstračního příkladu

6. Použití fontů

7. Zdrojový kód dnešního třetího demonstračního příkladu

8. Příklad widgetu, který řídí hodnotu zvoleného atomu

9. Zdrojový kód dnešního čtvrtého demonstračního příkladu

10. Repositář s demonstračními příklady

11. Odkazy na předchozí části seriálu

12. Odkazy na Internetu

1. Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (2)

V předchozí části seriálu o programovacím jazyce Clojure i o knihovnách určených pro vývojáře vytvářející aplikace v tomto jazyku jsme se seznámili se základními informacemi o knihovně Seesaw, kterou je možné využít pro tvorbu desktopových aplikací s téměř plnohodnotným grafickým uživatelským rozhraním. Připomeňme si, že Seesaw sice interně využívá okna a widgety nabízené známou javovskou knihovnou Swing, ovšem samotné programátorské rozhraní je zcela odlišné, což vede k tomu, že práce v Clojure+Seesaw je v naprosté většině případů mnohem jednodušší, než je tomu při použití klasické kombinace Java+Swing. Dnes si popíšeme některé další vlastnosti knihovny Seesaw: použití správců rozmístění ovládacích prvků, specifikaci barev a fontů a v neposlední řadě taktéž navázání ovládacího prvku (widgetu) na zvolenou proměnnou.

2. Tvorba formulářů s použitím mřížky (grid)

To, že je knihovna Seesaw postavena na javovské knihovně Swing, nemusí být na první pohled patrné, protože tvorba oken i formulářů a použití prvků GUI (widgetů) je v mnoha ohledech řešeno jednodušeji a z pohledu programátora i přímočařeji, než je tomu ve Swingu. Ovšem v jedné dosti důležité oblasti nalezneme velkou podobnost mezi knihovnami Seesaw a Swing: jedná se o použití takzvaných správců rozvržení (layout manager). Jednotlivé widgety je totiž nutné umístit do kontejnerů (oken, formulářů, …) a aby nebylo nutné počítat a ručně přímo do programu zadávat absolutní souřadnice a rozměry jednotlivých widgetů, používají se (ve Swingu) speciálně navržené třídy, které rozmístění prvků provedou automaticky na základě rozměrů okna a dalších zadaných podmínek. Správců rozvržení existuje relativně velké množství a dokonce je jednoduché si naprogramovat vlastního správce.

V knihovně Seesaw se setkáme především s funkcí nazvanou grid-panel, která slouží k rozmístění ovládacích prvků s využitím javovské třídy GridLayout. Tento správce rozvržení nabízí základní prostředky pro umístění widgetů do pravidelné mřížky, což vyhovuje pro tvorbu jednodušších formulářů, ovšem později narazíme na mnoho omezení, která jsou vlastně dosti umělá (podobný správce rozvržení nalezneme i v Tcl/Tk, tam se ovšem jedná o mnohem vyspělejší implementaci). Podívejme se nyní na parametry, které lze funkci grid-panel předat. Všechny parametry jsou pojmenované, tj. nejprve se zadá klíčové slovo (keyword) a ihned za ním hodnota parametru:

# Parametr Význam
1 :rows počet řádků, pokud nezadáno, předpokládá se hodnota 0 (unspecified)
2 :columns počet sloupců, mělo by být zadáno vždy
3 :items seznam prvků (widgetů), které se postupně poskládají do plochy okna či jiného kontejneru
4 :hgap horizontální mezera mezi sousedními prvky
5 :vgap vertikální mezera mezi sousedními prvky

3. Zdrojový kód dnešního prvního demonstračního příkladu

Použití funkce grid-panel si ukážeme na dnešním prvním demonstračním příkladu, který je pojmenovaný seesaw5 (příklady 1 až 4 totiž byly popsány minule). Kostru tohoto příkladu vytvoříme jednoduše:

lein new app seesaw5

Po spuštění tohoto příkazu by se měla vygenerovat následující struktura adresářů a souborů:

.
├── doc
│   └── intro.md
├── LICENSE
├── project.clj
├── README.md
├── resources
├── src
│   └── seesaw5
│       └── core.clj
└── test
    └── seesaw5
        └── core_test.clj

Úprava projektového souboru project.clj je snadná – viz zvýrazněný řádek:

(defproject seesaw5 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [seesaw "1.4.5"]]
  :main ^:skip-aot seesaw5.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Nejdůležitější částí tohoto příkladu je samozřejmě soubor src/seesaw5/core.clj. V něm se nachází definice symbolu formular, který je navázán na hodnotu vrácenou výše popsanou funkcí grid-panel. Povšimněte si, že panel je rozdělen na mřížku 2×2 buňky, do níž jsou umístěny tři widgety: textový popisek (label), tlačítko a další textový popisek (poslední buňka je prázdná). Celý panel se vloží do formuláře ve funkci-konstruktoru frame:

(ns seesaw5.core
    (:gen-class))
 
(use 'seesaw.core)
 
(def formular
    (grid-panel :columns 2
                :rows 2
                :items ["Label1"
                        (button :text "Click me")
                        "Label2"]))
 
(defn -main
    [& args]
    (-> (frame :title "Grid-panel test"
               :on-close :exit
               :content formular)
        (pack!)
        (show!)))

Obrázek 1: Screenshot demonstračního příkladu seesaw5.

4. Použití barev

U většiny widgetů a taktéž u většiny kontejnerů je možné změnit barvu jejich pozadí popř. i barvu popředí u některých prvků (barva textu atd.). Vlastní specifikace barvy je v knihovně Seesaw velmi jednoduchá a bude pravděpodobně vyhovovat jak programátorům znajícím Swing, tak i vývojářům pracujícím s HTML a CSS. V následující tabulce jsou vypsány některé způsoby, jakými je možné barvu specifikovat – buď je možné použít jméno barvy ve formě řetězce, lepší je použití stejného jména, ovšem zapsaného jako klíčové slovo (keyword), ovšem možný je i způsob používaný (nejenom) v HTML a CSS. Dokonce je možné k původní trojici barvových složek dopsat i hodnotu průhlednosti, tj. podporován je i alfa kanál (ovšem s omezeními danými knihovnou Swing):

# Zápis Význam
1 „green“ jedna z pojmenovaných barev
2 :green lepší způsob spočívá v použití keywords
3 „#00ff00“ zápis stejně jako v HTML či CSS
4 „#0f0“ zkrácený zápis, obdoba předchozího řádku
5 :green 128 barva + hodnota alfa
6 „#00ff00“ 128 barva + hodnota alfa
7 0 255 0 složky RGB
8 0 255 0 128 složky RGBA

Pro zajímavost – knihovna Seesaw deklaruje následující barvy, přičemž všechny barvy lze v aplikacích buď specifikovat řetězcem (příklad – „aliceblue“) či klíčovým slovem (příklad – :aliceblue):

Název barvy Hodnoty R G B
aliceblue 240,248,255
antiquewhite 250,235,215
aqua 0,255,255
aquamarine 127,255,212
azure 240,255,255
beige 245,245,220
bisque 255,228,196
black 0,0,0
blanchedalmond 255,235,205
blue 0,0,255
blueviolet 138,43,226
brown 165,42,42
burlywood 222,184,135
cadetblue 95,158,160
chartreuse 127,255,0
chocolate 210,105,30
coral 255,127,80
cornflowerblue 100,149,237
cornsilk 255,248,220
crimson 220,20,60
cyan 0,255,255
darkblue 0,0,139
darkcyan 0,139,139
darkgoldenrod 184,134,11
darkgray 169,169,169
darkgreen 0,100,0
darkgrey 169,169,169
darkkhaki 189,183,107
darkmagenta 139,0,139
darkolivegreen 85,107,47
darkorange 255,140,0
darkorchid 153,50,204
darkred 139,0,0
darksalmon 233,150,122
darkseagreen 143,188,143
darkslateblue 72,61,139
darkslategray 47,79,79
darkslategrey 47,79,79
darkturquoise 0,206,209
darkviolet 148,0,211
deeppink 255,20,147
deepskyblue 0,191,255
dimgray 105,105,105
dimgrey 105,105,105
dodgerblue 30,144,255
firebrick 178,34,34
floralwhite 255,250,240
forestgreen 34,139,34
fuchsia 255,0,255
gainsboro 220,220,220
ghostwhite 248,248,255
gold 255,215,0
goldenrod 218,165,32
gray 128,128,128
green 0,128,0
greenyellow 173,255,47
grey 128,128,128
honeydew 240,255,240
hotpink 255,105,180
indianred 205,92,92
indigo 75,0,130
ivory 255,255,240
khaki 240,230,140
lavender 230,230,250
lavenderblush 255,240,245
lawngreen 124,252,0
lemonchiffon 255,250,205
lightblue 173,216,230
lightcoral 240,128,128
lightcyan 224,255,255
lightgoldenrodyellow 250,250,210
lightgray 211,211,211
lightgreen 144,238,144
lightgrey 211,211,211
lightpink 255,182,193
lightsalmon 255,160,122
lightseagreen 32,178,170
lightskyblue 135,206,250
lightslategray 119,136,153
lightslategrey 119,136,153
lightsteelblue 176,196,222
lightyellow 255,255,224
lime 0,255,0
limegreen 50,205,50
linen 250,240,230
magenta 255,0,255
maroon 128,0,0
mediumaquamarine 102,205,170
mediumblue 0,0,205
mediumorchid 186,85,211
mediumpurple 147,112,219
mediumseagreen 60,179,113
mediumslateblue 123,104,238
mediumspringgreen 0,250,154
mediumturquoise 72,209,204
mediumvioletred 199,21,133
midnightblue 25,25,112
mintcream 245,255,250
mistyrose 255,228,225
moccasin 255,228,181
navajowhite 255,222,173
navy 0,0,128
oldlace 253,245,230
olive 128,128,0
olivedrab 107,142,35
orange 255,165,0
orangered 255,69,0
orchid 218,112,214
palegoldenrod 238,232,170
palegreen 152,251,152
paleturquoise 175,238,238
palevioletred 219,112,147
papayawhip 255,239,213
peachpuff 255,218,185
peru 205,133,63
pink 255,192,203
plum 221,160,221
powderblue 176,224,230
purple 128,0,128
red 255,0,0
rosybrown 188,143,143
royalblue 65,105,225
saddlebrown 139,69,19
salmon 250,128,114
sandybrown 244,164,96
seagreen 46,139,87
seashell 255,245,238
sienna 160,82,45
silver 192,192,192
skyblue 135,206,235
slateblue 106,90,205
slategray 112,128,144
slategrey 112,128,144
snow 255,250,250
springgreen 0,255,127
steelblue 70,130,180
tan 210,180,140
teal 0,128,128
thistle 216,191,216
tomato 255,99,71
turquoise 64,224,208
violet 238,130,238
wheat 245,222,179
white 255,255,255
whitesmoke 245,245,245
yellow 255,255,0
yellowgreen 154,205,50

5. Zdrojový kód dnešního druhého demonstračního příkladu

V dnešním druhém demonstračním příkladu nazvaném seesaw6 je ukázáno použití barev ve formuláři obsahujícím několik tlačítek, přičemž každému tlačítku je přiřazena jiná barva pozadí.

Vytvoření kostry příkladu:

lein new app seesaw6

Obsah projektového souboru project.clj:

(defproject seesaw6 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [seesaw "1.4.5"]]
  :main ^:skip-aot seesaw6.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Ve zdrojovém kódu src/seesaw6/core.clj můžeme vidět definici formuláře obsahujícího jeden textový popisek (label) a osmici tlačítek, přičemž každému tlačítku je s využitím pojmenovaného parametru :background nastavena odlišná barva pozadí. Povšimněte si, že celý formulář je popsán velmi jednoduše na pouhých několika řádcích zdrojového kódu. V mnoha ohledech se jedná o lepší řešení, než to, které je nabízeno například GUI knihovnami, v nichž jsou definice formuláře uloženy v XML souborech:

(ns seesaw6.core
    (:gen-class))
 
(use 'seesaw.core)
(use 'seesaw.color)
 
(def formular
    (grid-panel :columns 3
                :rows 3
                :items ["Color test"
                        (button :text ":background :red"    :background :red)
                        (button :text ":background :yellow" :background :yellow)
                        (button :text ":background :orange" :background :orange)
                        (button :text ":background #ff8080" :background "#ff8080")
                        (button :text ":background #8080ff" :background "#8080ff")
                        (button :text ":background #8f8"    :background "#8f8")
                        (button :text ":background #ff8"    :background "#ff8")
                        (button :text ":foreground :orange" :foreground :orange)
                        ]))
 
(defn -main
    [& args]
    (-> (frame :title "Color test"
               :on-close :exit
               :content formular)
        (pack!)
        (show!)))

Poznámka: z výpisu zdrojového kódu je zřejmé, že pozadí tlačítka (či libovolného jiného widgetu) se volí vlastností :background.

Obrázek 2: Screenshot demonstračního příkladu seesaw6.

6. Použití fontů

Další vlastností knihovny Seesaw, kterou si dnes popíšeme, je specifikace písma použitého pro vybrané ovládací prvky. Podobně jako tomu bylo i u specifikace barev, i fonty je možné popsat hned několika různými způsoby, vždy je však nutné zadat jméno fontu, požadovanou velikost a styl (tučné písmo, kurzíva, kombinace obojího atd.). Požadované písmo lze popsat následujícími způsoby:

# Popis písma Poznámka
1 :font „ARIAL-12“ font+velikost
2 :font „ARIAL-BOLD-18“ font+styl+velikost
3 :font „ARIAL-ITALIC-20“ font+styl+velikost
4 :font {:name „ARIAL“ :style :bold :size 16} popis atributů
5 :font {:name „DejaVu Sans Mono“ :size 16} popis atributů
6 :font {:name „Liberation Serif“ :style :bold :size 16} tučné písmo
7 :font {:name „Liberation Serif“ :style :italic :size 16} kurzíva
8 :font {:name „Liberation Serif“ :style #{:bold :italic} :size 16} tučné písmo+kurzíva

Povšimněte si zejména řádku číslo 8, na němž je ukázáno, že při výběru tučného kurzivního písma je nutné jména obou stylů uložit do množiny (set).

7. Zdrojový kód dnešního třetího demonstračního příkladu

Třetí demonstrační příklad nazvaný seesaw7 se svou strukturou podobá příkladu druhému, až na ten rozdíl, že se pro jednotlivá tlačítka použijí různá písma a nikoli různé barvy pozadí.

Vytvoření kostry příkladu:

lein new app seesaw7

Vzniknout by měla tato adresářová struktura:

.
├── doc
│   └── intro.md
├── LICENSE
├── project.clj
├── README.md
├── resources
├── src
│   └── seesaw7
│       └── core.clj
└── test
    └── seesaw7
        └── core_test.clj

Obsah projektového souboru project.clj:

(defproject seesaw7 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [seesaw "1.4.5"]]
  :main ^:skip-aot seesaw7.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Obsah souboru core.clj:

(ns seesaw7.core
    (:gen-class))
 
(use 'seesaw.core)
(use 'seesaw.font)
 
(def formular
    (grid-panel :columns 3
                :rows 3
                :items ["Font test"
                        (button :text ":font ARIAL-12"
                                :font "ARIAL-12")
                        (button :text ":font ARIAL-BOLD-18"
                                :font "ARIAL-BOLD-18")
                        (button :text ":font ARIAL-ITALIC-20"
                                :font "ARIAL-ITALIC-20")
                        (button :text "{:name \"ARIAL\" :style :bold :size 16}"
                                :font {:name "ARIAL" :style :bold :size 16})
                        (button :text "{:name \"DejaVu Sans Mono\" :size 16}"
                                :font {:name "DejaVu Sans Mono" :size 16})
                        (button :text "{:name \"Liberation Serif\" :style :bold :size 16}"
                                :font {:name "Liberation Serif" :style :bold :size 16})
                        (button :text "{:name \"Liberation Serif\" :style :italic :size 16}"
                                :font {:name "Liberation Serif" :style :italic :size 16})
                        (button :text "{:name \"Liberation Serif\" :style :italic :size 16}"
                                :font {:name "Liberation Serif" :style #{:bold :italic} :size 16})
                        ]))
 
(defn -main
    [& args]
    (-> (frame :title "Font test"
               :on-close :exit
               :content formular)
        (pack!)
        (show!)))

Poznámka: z výpisu zdrojového kódu je zřejmé, že font tlačítka (či libovolného jiného widgetu) se volí vlastností :font.

Obrázek 3: Screenshot demonstračního příkladu seesaw7.

8. Příklad widgetu, který řídí hodnotu zvoleného atomu

Poslední vlastností knihovny Seesaw, kterou se v dnešním článku budeme zabývat, je způsob navázání stavu vybraného widgetu na hodnotu specifikované proměnné. Aplikaci je totiž možné nakonfigurovat takovým způsobem, že se na základě operací prováděných uživatelem v GUI bude automaticky měnit hodnota zvolené proměnné. Je zde ovšem jeden malý háček – programovací jazyk Clojure dovoluje jen řízenou změnu stavu proměnných, což mj. znamená, že programátor sám musí určit, za jakých podmínek se bude měnit hodnota proměnné (v transakci, v rámci jednoho vlákna, synchronizovaně s ostatními vlákny atd.). Pro jednoduchost se přidržme použití atomů, jejichž vlastnosti se asi nejvíce přibližují chápání běžných proměnných. Naším úkolem bude vytvořit aplikací s track barem (též sliderem), při jehož změně se na terminál vypíše jeho nová hodnota.

Nejdříve vytvoříme vlastní track bar, a to velmi jednoduše pomocí funkce core/slider, které se předá minimální hodnota, maximální hodnota a východí hodnota. Referenci uložíme do slider-control:

(def slider-control
    (core/slider :min 0 :max 100 :value 50))

Následně definujeme atom a navážeme ho na jméno slider-atom-value:

(def slider-atom-value (atom 50))

Nyní přichází řada na vytvoření vazby mezi track barem (sliderem) a atomem. Toto je nejdůležitější část aplikace:

(bind/bind slider-control
      slider-atom-value
      slider-control)

Následuje již z minula známý kód – vytvoření tlačítka a vazba anonymní funkce zavolané při stisku tlačítka. V této funkci se čte hodnota atomu s použitím deref, což lze zkrátit na @:

(def print-button
    (core/button :text "Print value"))
 
(core/listen print-button
             :mouse-clicked (fn [e] (println @slider-atom-value)))

Zbytek aplikace již neobsahuje žádné překvapení:

(def formular
    (core/grid-panel :columns 2
                :rows 2
                :items ["Slider test"
                        slider-control
                        ""
                        print-button
                        ]))
 
(defn -main
    [& args]
    (-> (core/frame :title "Slider test"
                    :on-close :exit
                    :content formular)
        (core/pack!)
        (core/show!)))

9. Zdrojový kód dnešního čtvrtého demonstračního příkladu

Podívejme se nyní na zdrojový kód celé aplikace, v níž se používá track bar:

Vytvoření kostry příkladu:

lein new app seesaw8

Vzniknout by měla stejná adresářová struktura, jako u všech sedmi příkladů předchozích.

Obsah projektového souboru project.clj:

(defproject seesaw8 "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [seesaw "1.4.5"]]
  :main ^:skip-aot seesaw8.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Obsah souboru core.clj:

(ns seesaw8.core
    (:gen-class))
 
(require ['seesaw.core :as 'core])
(require ['seesaw.bind :as 'bind])
 
(def slider-control
    (core/slider :min 0 :max 100 :value 50))
 
(def slider-atom-value (atom 50))
 
(bind/bind slider-control
      slider-atom-value
      slider-control)
 
(def print-button
    (core/button :text "Print value"))
 
(core/listen print-button
             :mouse-clicked (fn [e] (println @slider-atom-value)))
 
(def formular
    (core/grid-panel :columns 2
                :rows 2
                :items ["Slider test"
                        slider-control
                        ""
                        print-button
                        ]))
 
(defn -main
    [& args]
    (-> (core/frame :title "Slider test"
                    :on-close :exit
                    :content formular)
        (core/pack!)
        (core/show!)))

Obrázek 4: Screenshot demonstračního příkladu seesaw8.

widgety

10. Repositář s demonstračními příklady

Všechny čtyři dnes popsané demonstrační příklady byly, podobně jako v předchozích částech tohoto seriálu, uloženy do GIT repositáře dostupného na adrese https://github.com/tisnik/clojure-examples. V tabulce zobrazené pod tímto odstavcem naleznete na jednotlivé příklady přímé odkazy:

11. Odkazy na předchozí části seriálu

Stalo se již zvykem uvést odkazy na všechny předchozí části tohoto seriálu:

  1. Leiningen: nástroj pro správu projektů napsaných v Clojure
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure/
  2. Leiningen: nástroj pro správu projektů napsaných v Clojure (2)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/
  3. Leiningen: nástroj pro správu projektů napsaných v Clojure (3)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-3/
  4. Leiningen: nástroj pro správu projektů napsaných v Clojure (4)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-4/
  5. Leiningen: nástroj pro správu projektů napsaných v Clojure (5)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-5/
  6. Leiningen: nástroj pro správu projektů napsaných v Clojure (6)
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-6/
  7. Programovací jazyk Clojure a databáze (1.část)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/
  8. Pluginy pro Leiningen
    http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/
  9. Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi/
  10. Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
    http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi-2/
  11. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk
    http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk/
  12. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (2)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-2/
  13. Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-dokonceni/
  14. Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure
    http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure/

12. Odkazy na Internetu

  1. Building User Interfaces with Seesaw (slajdy k přednášce)
    http://darevay.com/talks/clo­jurewest2012/#/title-slide
  2. Seesaw na GitHubu
    https://github.com/daveray/seesaw
  3. Seesaw API Documentation
    http://daveray.github.io/seesaw/
  4. Seesaw wiki
    https://github.com/davera­y/seesaw/wiki
  5. seesaw-repl-tutorial.clj
    https://gist.github.com/da­veray/1441520
  6. Témata o Seesaw na Google groups
    https://groups.google.com/fo­rum/#!forum/seesaw-clj
  7. Threading macro (dokumentace k jazyku Clojure)
    https://clojure.github.io/clo­jure/clojure.core-api.html#clojure.core/->
  8. Understanding the Clojure → macro
    http://blog.fogus.me/2009/09/04/un­derstanding-the-clojure-macro/
  9. Clisk
    https://github.com/mikera/clisk
  10. clojars: net.mikera/clisk
    https://clojars.org/net.mikera/clisk
  11. clojure.inspector
    http://clojure.github.io/clo­jure/clojure.inspector-api.html
  12. Clisk: wiki
    https://github.com/mikera/clisk/wiki
  13. Dokumentace vygenerovaná pro knihovnu core.matrix
    https://cloojure.github.i­o/doc/core.matrix/index.html
  14. Size and Dimensionality
    https://groups.google.com/fo­rum/#!topic/numerical-clojure/zebBCa68eTw/discussion
  15. Towards core.matrix for Clojure?
    https://clojurefun.wordpres­s.com/2013/01/05/towards-core-matrix-for-clojure/
  16. The Clojure Toolbox
    http://www.clojure-toolbox.com/
  17. Neanderthal
    http://neanderthal.uncomplicate.org/
  18. Hello world project
    https://github.com/uncompli­cate/neanderthal/blob/mas­ter/examples/hello-world/project.clj
  19. vectorz-clj
    https://github.com/mikera/vectorz-clj
  20. vectorz – Examples
    https://github.com/mikera/vectorz-clj/wiki/Examples
  21. gloss
    https://github.com/ztellman/gloss
  22. HTTP client/server for Clojure
    http://www.http-kit.org/
  23. Array Programming
    https://en.wikipedia.org/wi­ki/Array_programming
  24. Discovering Array Languages
    http://archive.vector.org­.uk/art10008110
  25. no stinking loops – Kalothi
    http://www.nsl.com/
  26. Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
    http://www.vector.org.uk/
  27. APL Interpreters
    http://www.vector.org.uk/?a­rea=interpreters
  28. APL_(programming_language
    http://en.wikipedia.org/wi­ki/APL_(programming_langu­age
  29. APL FAQ
    http://www.faqs.org/faqs/apl-faq/
  30. APL FAQ (nejnovější verze)
    http://home.earthlink.net/~swsir­lin/apl.faq.html
  31. A+
    http://www.aplusdev.org/
  32. APLX
    http://www.microapl.co.uk/
  33. FreeAPL
    http://www.pyr.fi/apl/index.htm
  34. J: a modern, high-level, general-purpose, high-performance programming language
    http://www.jsoftware.com/
  35. K, Kdb: an APL derivative for Solaris, Linux, Windows
    http://www.kx.com
  36. openAPL (GPL)
    http://sourceforge.net/pro­jects/openapl
  37. Parrot APL (GPL)
    http://www.parrotcode.org/
  38. Learning J (Roger Stokes)
    http://www.jsoftware.com/hel­p/learning/contents.htm
  39. Rosetta Code
    http://rosettacode.org/wiki/Main_Page
  40. Why APL
    http://www.acm.org/sigapl/whyapl.htm
  41. java.jdbc API Reference
    https://clojure.github.io/java.jdbc/
  42. Hiccup
    https://github.com/weavejester/hiccup
  43. Clojure Ring na GitHubu
    https://github.com/ring-clojure/ring
  44. A brief overview of the Clojure web stack
    https://brehaut.net/blog/2011/rin­g_introduction
  45. Getting Started with Ring
    http://www.learningclojure­.com/2013/01/getting-started-with-ring.html
  46. Getting Started with Ring and Compojure – Clojure Web Programming
    http://www.myclojureadven­ture.com/2011/03/getting-started-with-ring-and-compojure.html
  47. Unit Testing in Clojure
    http://nakkaya.com/2009/11/18/unit-testing-in-clojure/
  48. Testing in Clojure (Part-1: Unit testing)
    http://blog.knoldus.com/2014/03/22/tes­ting-in-clojure-part-1-unit-testing/
  49. API for clojure.test – Clojure v1.6 (stable)
    https://clojure.github.io/clo­jure/clojure.test-api.html
  50. Leiningen: úvodní stránka
    http://leiningen.org/
  51. Leiningen: Git repository
    https://github.com/techno­mancy/leiningen
  52. leiningen-win-installer
    http://leiningen-win-installer.djpowell.net/
  53. Clojure 1: Úvod
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/
  54. Clojure 2: Symboly, kolekce atd.
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/
  55. Clojure 3: Funkcionální programování
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-3-cast-funkcionalni-programovani/
  56. Clojure 4: Kolekce, sekvence a lazy sekvence
    http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-4-cast-kolekce-sekvence-a-lazy-sekvence/
  57. Clojure 5: Sekvence, lazy sekvence a paralelní programy
    http://www.root.cz/clanky/clojure-a-bezpecne-aplikace-pro-jvm-sekvence-lazy-sekvence-a-paralelni-programy/
  58. Clojure 6: Podpora pro paralelní programování
    http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/
  59. Clojure 7: Další funkce pro paralelní programování
    http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/
  60. Clojure 8: Identity, stavy, neměnné hodnoty a reference
    http://www.root.cz/clanky/programovaci-jazyk-clojure-8-identity-stavy-nemenne-hodnoty-a-referencni-typy/
  61. Clojure 9: Validátory, pozorovatelé a kooperace s Javou
    http://www.root.cz/clanky/programovaci-jazyk-clojure-9-validatory-pozorovatele-a-kooperace-mezi-clojure-a-javou/
  62. Clojure 10: Kooperace mezi Clojure a Javou
    http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/
  63. Clojure 11: Generátorová notace seznamu/list comprehension
    http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/
  64. Clojure 12: Překlad programů z Clojure do bajtkódu JVM I:
    http://www.root.cz/clanky/programovaci-jazyk-clojure-12-preklad-programu-z-clojure-do-bajtkodu-jvm/
  65. Clojure 13: Překlad programů z Clojure do bajtkódu JVM II:
    http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/
  66. Clojure 14: Základy práce se systémem maker
    http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/
  67. Clojure 15: Tvorba uživatelských maker
    http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/
  68. Clojure 16: Složitější uživatelská makra
    http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/
  69. Clojure 17: Využití standardních maker v praxi
    http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/
  70. Clojure 18: Základní techniky optimalizace aplikací
    http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/
  71. Clojure 19: Vývojová prostředí pro Clojure
    http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/
  72. Clojure 20: Vývojová prostředí pro Clojure (Vimu s REPL)
    http://www.root.cz/clanky/programovaci-jazyk-clojure-20-vyvojova-prostredi-pro-clojure-integrace-vimu-s-repl/
  73. Clojure 21: ClojureScript aneb překlad Clojure do JS
    http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/
Našli jste v článku chybu?
DigiZone.cz: Světový pohár v přímém přenosu na ČT

Světový pohár v přímém přenosu na ČT

DigiZone.cz: Digi Slovakia zařazuje stanice SPI

Digi Slovakia zařazuje stanice SPI

Lupa.cz: Co všechno je Facebook schopný cenzurovat?

Co všechno je Facebook schopný cenzurovat?

Vitalia.cz: 5 důvodů, proč jet na výlov rybníka

5 důvodů, proč jet na výlov rybníka

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

Lupa.cz: Jak levné procesory změnily svět?

Jak levné procesory změnily svět?

Lupa.cz: Cimrman má hry na YouTube i vlastní doodle

Cimrman má hry na YouTube i vlastní doodle

Podnikatel.cz: Nemá dluhy? Zjistíte to na poště

Nemá dluhy? Zjistíte to na poště

Lupa.cz: Adblock Plus začal prodávat reklamy

Adblock Plus začal prodávat reklamy

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

Vitalia.cz: Voda z Vltavy před a po úpravě na pitnou

Voda z Vltavy před a po úpravě na pitnou

Lupa.cz: Další Češi si nechali vložit do těla čip

Další Češi si nechali vložit do těla čip

120na80.cz: Co je padesátkrát sladší než cukr?

Co je padesátkrát sladší než cukr?

Podnikatel.cz: Udělali jsme velkou chybu, napsal Čupr

Udělali jsme velkou chybu, napsal Čupr

Root.cz: Podívejte se na shořelé Samsung Note 7

Podívejte se na shořelé Samsung Note 7

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

Root.cz: Hořící telefon Samsung Note 7 zapálil auto

Hořící telefon Samsung Note 7 zapálil auto

DigiZone.cz: Budoucnost TV vysílání ve Visegrádu

Budoucnost TV vysílání ve Visegrádu

Vitalia.cz: Antibakteriální mýdla nepomáhají, spíš škodí

Antibakteriální mýdla nepomáhají, spíš škodí

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019