来自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
....
和它工作! 感谢大家花时间来做这件事。
答案 0 :(得分:3)
你可以尝试这样,在Clojure中访问Java的方式是错误的。
(.setBorder (JPanel.) (BorderFactory/createTitledBorder "Title"))
您可以阅读java interop引用,了解如何在Clojure中访问Java。
答案 1 :(得分:2)
Clojure语言参考here非常好地提供了java互操作性规则。 以下是要点:
静态方法的调用就像使用类名作为命名空间的普通函数一样:
(System/getProperty "java.class.path")
这将解析为java call 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))
如你在Kugathasan Abimaran的回答评论中的代码所示,你试图在几个地方使用相同的JPanel。你做错了,因为(参见上面的#3)(JPanel. ...)
是一个构造形式,每次使用它都会返回新的对象。您必须将新对象绑定到某个变量,然后在其上调用方法,然后将其放入容器/您需要的任何内容中。
更新:
你的代码很好,你应该像Kugathasan Abimaran建议的那样做。在(doto frame ...
行之前添加他的代码,将(JPanel.)
替换为您的panel_0
。它将按要求工作。
答案 2 :(得分:0)
您想要重现哪些Java代码?看起来你可能想要BorderFactory/createTitledBorder
,但谁知道呢?