Java “JOptionPane”;“将窗口添加到容器中”;Clojure中的例外
使用Java “JOptionPane”;“将窗口添加到容器中”;Clojure中的例外,java,clojure,Java,Clojure,使用JOptionPane.showInputDialog时,当我尝试指定父组件时,会得到一个IllegalArgumentException。它在Java中工作,但在Clojure中不工作。 不管异常是怎么说的,我实际上并没有在容器中添加窗口。我正在尝试创建一个单独的框架,并将其用作JOptionPane.showInputDialog的父窗口。这是我的Clojure代码: (def parent-frame (doto (new javax.swing.JFrame) (.set
JOptionPane.showInputDialog
时,当我尝试指定父组件时,会得到一个IllegalArgumentException
。它在Java中工作,但在Clojure中不工作。
不管异常是怎么说的,我实际上并没有在容器中添加窗口。我正在尝试创建一个单独的框架,并将其用作JOptionPane.showInputDialog
的父窗口。这是我的Clojure代码:
(def parent-frame
(doto (new javax.swing.JFrame)
(.setDefaultCloseOperation javax.swing.JFrame/DISPOSE_ON_CLOSE)
(.pack)
(.setVisible true)))
(javax.swing.JOptionPane/showMessageDialog parent-frame "Hello") ;pops up dialog
(javax.swing.JOptionPane/showInputDialog parent-frame "Hello?") ;throws an exception
等效的Java代码实现了我所期望的:
JFrame parentFrame = new JFrame();
parentFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
parentFrame.pack();
parentFrame.setVisible(true);
JOptionPane.showMessageDialog(parentFrame,"Hello"); //pops up a dialog
JOptionPane.showInputDialog(parentFrame,"Hello?"); //pops up a dialog
知道Clojure代码为什么不工作吗?
JOptionPane.showInputDialog
过载
showInputDialog(Object message, Object initialSelectionValue)
...
showInputDialog(Component parentComp, Object message)
当执行(javax.swing.JOptionPane/showInputDialog父框架“Hello?”)
时,clojure似乎调用showInputDialog(对象消息,对象初始选择值)
您可以在回复中检查此项:
user=> (javax.swing.JOptionPane/showInputDialog parent-frame "hello")
IllegalArgumentException adding a window to a container java.awt.Container.checkNotAWindow (Container.java:490)
user=> *e
#error {
:cause "adding a window to a container"
:via
[{:type java.lang.IllegalArgumentException
:message "adding a window to a container"
:at [java.awt.Container checkNotAWindow "Container.java" 490]}]
:trace
[[java.awt.Container checkNotAWindow "Container.java" 490]
[java.awt.Container addImpl "Container.java" 1091]
[java.awt.Container add "Container.java" 973]
[javax.swing.plaf.basic.BasicOptionPaneUI addMessageComponents "BasicOptionPaneUI.java" 358]
[com.apple.laf.AquaOptionPaneUI createMessageArea "AquaOptionPaneUI.java" 92]
[javax.swing.plaf.basic.BasicOptionPaneUI installComponents "BasicOptionPaneUI.java" 172]
[javax.swing.plaf.basic.BasicOptionPaneUI installUI "BasicOptionPaneUI.java" 141]
[javax.swing.JComponent setUI "JComponent.java" 666]
[javax.swing.JOptionPane setUI "JOptionPane.java" 1860]
[javax.swing.JOptionPane updateUI "JOptionPane.java" 1882]
[javax.swing.JOptionPane <init> "JOptionPane.java" 1845]
[javax.swing.JOptionPane showInputDialog "JOptionPane.java" 568]
[javax.swing.JOptionPane showInputDialog "JOptionPane.java" 494]
[javax.swing.JOptionPane showInputDialog "JOptionPane.java" 455]
[user$eval10619 invokeStatic "form-init4926112649336753943.clj" 1]
[user$eval10619 invoke "form-init4926112649336753943.clj" 1]
...
如您所见,JOptionPane
允许将对象作为消息传递。如果将组件
作为消息传递,它将用作消息组件
在这种情况下,父帧
作为消息传递,之后它试图将此父帧
(即窗口
)添加到容器
,这导致了非法argumentException
我不知道当目标方法重载时clojure如何决定调用哪个方法。Clojure选错了一个。我认为你应该用其他方法来避免这个问题
(javax.swing.JOptionPane/showInputDialog parent-frame "Hello?" "")
这将导致clojure调用showInputDialog(组件父级、对象混乱、字符串初始选择值)
,并正确显示JOptionPane
编辑
您还可以为参数提供类型提示,clojure可以选择正确的方法,正如@James在他的回答中提到的。这是更好的办法
(javax.swing.JOptionPane/showInputDialog #^java.awt.Component parent-frame "Hello?")
如前所述,JOptionPane.showInputDialog
过载:
showInputDialog(Object message, Object initialSelectionValue)
showInputDialog(Component parentComp, Object message)
Java通过参数数量及其类型来区分重载方法,而Clojure仅通过参数数量来区分。您可以通过类型提示让Clojure调用正确的方法:
(javax.swing.JOptionPane/showInputDialog #^java.awt.Component parent-frame "Hello?")
这里有更多信息:对。Clojure和Java之间的区别在于Java通过参数数量及其类型来区分重载方法,而Clojure仅通过参数数量来区分。抢手货
(javax.swing.JOptionPane/showInputDialog #^java.awt.Component parent-frame "Hello?")