0

也许我在理解 Griffon 的转换器和 reverseConverter 时遗漏了一些东西。出了什么问题,我应该如何解决这个问题?

感谢@tim_yates 的编辑,但我发现我不仅在 Griffon 中而且在普通的 Groovy 中也遇到了同样的错误,如下所示:

import groovy.beans.Bindable
import groovy.swing.SwingBuilder

class Model {
    @Bindable String name
    @Bindable Integer score
}

Model m = new Model()

new SwingBuilder().edt {
    frame(title: 'Untitled', pack: true, show: true) {
        flowLayout()
        label("Name: ")
        textField(columns: 10, text: bind("name", source: m, mutual: true))
        label("Score: ")
        textField(columns: 3, text: bind("score", source: m, 
            reverseConverter: { it.isEmpty()? 0: Integer.parseInt(it) },
            converter: { String.valueOf(it) },
            mutual: true))
        button("Save", actionPerformed: { 
            println "You're saving ${m.name} with score ${m.score}"
        })
        button("Reset Input To Default", actionPerformed: {
            edt {
              m.name = "defaultName"
              m.score = 50
            }
        })
    }
}

堆栈跟踪更详细:

Result: groovy.swing.SwingBuilder@ae20b6Exception in thread "AWT-EventQueue-0" 
java.lang.IllegalStateException: Attempt to mutate in notification
    at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1338)
    at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:659)
    at javax.swing.text.JTextComponent.setText(JTextComponent.java:1718)
    at sun.reflect.GeneratedMethodAccessor276.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2404)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3341)
    at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:196)
    at groovy.beans.DefaultPropertyWriter.write(DefaultPropertyWriter.java:28)
    at groovy.beans.DefaultPropertyAccessor.write(DefaultPropertyAccessor.java:30)
    at org.codehaus.groovy.binding.PropertyBinding.setBeanProperty(PropertyBinding.java:236)
    at org.codehaus.groovy.binding.PropertyBinding.access$000(PropertyBinding.java:51)
    at org.codehaus.groovy.binding.PropertyBinding$2.run(PropertyBinding.java:189)
    at org.codehaus.groovy.binding.PropertyBinding.updateTargetValue(PropertyBinding.java:196)
    at org.codehaus.groovy.binding.AbstractFullBinding.fireBinding(AbstractFullBinding.java:51)
    at org.codehaus.groovy.binding.AbstractFullBinding.update(AbstractFullBinding.java:55)
    at org.codehaus.groovy.binding.PropertyBinding$PropertyFullBinding.propertyChange(PropertyBinding.java:279)
    at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:283)
    at java_beans_PropertyChangeSupport$firePropertyChange$0.call(Unknown Source)
    at Model.firePropertyChange(test.groovy)
    at Model$firePropertyChange.callCurrent(Unknown Source)
    at Model.setScore(test.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2404)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3341)
    at Model.setProperty(test.groovy)
    at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:192)
    at groovy.beans.DefaultPropertyWriter.write(DefaultPropertyWriter.java:28)
    at groovy.beans.DefaultPropertyAccessor.write(DefaultPropertyAccessor.java:30)
    at org.codehaus.groovy.binding.PropertyBinding.setBeanProperty(PropertyBinding.java:236)
    at org.codehaus.groovy.binding.PropertyBinding.access$000(PropertyBinding.java:51)
    at org.codehaus.groovy.binding.PropertyBinding$2.run(PropertyBinding.java:189)
    at org.codehaus.groovy.binding.PropertyBinding.updateTargetValue(PropertyBinding.java:220)
    at org.codehaus.groovy.binding.AbstractFullBinding.fireBinding(AbstractFullBinding.java:51)
    at org.codehaus.groovy.binding.AbstractFullBinding.update(AbstractFullBinding.java:55)
    at groovy.swing.binding.JTextComponentTextBinding.removeUpdate(JTextComponentProperties.java:85)
    at javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:260)
    at javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:623)
    at javax.swing.text.AbstractDocument.remove(AbstractDocument.java:591)
    at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:667)
    at javax.swing.text.JTextComponent.setText(JTextComponent.java:1718)
    at sun.reflect.GeneratedMethodAccessor276.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2404)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3341)
    at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:196)
    at groovy.beans.DefaultPropertyWriter.write(DefaultPropertyWriter.java:28)
    at groovy.beans.DefaultPropertyAccessor.write(DefaultPropertyAccessor.java:30)
    at org.codehaus.groovy.binding.PropertyBinding.setBeanProperty(PropertyBinding.java:236)
    at org.codehaus.groovy.binding.PropertyBinding.access$000(PropertyBinding.java:51)
    at org.codehaus.groovy.binding.PropertyBinding$2.run(PropertyBinding.java:189)
    at org.codehaus.groovy.binding.PropertyBinding.updateTargetValue(PropertyBinding.java:196)
    at org.codehaus.groovy.binding.AbstractFullBinding.fireBinding(AbstractFullBinding.java:51)
    at org.codehaus.groovy.binding.AbstractFullBinding.update(AbstractFullBinding.java:55)
    at org.codehaus.groovy.binding.PropertyBinding$PropertyFullBinding.propertyChange(PropertyBinding.java:279)
    at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:283)
    at java_beans_PropertyChangeSupport$firePropertyChange$0.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at java_beans_PropertyChangeSupport$firePropertyChange.call(Unknown Source)
    at Model.firePropertyChange(test.groovy)
    at Model$firePropertyChange.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at Model$firePropertyChange.callCurrent(Unknown Source)
    at Model.setScore(test.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2404)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3341)
    at Model.setProperty(test.groovy)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setGroovyObjectProperty(ScriptBytecodeAdapter.java:528)
    at test$_run_closure1_closure2_closure6_closure7.doCall(test.groovy:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at groovy.swing.SwingBuilder.edt(SwingBuilder.groovy:330)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:361)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at test$_run_closure1_closure2_closure6.doCall(test.groovy:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
    at groovy.lang.Closure.call(Closure.java:412)
    at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:51)
    at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:82)
    at $Proxy11.actionPerformed(Unknown Source)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6505)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:703)
    at java.awt.EventQueue.access$000(EventQueue.java:102)
    at java.awt.EventQueue$3.run(EventQueue.java:662)
    at java.awt.EventQueue$3.run(EventQueue.java:660)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:676)
    at java.awt.EventQueue$4.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:673)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
4

2 回答 2

1

我相信这是由转换器引起的绑定中的错误,因为它们以绑定认为它在触发时发生变化的方式转换值。如果没有注册转换器(因此在两端强制执行相同的类型),则不会发生错误;这让我认为这是转换器的错。

在我看来,一张票应该在http://jira.codehaus.org/browse/groovy提出

于 2013-03-02T17:35:07.823 回答
0

从上面的答案中,我也同意这可能是一个错误,应该报告。

对于临时,我将使用此解决方法来防止显示异常:

textField(columns: 3, text: bind("score", target: m, 
    converter: { it.isEmpty()? 50: Integer.parseInt(it) },
    reverseConverter: { String.valueOf(it) },
    mutual: true))

转换器将需要将空字符串转换为模型中相同的默认值,在此示例中为 50。这将满足以下守卫org.codehaus.groovy.binding.PropertyBinding

public void updateTargetValue(final Object newValue) {

  Runnable runnable = new Runnable() {
     public void run() {
         ...
         if ((sourceValue==null && newValue==null) || 
              DefaultTypeTransformation.compareEqual(sourceValue, newValue)) {
            // not a change, don't fire it
            return;
         }
     }
  }

}
于 2013-03-03T17:09:03.910 回答