用java实质的Gui问题外观和感觉

设置外观和感觉有一个非常奇怪的错误。 为了设置外观我使用以下内容:

... String scheme = "net.sourceforge.atunes.gui.substance.SubstanceATunesSunLookAndFeel"; try { UIManager.setLookAndFeel(scheme); UIManager.put(LafWidget.ANIMATION_KIND, LafConstants.AnimationKind.NONE); UIManager.put(SubstanceLookAndFeel.TABBED_PANE_CONTENT_BORDER_KIND, SubstanceConstants.TabContentPaneBorderKind.SINGLE_FULL); JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); } catch (ClassNotFoundException e) { ExceptionHandler.handleSilently(e); } catch (InstantiationException e) { ExceptionHandler.handleSilently(e); } catch (IllegalAccessException e) { ExceptionHandler.handleSilently(e); } catch (UnsupportedLookAndFeelException e) { ExceptionHandler.handleSilently(e); } 

放在主要function中:

 SwingUtilities.invokeAndWait(new Runnable(){ public void run(){ ... } 

在设置外观之前没有gui元素,因此不需要执行SwingUtilities.updateComponentTreeUI(…)。 所以,一切都很好,但一些用户报告非常奇怪的包包括未处理的窗口,如: 启动程序时,用户会看到以下屏幕(仅当用鼠标移动到此区域时,按钮才会出现;在此之前,窗口不会显示这些按钮。


那么,任何人都可以帮我找到正确的解决方案(我不问解决方案,我只是问正确的方法来解决它)。 首先,我认为这是因为内存不足错误,但用户计算机的配置是:

机器配置:
惠普d530 CMT(DF373A)
 Windows 7旗舰版,32位,SP1
 2GB Ram
 NVIDIA GeForce FX 5700(1680x1050,32位深度)
 Java 1.6.0_26

所以,我猜Out Of Memory并非如此。 任何建议,请。


UPD:所以,每个GUI创建语句都被移动到main函数中的一个SwingUtilities.invokeLater()语句! 但是,一些用户仍然会重现这个问题。 此外,现在已知,只有视图是如此奇怪,但它上面的每个按钮都按预期运行! (我的意思是按下Ok按钮后,显示下一个MVC并且看起来很好)。 只有在设置外观后立即创建的第一个窗口才会出现此错误。 所以,我猜这不是错误的EDT usig的情况,因为井按钮监听器的执行。 此外,我们的日志(log4j)看起来很棒,因为没有什么奇怪的事情发生!
谁有人建议可能的原因?

解决方案请参阅http://java.sun.com/products/java-media/2D/perf_graphics.html作为命令行参数添加的位置:

 -Dsun.java2d.noddraw=true 

同意@Joey

如果您有来自Kirill的Java.net的原始代码源,那么有很多示例可以向您展示

1)之前安装UI

 UIManager.installLookAndFeel("Substance " + sInfo.getDisplayName(), sInfo.getClassName()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { someMainclass.setVisible(true); } }); 

2)您在try-catch中打包所需的SwingUtilities.updateComponentTreeUI(someWindow)问题

 for (Window w : Window.getWindows()) { SwingUtilities.updateComponentTreeUI(w); } 

3)或最安全的方式,确保提取点2dn的顶级容器

 SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(new SubstanceOfficeSilver2007LookAndFeel()); SwingUtilities.updateComponentTreeUI(frame); } catch (UnsupportedLookAndFeelException e) { throw new RuntimeException(e); } } }); SwingUtilities.invokeLater(new Runnable() { 

4)你可以切换主题,L&f,混合主题但必须包含在InvokeLater()

5)

编辑:

@rauch正如我所提到的,Substance对EDT非常敏感,真的忘了在没有最深入了解EDT及其单线程规则的情况下从BackGround任务中替换Model,

嗯我尝试直接替换模型,以避免一些arrayIndexException加上来自Substance的一些exception(我忘了那是一个月前),

你永远不会用javax.swing.Timer或SwingWorker欺骗它,有时候(我认为HightLighter ???或来自Trident.jar的东西拒绝正常工作???和overRun EDT队列)从来没有解决过这个细节,

只是我将所有内容(从Backgroung任务输出到GUI)包装到AbstractAction

编辑2.当我读@kleopatra评论时(错误地我忽略了她的建议)

 would be my first guess as well - were it not Substance: usually it throws on not being on the EDT. Plus: s/he states that the first snippet is placed inside the invokeAndWait to let it run on the EDT 

按照她的建议, Sustance有自己的SwingX L&f ,对我来说SwingX == kleopatra ,我不能给你workAround因为我真的讨厌invokeAndWait而且我避免使用这个方法