Clojure добавление границы в JPanel и вообще доступ к java-методам в объектах
Исходя из LISP, у меня самые сложные моменты при доступе к Java-объектам. Я пытаюсь поставить титулованную границу на JPanel. Вот мой код и исключение:
user=> (import '(javax.swing JComponent JPanel BorderFactory))
javax.swing.BorderFactory
user=> (JPanel. (.setBorder (.createTitledBorder "Title")))
#<CompilerException java.lang.IllegalArgumentException: No matching field found: createTitledBorder for class java.lang.String (NO_SOURCE_FILE:785)>
Где я могу найти правила для решения таких ситуаций? Как всегда, ваша помощь будет высоко оценена.
Я благодарю вас всех за ваши ответы и разъяснения. Я публикую основы этой функции, чтобы мы все знали, к чему обращаться:
(import '(javax.swing JComponent JButton JFrame JLabel JPanel BorderFactory))
(use '(clojure.contrib [miglayout :only (miglayout)]))
(defn cm_dlg []
(let
[
panel_0
(miglayout
(JPanel.)
:layout [:wrap 2]
(JLabel. "Some Text:") [:align "right"]
(JLabel. "More Text:") [:align "left"]
(JLabel. "Some Text:") [:align "right"]
(JLabel. "More Text:") [:align "left"]
(JLabel. "Some Text:") [:align "right"]
(JLabel. "More Text:") [:align "left"]
(JLabel. "Some Text:") [:align "right"]
(JLabel. "More Text:") [:align "left"]
)
panel_1
(miglayout
(JPanel.)
:layout [:wrap]
(JButton. "Button0") [:align "center"]
(JButton. "Button1") [:align "center"]
(JButton. "Button2") [:align "center"]
(JButton. "Button3") [:align "center"]
)
frame (JFrame. "Frame")
]
(doto frame
(.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
(-> .getContentPane
(.add (miglayout (JPanel.)
:layout [:flowy]
panel_0 [:align "center"]
panel_1 [:align "center"]
)))
(.pack)
(.setVisible true))))
Например, эта функция работает без проблем, но я пытаюсь установить TitledBorder на panel_0. Следуя вашим инструкциям, я пытался кодировать по-разному, но пока безуспешно.
Еще раз спасибо всем за вашу помощь.
ОБНОВЛЕНИЕ: Извините, гуглоплекс. Со всем этим беспорядком у меня была другая защита. Да, это работает, как ты и Кугатасан сказали. Я наконец закодировал как:
....
(JButton. "Button3") [:align "center"]
)
tb (BorderFactory/createTitledBorder "Title")
frame (JFrame. "Frame")
]
(.setBorder panel_0 tb)
(doto frame
....
И ЭТО РАБОТАЛО!!! Спасибо всем за то, что посвятили этому время.
3 ответа
Справочник по языку Clojure очень хорошо описывает правила взаимодействия с Java. Вот основные моменты:
Статические методы вызываются как обычные функции, используя имя класса в качестве пространства имен:
(System/getProperty "java.class.path")
Это будет решено для вызова Java
System.getProperty("java.class.path")
Обычные методы вызываются для определенных объектов класса, поэтому их синтаксис вызова немного отличается:
(.setText label "Some text")
Это будет решено для вызова Java
label.setText("Some text")
, То есть обычные вызовы методов имеют такую форму:(.methodName object arg1 arg2 arg3 ...)
Объект строится с использованием специальной формы
new
:(new JLabel "Initial text")
Для этого есть сокращение, использующее макрос для чтения точек:
(JLabel. "Initial text")
Эти последние две формы полностью эквивалентны. Итак, как вы можете видеть, конструкция принимает следующую форму:
(new Classname arg1 arg2 ...) ; or (Classname. arg1 arg2 ...)
Конечно, чтобы использовать обычные методы, вы должны привязать вновь созданный объект к некоторому символу, например, так:
(let [label (JLabel. "Initial text")]
...)
внутри let
тело вы можете использовать label
как объект:
(let [label (JLabel. "Initial text")]
(.setText label "New text")
(.setIconTextGap label 10))
Как следует из вашего кода в комментарии к ответу Кугатасана Абимарана, вы пытаетесь использовать один и тот же JPanel в нескольких местах. Вы делаете это неправильно, так как (см. № 3 выше) (JPanel. ...)
это строительная форма, она возвращает новый объект каждый раз, когда вы его используете. Вы должны связать новый объект с некоторой переменной, затем вызвать методы для него и затем поместить его в контейнер / все, что вам нужно.
ОБНОВЛЕНИЕ: Ваш код в порядке, вы должны делать то, что предложил Кугатасан Абимаран. Добавьте его код прямо перед вашим (doto frame ...
линия, заменяющая (JPanel.)
там с вашим panel_0
, Это будет работать как требуется.
Вы можете попытаться сделать это следующим образом, неправильный способ доступа к Java в Clojure.
(.setBorder (JPanel.) (BorderFactory/createTitledBorder "Title"))
Вы можете прочитать ссылки на Java-взаимодействия, чтобы узнать, как получить доступ к Java в Clojure.
Какой код Java вы пытаетесь воспроизвести? Похоже, вы могли бы хотеть BorderFactory/createTitledBorder
а кто знает?