用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
而且我避免使用这个方法