Clojure为JPanel添加边框,并且通常访问对象中的java方法

时间:2011-12-07 23:21:24

标签: clojure border jpanel java-interop clojure-java-interop

来自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。随着这一切的混乱,我正在运行一个不同的定义。 是的,它像你和Kugathasan说的那样有效。 我最终编码为:

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

和它工作! 感谢大家花时间来做这件事。

3 个答案:

答案 0 :(得分:3)

你可以尝试这样,在Clojure中访问Java的方式是错误的。

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

您可以阅读java interop引用,了解如何在Clojure中访问Java。

答案 1 :(得分:2)

Clojure语言参考here非常好地提供了java互操作性规则。 以下是要点:

  1. 静态方法的调用就像使用类名作为命名空间的普通函数一样:

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

    这将解析为java call 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 ...)
    
  4. 当然,要使用常规方法,您必须将新创建的对象绑定到某个符号,例如像这样:

    (let [label (JLabel. "Initial text")]
      ...)
    

    let内部,您现在可以使用label作为对象:

    (let [label (JLabel. "Initial text")]
      (.setText label "New text")
      (.setIconTextGap label 10))
    

    如你在Kugathasan Abimaran的回答评论中的代码所示,你试图在几个地方使用相同的JPanel。你做错了,因为(参见上面的#3)(JPanel. ...)是一个构造形式,每次使用它都会返回新的对象。您必须将新对象绑定到某个变量,然后在其上调用方法,然后将其放入容器/您需要的任何内容中。

    更新: 你的代码很好,你应该像Kugathasan Abimaran建议的那样做。在(doto frame ...行之前添加他的代码,将(JPanel.)替换为您的panel_0。它将按要求工作。

答案 2 :(得分:0)

您想要重现哪些Java代码?看起来你可能想要BorderFactory/createTitledBorder,但谁知道呢?