Каков наилучший способ сделать GUI в Clojure?


150

Каков наилучший способ сделать GUI в 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: в вашем коде есть ошибка Он говорит «Привет, качели» вместо «Привет, мир». </ Шутка>
Томас Эдинг

1
В самом деле? Свинг? Разве это не ограничивает разработчика функциональностью, которую предлагает Swing, просто на более высоком уровне абстракции, если таковой имеется? Делает ли Clojure приложения устаревшими или же улучшает все области, в которых Swing слаб? Я говорю о привязках, MVC и всех тех «новых» вещах, которые Swing теперь предлагает как таковые. Это как-то фиксируется языковыми особенностями Clojure?
Зельфир Кальцталь

1
Он решил специально сфокусироваться на Swing. Ничего плохого в этом нет ...
Кеногу Лабз


16

Если вы хотите заниматься программированием с помощью графического интерфейса, я бы указал на « Конвертер температуры» или колонию муравьев .

Многие вещи в Swing выполняются подклассами, особенно если вы создаете пользовательские компоненты. Для этого есть две основные функции / макросы: proxy и gen-class .

Теперь я понимаю, куда ты идешь с Лиспой. Я не думаю, что есть что-то подобное еще. Я бы настоятельно рекомендовал не пытаться создать грандиозную среду построения GUI в стиле CLIM , но делать что-то более Lispy: начните писать свое приложение Swing и абстрагируйте свои общие шаблоны с помощью макросов. При этом у вас может получиться язык для написания графического интерфейса пользователя, или, может быть, какой-то очень общий материал, которым можно делиться и расти.

Одна вещь, которую вы теряете при написании GUI в Clojure, - это использование таких инструментов, как Matisse. Это может быть убедительным указанием для написания некоторых частей на Java (GUI) и некоторых частей на Clojure (логика). Что на самом деле имеет смысл, так как в логике вы сможете создать язык для вашей логики, используя макросы, и я думаю, что здесь есть что-то большее, чем в GUI. Очевидно, это зависит от вашего приложения.


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

Вы можете использовать Matisse с Clojure, потому что сгенерированный код является просто кодом Java, к которому Clojure может легко получить доступ. На самом деле где-то есть учебник ...
Rayne

3
Интересно, когда мы получим первый дизайнер GUI с выходом clojure. Из-за гомоничности, сгенерированный код даже не должен быть плохим!
nperson325681

15

Никто еще не предложил это, поэтому я буду: Браузер как платформа пользовательского интерфейса. Вы можете написать свое приложение на Clojure, включая HTTP-сервер, а затем разработать пользовательский интерфейс, используя что угодно, от HTML до hiccup , ClojureScript и любой из миллиардов JS-библиотек, которые вам нужны. Если вам нужно постоянное поведение браузера и «внешний вид приложения для ПК», вы можете связать Chrome с вашим приложением .

Это похоже на то, как Light Table распространяется.


это здорово, но определить правильный порт может быть сложно на каждом клиентском компьютере
scape

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.
Джероен Диркс

8

Существует оболочка для MigLayout в contrib clojure. Вы также можете взглянуть на эту суть . Я в основном выкладываю любой код, который пишу, когда изучаю свинг / миграцию.

Пример 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.
Trejkaz

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

Я задал себе тот же вопрос написания графического интерфейса в Clojure с Swing и придумал библиотечную подпись

Это позволяет использовать представление вашей доменной модели в виде единой структуры данных Clojure, заключенной в атом.

Смотрите примеры здесь .


2

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

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

Но также я еще не очень близок с Clojure, и, возможно, это возможно, и я просто еще не понял, как это сделать правильно.


2

Моя предпочтительная среда пользовательского интерфейса Clojure использует IO.js (узел для ES6) + Electron (контейнер) + 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 - лучший подход для создания GUI. По сути, SWT - это стиль «включай и работай» для разработки программного обеспечения.


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

1
Карл, второй это. Хороший учебник о том, как писать плагины Eclipse с использованием clojure, был бы неплохо.
Egon Willighagen

1

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

(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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.