Clojure добавление границы в JPanel и вообще доступ к java-методам в объектах - PullRequest
0 голосов
/ 08 декабря 2011

Исходя из 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.Следуя вашим инструкциям, я пытался писать по-разному, но пока безуспешно.
Еще раз спасибо всем за помощь.

ОБНОВЛЕНИЕ: Извините, googloplex.Со всем этим беспорядком у меня была другая защита.Да, это работает, как ты и Кугатасан сказали.Я наконец закодировал как:

....
   (JButton. "Button3") [:align "center"]
   )
     tb (BorderFactory/createTitledBorder "Title")
     frame (JFrame. "Frame")
     ]
    (.setBorder panel_0 tb)
    (doto frame
....

и ЭТО РАБОТАЛО !!!Спасибо всем за то, что уделили нам время.

Ответы [ 3 ]

3 голосов
/ 08 декабря 2011

Вы можете попробовать вот так, способ доступа к Java в Clojure неправильный.

(.setBorder (JPanel.) (BorderFactory/createTitledBorder "Title"))

Вы можете прочитать java interop ссылки, чтобы узнать, как получить доступ к Java в Clojure.

2 голосов
/ 08 декабря 2011

Справочник по языку Clojure здесь очень хорошо описывает правила взаимодействия с Java. Вот основные моменты:

  1. Статические методы вызываются как обычные функции, используя имя класса в качестве пространства имен:

    (System/getProperty "java.class.path")
    

    Это будет разрешено вызовом Java System.getProperty("java.class.path")

  2. Обычные методы вызываются для определенных объектов класса, поэтому их синтаксис вызова немного отличается:

    (.setText label "Some text")
    

    Это будет разрешено вызовом java label.setText("Some text"). То есть обычные вызовы методов имеют следующий вид:

    (.methodName object arg1 arg2 arg3 ...)
    
  3. Объект строится по специальной форме 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. ...) является формой построения, она возвращает новый объект каждый раз, когда вы его используете. Вы должны привязать новый объект к некоторой переменной, затем вызвать методы для него и затем поместить его в контейнер / что вам нужно.

UPDATE: Ваш код в порядке, вы должны делать то, что предложил Кугатхасан Абимаран. Добавьте его код перед строкой (doto frame ..., заменив (JPanel.) там своим panel_0. Это будет работать как требуется.

0 голосов
/ 08 декабря 2011

Какой код Java вы пытаетесь воспроизвести?Похоже, вы могли бы хотеть BorderFactory/createTitledBorder, но кто знает?

...