Який найкращий спосіб зробити графічні інтерфейси в Clojure?


150

Який найкращий спосіб зробити графічні інтерфейси в Clojure ?

Чи є приклад якоїсь функціональної оболонки Swing або SWT ? Або якась інтеграція з декларативним описом графічного інтерфейсу JavaFX, яку можна легко перетворити на s-вирази за допомогою деякої макрології?

Будь-які підручники?

Відповіді:


121

Я смиренно запропоную Сесау .

Ось підручник на основі REPL, який не передбачає знання Java або Swing.


Seesaw дуже схожий на те, що пропонує @tomjen. Ось "Привіт, світ":

(use 'seesaw.core)

(-> (frame :title "Hello"
       :content "Hello, Seesaw"
       :on-close :exit)
  pack!
  show!)

і ось приклад @Abhijith і @ dsm, перекладений буквально:

(ns seesaw-test.core
  (:use seesaw.core))

(defn handler
  [event]
  (alert event
    (str "<html>Hello from <b>Clojure</b>. Button "
      (.getActionCommand event) " clicked.")))

(-> (frame :title "Hello Swing" :on-close :exit
           :content (button :text "Click Me" :listen [:action handler]))
  pack!
  show!)

2
роблячи Swing весело? Вони сказали, що це неможливо!
Майкл Більстра

9
Не потрібно бути покірним - ви можете цим пишатися! +1!
mydoghasworms

7
-1: У вашому коді помилка. У ній написано "Привіт, Сесау" замість "Привіт, світ". </Joke>
Томас Едінг

1
Дійсно? Гойдалки? Чи не обмежує це розробник функціоналом, який пропонує Swing, лише на більш високому рівні абстракції, якщо такий є? Clojure якось робить програми, які виглядають менш застарілими, чи це якимось чином покращує всі сфери, в яких Swing слабкий? Я говорю про прив'язки та MVC та все те «нове», що зараз пропонує Swing. Це якось фіксується мовними особливостями Clojure?
Зельфір Кальтшталь

1
Він вирішив спеціально зробити цілеспрямовану абстракцію над Swing. Нічого поганого в цьому ...
Kenogu Labz


16

Якщо ви хочете зайнятися програмуванням графічного інтерфейсу, я би вказав на перетворювач температури або колонію мурах .

Багато речей у Swing виконуються за допомогою підкласифікації, особливо якщо ви створюєте власні компоненти. Для цього існують дві основні функції / макроси: проксі та ген-клас .

Тепер я розумію, куди ви їдете з більш Ліспі. Я не думаю, що ще немає нічого подібного. Я б настійно радив не намагатися створити грандіозний каркас для побудови графічного інтерфейсу a-la CLIM , але зробити щось більше Lispy: почніть писати додаток Swing і абстрагуйте свої загальні шаблони з макросами. Виконуючи це, ви можете розробити мову для написання свого типу графічних інтерфейсів, або, можливо, дуже загальні речі, якими можна ділитися та розвиватися.

Одне, що ви втрачаєте при написанні графічних інтерфейсів у Clojure, - це використання таких інструментів, як Matisse. Це може бути сильним вказівкою на написання деяких частин на Java (GUI), а деяких - у Clojure (логіка). Що насправді має сенс, оскільки в логіці ви зможете створити мову для свого типу логіки за допомогою макросів, і я думаю, що там можна отримати більше, ніж з графічним інтерфейсом. Очевидно, це залежить від вашої заявки.


2
Не хвилюйтеся про втрату Меттісса. Ви можете використовувати miglayout.com , який є досить потужним, щоб ви могли робити макети вручну.
tomjen

Ви можете використовувати Matisse з Clojure, оскільки генерований код - це лише код Java, до якого Clojure може легко отримати доступ. Насправді десь є підручник для цього ...
Рейне

3
Цікаво, коли ми отримуємо перший дизайнер GUI-інтерфейсу, що виводить Clojure. Через гомоконічність генерований код навіть не повинен бути поганим!
nperson325681

15

Ще ніхто не запропонував цього, тому я буду: браузер як платформа UI. Ви можете написати додаток в Clojure, в тому числі сервер HTTP , а потім розробити призначений для користувача інтерфейс , використовуючи що - небудь від HTML до гикавки , ClojureScript і будь-який з мільярдів JS вам потрібно знайти бібліотеки. Якщо ви хочете послідовної поведінки веб-переглядача та "настільної програми look'n'feel", ви можете поєднати хром зі своїм додатком .

Схоже, таким чином розподіляється Світлова таблиця .


це чудово, але визначити правильний порт може бути складним на кожній клієнтській машині
скапіруйте

14

З цієї сторінки :

(import '(javax.swing JFrame JButton JOptionPane)) ;'
(import '(java.awt.event ActionListener))          ;'

(let [frame (JFrame. "Hello Swing")
     button (JButton. "Click Me")]
 (.addActionListener button
   (proxy [ActionListener] []
     (actionPerformed [evt]
       (JOptionPane/showMessageDialog  nil,
          (str "<html>Hello from <b>Clojure</b>. Button "
               (.getActionCommand evt) " clicked.")))))

 (.. frame getContentPane (add button))

 (doto frame
   (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
   .pack
   (.setVisible true)))

print("code sample");

І, звичайно ж , було б варто подивитися на сумісність розділі сайту Clojure в.


3
Так, я знаю, що ти можеш повернутися до прямого використання Swing, але я поцікавився, якщо є більш м'який спосіб зробити це.
Марко

Також зауважте, що в останніх версіях про закриття потрібно додати. перед функцією член викликує в блоці todo.
Jeroen Dirks

8

У додатку clojure є обгортка для MigLayout. Ви також можете поглянути на цю суть . Я в основному виставляю будь-який код, який я пишу, коли я навчаюсь гойдалки / міглайту.

Приклад dsm переписаний липовим способом за допомогою contrib.swing-utils

(ns test
      (:import (javax.swing JButton JFrame))
      (:use (clojure.contrib
          [swing-utils :only (add-action-listener)])))

    (defn handler
      [event]
      (JOptionPane/showMessageDialog nil,
        (str "<html>Hello from <b>Clojure</b>. Button "
          (.getActionCommand event) " clicked.")))

    (let [ frame (JFrame. "Hello Swing") 
           button (JButton. "Click Me")  ]
      (add-action-listener button handler)
        (doto frame
          (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
          (.add button)
          (.pack)
          (.setVisible true)))


6

Я б скоріше пішов на clojurefx, це трохи передчасно, але це працює і економить ваш час.

Я розпочав свій графічний інтерфейс із просмотра, а потім спробував інший компонент у clojurefx.

Я закінчив обоє, і я переконаний, що збираюся переробляти простір на clojurefx.

Зрештою, JavaFX - це шлях іти вперед.

Він відчуває себе легше, ніж глазур. Або принаймні, написавши це ..

Прив'язки працюють, слухачі працюють, більшість компонентів працюють, інакше просто використовуйте один з макросів, щоб створити конструктор для конкретного випадку та виконаної роботи. Або, якщо вам важко, напишіть деякі методи на Java і попросіть допомоги, щоб поліпшити clojurefx.

Хлопець, який написав clojurefx, на даний момент зайнятий, але ви можете роздрібнити проект і зробити деякі виправлення.


Чи вирішив JavaFX проблеми ще не дуже рідного вигляду? Питання серйозне, адже коли я вперше перевірив це, це було дуже давно, і це виглядало менш правильно, ніж Swing.
Трежказ

4

Ось ще один дуже базовий приклад обгортання:

; time for some swing
(import '(javax.swing JFrame JTable JScrollPane))
(import '(javax.swing.table DefaultTableModel))

(let 
  [frame (JFrame. "Hello Swing")
    dm (DefaultTableModel.)
      table (JTable. dm)
        scroll (JScrollPane. table)]
  (doto dm
      (.setNumRows 30)
        (.setColumnCount 5))
  (.. frame getContentPane (add scroll))
    (doto frame
      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) 
        (.pack)
        (.setVisible true)))

3

Я задав собі те саме питання, як написати GUI в Clojure with Swing, і придумав бібліотеку signe

Це дозволяє вам представляти вашу модель домену як єдину структуру даних Clojure, загорнуту всередині атома.

Дивіться приклади тут .


2

Я розробляв аплет Java, в якому все написано в Clojure, крім коду аплета, який написаний на Java. Аплет викликає зворотні виклики коду Clojure про init, фарбу тощо з гаків java для тих методів, які визначені моделлю аплет. Таким чином, код в кінцевому підсумку становить 99,999 відсотків Clojure, і вам зовсім не доведеться думати про крихітний Java-фрагмент.

У цьому підході є деякі недоліки, про які я сподіваюся детальніше обговорити в групі Clojure Google. Я думаю, що розробники Clojure повинні включати в себе власний спосіб створення додатків. В даний час ви можете робити все, що вам подобається в графічному інтерфейсі від REPL, але якщо ви хочете отримати доступний GUI-додаток, потрібно написати Java, щоб зателефонувати на код Clojure. Крім того, здається, що архітектура Java-аплету вимушує вас за межами кращих ідіоматичних практик Clojure, вимагаючи від вас змінного стану тощо.

Але також я ще не дуже далеко з Clojure, і, можливо, це можливо, і я просто ще не дізнався, як це зробити правильно.


2

Моє переважне середовище інтерфейсу Clojure використовує IO.js (Node for ES6) + Electron (Container) + Quiescent (ReactJS обгортка) .


1
Це може бути складним, але я все ж хочу запитати: чи можете ви навести приклад того, як розпочати роботу з цими творами? Або опишіть, яка частина програми буде оброблятися за допомогою тієї рамки / бібліотеки, яку ви згадали?
Зельфір Кальтшталь

2

Тому я не бачив у цьому списку Fn-Fx від Тімоті Болдріджа (халгірі). Це бібліотека Clojure, що забезпечує функціональну абстракцію над JavaFX.

Його можна знайти в Github за адресою https://github.com/halgari/fn-fx .

Для використання переконайтеся, що ви використовуєте останню версію Java (1.8 90+) та додайте залежність до репортажу github, додавши в проект project.clj наступне:

:plugins [[lein-git-deps "0.0.1-SNAPSHOT"]]
:git-dependencies [["https://github.com/halgari/fn-fx.git"]]

Я спробував це, і він працює з коробки.


1

Clojure та SWT - найкращий підхід для ведення графічних інтерфейсів. По суті, SWT - це стиль підключення та розробки програмного забезпечення для розробки програмного забезпечення.


1
Чи можете ви надати посилання чи приклад? Мені було б цікаво, але поняття не маю, як почати.
Карл Смотрич

1
Карл, друге що. Гарний підручник про те, як писати плагіни Eclipse за допомогою clojure, було б досить приємно.
Егон Віллігаген

1

Я не думаю, що існує офіційна, але особисто я би скористався тим, що я використовую одну з найпотужніших мов у світі і лише уявляю, як виглядатиме ідеальний код Gui:

(form {:title :on-close dispose :x-size 500 :y-size 450}
  [(button {:text "Close" :id 5 :on-click #(System/exit 0) :align :bottom})
   (text-field {:text "" :on-change #(.println System/out (:value %)) :align :center})
   (combo-box {:text "Chose background colour" :on-change background-update-function
               :items valid-colours})])

Ваша ідея відрізнятиметься, але це, мабуть, сподівається, що вищесказане дає вам певну ідею.


Схоже, groovy SwingBuilder dsl в перекладі на Clojure.
Марко

@ dev-er-dev Це дуже можливо, я ніколи не використовував groovy, але великі уми роблять щось подібне :)
tomjen

1

Я знаю, що ви натякаєте на класичні рішення для настільних комп'ютерів, але веб дуже добре поєднується з клоджур. Я написав повний аудіо-додаток, де все підключено, так що якщо ви додасте музику до папки аудіо, це відображається в веб-інтерфейсі. Просто кажучи, що настільний додаток - не єдиний спосіб :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.