Java 7.x中的validateTree不起作用(在Java 6.x中很好)

use*_*830 7 java swing java-6 java-7

我的java版本是:

Java Plug-in 10.3.1.255使用JRE版本1.7.0_03-b05 Java HotSpot(TM)客户端VM

所以当我有版本6.x一切都很好,升级后我得到了这个:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: This function should be called while holding treeLock
        at java.awt.Component.checkTreeLock(Component.java:1196)
        at java.awt.Container.validateTree(Container.java:1682)
        at pl.recorder.ScenarioWindow.showUploadPanel(PlayerWindow.java:721)
        at pl.recorder.actions.UploadFilesAction.execute(DesignFilesAction.java:71)
        at pl.recorder.actions.EndTestAction.actionPerformed(EndTestAction.java:91)
        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:2713)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
        at java.awt.EventQueue.access$000(EventQueue.java:101)
        at java.awt.EventQueue$3.run(EventQueue.java:666)
        at java.awt.EventQueue$3.run(EventQueue.java:664)
        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:680)
        at java.awt.EventQueue$4.run(EventQueue.java:678)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

我改变validateTree()validate()并且感到惊讶;) - everthing工作正常,但我不知道这个改变是否也适用于java 6.x(我猜不是).如何更改此代码以在Java 6x和7x中工作.

小智 10

"这不是一个bug,它是java 7的一个特性";)

应该在持有treeLock时调用此函数

这是强迫你写作:

synchronized(getTreeLock()) {
     validateTree();
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*n C 8

为了回应@ vince的回答,我认为查看该方法的Java 1.4.2 javadoc说明了什么是有益的:

protected void validateTree()

递归地下降容器树并重新计算标记为需要的任何子树的布局(标记为无效的子树).应该通过调用此方法的方法提供同步:validate.

(重点补充.)

我读这个的方式,就是说这个方法被设计成被调用validate()(可能)将持有树锁.

请注意,Java 6和Java 7中的文本完全相同.规范没有改变......

现在显然有应用程序代码validateTree()直接调用...没有获取树锁.据推测,当最终用户点击太快或某事时,这会导致无法解决的问题(Heisenbugs).据推测,Java 7的变化旨在将这种错误/错误的使用validateTree()带给开发人员注意力.

好的,所以这是短暂的痛苦.但从长远来看,每个人都获胜(除了律师:-)):

  • Oracle没有针对奇怪的不可重现行为获取错误报告,这些行为确实是应用程序员的问题.

  • 开发人员不会因为奇怪的不可复制行为而收到客户的错误报告.

  • 最终用户可以获得更好的应用程序.