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 上。按照您的指示,我尝试以不同的方式进行编码,但到目前为止尚未成功。
再次感谢大家的帮助。
更新:抱歉,googloplex。面对所有这些混乱,我正在运行不同的定义。 是的,正如你和 Kugathasan 所说的那样。 我最终编码为:
....
(JButton. "Button3") [:align "center"]
)
tb (BorderFactory/createTitledBorder "Title")
frame (JFrame. "Frame")
]
(.setBorder panel_0 tb)
(doto frame
....
并且成功了!!! 感谢大家为此投入时间。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你可以这样尝试,你在Clojure中访问Java的方式是错误的。
您可以阅读 java interop 参考资料来了解如何在 Clojure 中访问 Java。
You can try like this, the way you access Java in Clojure is wrong.
You may read java interop references to know how to access Java in Clojure..
Clojure 语言参考此处很好地给出了 java 互操作性规则。
以下是要点:
静态方法的调用就像使用类名作为命名空间的普通函数一样:
这将解析为 java 调用
System.getProperty("java.class.path")
常规方法是在类的特定对象上调用的,因此它们的调用语法略有不同:
这将解析为 java 调用
label.setText("Some text")
。也就是说,常规方法调用采用以下形式:使用特殊形式构造对象
new
:有一个使用点读取器宏的简写:
最后两种形式是完全等价的。因此,如您所见,构造采用以下形式:
当然,要使用常规方法,您必须将新创建的对象绑定到某个符号,例如:
在
let
主体中,您现在可以使用label
作为对象:正如 Kugathasan Abimaran 答案的评论中的代码所示,您尝试在多个地方使用相同的 JPanel。你这样做是错误的,因为(参见上面的#3)
(JPanel. ...)
是一种构造形式,每次使用它时它都会返回新对象。您必须将新对象绑定到某个变量,然后调用它的方法,然后将其放入容器/任何您需要的东西中。更新:
你的代码很好,你应该像 Kugathasan Abimaran 建议的那样做。在您的
(doto frame ...
行之前添加他的代码,将其中的(JPanel.)
替换为您的panel_0
。它将按要求工作。Clojure language reference here gives the java interoperability rules pretty well.
Here are the main points:
Static methods are called just like plain functions using class name as namespace:
This will be resolved to java call
System.getProperty("java.class.path")
Regular methods are called on specific objects of the class, so their calling syntax is slightly different:
This will be resolved to java call
label.setText("Some text")
. That is, the regular method calls take this form:Object are constructed using special form
new
:There is a shorthand for it using dot reader macro:
These last two forms are completely equivalent. So, as you can see, construction takes this form:
Of course, to use regular methods you have to bind newly created object to some symbol, e.g. like this:
Inside
let
body you now can uselabel
as an object:As follows from your code in the commentary to Kugathasan Abimaran's answer, you are trying to use the same JPanel in several places. You are doing it incorrectly, since (see #3 above)
(JPanel. ...)
is a construction form, it returns new object every time you use it. You have to bind the new object to some variable, then call methods on it and then put it into container/whatever you need.UPDATE:
Your code is fine, you should do like Kugathasan Abimaran suggested. Add his code just before your
(doto frame ...
line, replacing(JPanel.)
there with yourpanel_0
. It will work as required.您想要重现什么 Java 代码?看起来您可能想要
BorderFactory/createTitledBorder
,但谁知道呢?What Java code are you trying to reproduce? It looks like you might want
BorderFactory/createTitledBorder
, but who knows?