强制 Clojure 宏中的参数捕获命名空间
我正在开发一个 Clojure 宏来帮助构建基于 GridBagLayout 的 JPanel。我可以将宏内的默认映射中的 Java 类获取到名称空间限定,但不能获取作为参数传递的那些类。我需要什么样的反引号、引号、代号或其他内容的神奇组合?
(import [java.awt GridBagConstraints GridBagLayout Insets]
[javax.swing JButton JPanel])
(defmacro make-constraints [gridx gridy & constraints]
(let [defaults
{:gridwidth 1 :gridheight 1 :weightx 0 :weighty 0
:anchor 'GridBagConstraints/WEST :fill 'GridBagConstraints/NONE
:insets `(Insets. 5 5 5 5) :ipadx 0 :ipady 0}
values
(assoc (merge defaults (apply hash-map constraints))
:gridx gridx :gridy gridy)]
`(GridBagConstraints. ~@(map (fn [value]
(if
(or
(number? value)
(string? value)
(char? value)
(true? value)
(false? value)
(nil? value))
value
`~value))
(map values
[:gridx :gridy :gridwidth :gridheight
:weightx :weighty :anchor :fill
:insets :ipadx :ipady])))))
当我使用默认映射中定义的 Insets
时,它被限定(不是“符号捕获”)为 (java.awt.Insets ...)
:
user=> (macroexpand-1 '(make-constraints 0 0 :weightx 1))
(java.awt.GridBagConstraints.
0 0 1 1 1 0
GridBagConstraints/WEST GridBagConstraints/NONE
(java.awt.Insets. 5 5 5 5) 0 0)
但是当我把它作为一个论点传递,但它不是:
user=> (macroexpand-1 '(make-constraints 1 1 :insets (Insets. 2 2 2 2)))
(java.awt.GridBagConstraints.
1 1 1 1 0 0
GridBagConstraints/WEST GridBagConstraints/NONE
(Insets. 2 2 2 2) 0 0)
我不仅仅是想成为一个坚持者。我收到编译器错误,它无法找到正确的 GridBagConstraints 构造函数。
I am working on a Clojure macro to help build GridBagLayout-based JPanels. I can get Java classes in a defaults map inside the macro to namespace-qualify, but not those passed in as arguments. What magic combination of backquotes, quotes, tildas, or something else do I need?
(import [java.awt GridBagConstraints GridBagLayout Insets]
[javax.swing JButton JPanel])
(defmacro make-constraints [gridx gridy & constraints]
(let [defaults
{:gridwidth 1 :gridheight 1 :weightx 0 :weighty 0
:anchor 'GridBagConstraints/WEST :fill 'GridBagConstraints/NONE
:insets `(Insets. 5 5 5 5) :ipadx 0 :ipady 0}
values
(assoc (merge defaults (apply hash-map constraints))
:gridx gridx :gridy gridy)]
`(GridBagConstraints. ~@(map (fn [value]
(if
(or
(number? value)
(string? value)
(char? value)
(true? value)
(false? value)
(nil? value))
value
`~value))
(map values
[:gridx :gridy :gridwidth :gridheight
:weightx :weighty :anchor :fill
:insets :ipadx :ipady])))))
When I use the Insets
defined in the defaults map, it gets qualified (not "symbol-captured") as (java.awt.Insets ...)
:
user=> (macroexpand-1 '(make-constraints 0 0 :weightx 1))
(java.awt.GridBagConstraints.
0 0 1 1 1 0
GridBagConstraints/WEST GridBagConstraints/NONE
(java.awt.Insets. 5 5 5 5) 0 0)
but when I pass it as an argument, it does not:
user=> (macroexpand-1 '(make-constraints 1 1 :insets (Insets. 2 2 2 2)))
(java.awt.GridBagConstraints.
1 1 1 1 0 0
GridBagConstraints/WEST GridBagConstraints/NONE
(Insets. 2 2 2 2) 0 0)
I'm not just trying to be a stickler. I am getting compiler errors that it cannot find a proper GridBagConstraints
constructor.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道 GridBagLayout,但以下内容基本上应该与您的宏类似。如果您的组件的
:height
大于 1,则必须在其下方的列中添加nil
以保持列计数器同步。假设您的arrive-text-field
高度为 2,那么您必须在depart-label
之前添加一行nil
code> row 以保持计数器正确。这只是一个快速破解。用法和以前一样。
I don't know
GridBagLayout
, but the following should basically work similar to your macro. If you have a component with a:height
bigger than 1, you have to addnil
in the column(s) below it to keep the column counter in sync. Say, yourarrive-text-field
would have a height of 2, than you'd have to add a row ofnil
before thedepart-label
row in order to keep the counters correct. It's just a quick hack.Usage just as before.
这是我的解决方案。我在我正在编写的 Swing 应用程序中使用它。它已经为我节省了许多行代码编写(针对两个不同的面板),并且与手写代码一样快。
感谢amalloy,user100464< /a> 和 kotarak 寻求帮助。
Here is my solution. I am using it in a Swing application that I am writing. It has already saved me many lines of code writing (for two different panels) and will be as fast as hand-written code.
Thanks to amalloy, user100464, and kotarak for the help.