简体   繁体   English

具有自己的L&F的Java Swing有时会突然切换回默认L&F

[英]Java Swing with own L&F sometimes suddenly switches back to default L&F

In a Java Swing application that uses several own UI's (eg for JTabbedPane) sometimes right after startup, the Look and Feel (L&F) of the entire application changes back to the default. 在有时会在启动后立即使用多个自己的UI的Java Swing应用程序中(例如,对于JTabbedPane),整个应用程序的外观(L&F)会更改回默认值。 It quickly shows everything correct and then after a second or less the entire application changes to the ugly default. 它迅速显示出所有正确的内容,然后在一秒钟或更短的时间内,整个应用程序更改为难看的默认值。

Unfortunately, this is difficult to reproduce. 不幸的是,这很难重现。 It happens very rarely and so far only under Ubuntu when I start it directly from within Eclipse using java-1.6.0-openjdk-amd64. 这种情况很少发生,到目前为止只有在Ubuntu下,当我使用java-1.6.0-openjdk-amd64在Eclipse中直接启动它时,才发生。 I have a newer java version installed too, but I use 1.6 to test compatibility. 我也安装了更新的Java版本,但是我使用1.6来测试兼容性。

Since it happens either for all or for no component, it looks like it does not matter how II derive the UI. 由于它发生在所有组件上,也可能没有发生,因此II派生UI似乎无关紧要。 It even changes back this little change where no custom UI is used: 它甚至可以改回不使用自定义UI的小变化:

JTextField textField = new JTextField();
textField.setBorder(null);

So if it happens, then the border will show up. 因此,如果发生这种情况,边框将显示出来。

Since this is difficult to reproduce, I can not give a code example where it always happens. 由于这很难重现,因此我无法给出一个总是发生这种情况的代码示例。 Actually, the one above is already an example, but it does not happen always. 实际上,上面的例子已经是一个例子,但并非总是如此。 But I hope to find someone who run into a similar issue where the L&F or any changes to it suddenly and unwanted changed back to the default. 但是,我希望找到遇到类似问题的人,L&F或对L&F的任何更改会突然出现,并且不必要的会变回默认值。 If so, I would appreciate if you could share your experience and hopefully a solution. 如果是这样,希望您能分享您的经验并希望提供解决方案。

---------------- Edit: I found two workaraounds: ----------------编辑:我发现了两个workaraounds:

  1. For the border problem, I simply use textField.setBorder(new EmptyBorder()); 对于边框问题,我只使用textField.setBorder(new EmptyBorder()); instead of setting it to null. 而不是将其设置为null。
  2. For the reset of the UI, which was indeed caused by unwanted calls to updateUI, I created for my customized swing objects subclasses that override updateUI(), eg: 对于UI的重置,这确实是由于对updateUI的不必要调用而引起的,我为我的自定义摆动对象子类创建了覆盖updateUI()的子类,例如:

     public class JTabbedPaneNoHeads extends JTabbedPane { public JTabbedPaneNoHeads() { setUI(new GUITabbedPaneNoHeadsUI()); } @Override public GUITabbedPaneNoHeadsUI getUI() { return (GUITabbedPaneNoHeadsUI) ui; } @Override public void updateUI() { /* This was to find out who is calling updateUI: StackTraceElement[] _stackTrace = Thread.currentThread().getStackTrace(); for (StackTraceElement element : _stackTrace ){ System.out.print(element + " -- "); } System.out.println(); */ setUI(new GUITabbedPaneNoHeadsUI()); } } 

Now everything works fine. 现在一切正常。

btw: the calls to updateUI had the following stack trace (generated by the commented block in the code above): 顺便说一句:对updateUI的调用具有以下堆栈跟踪(由上面的代码中的注释块生成):

livedocket.GUI.design.JTabbedPaneNoHeads.updateUI(JTabbedPaneNoHeads.java:22)
javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1230)
.... many more of these updateComponentTreeUI0 ...
javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1245)
javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1221)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener.updateWindowUI(MetalLookAndFeel.java:2329)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener.updateAllUIs(MetalLookAndFeel.java:2342)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener.access$200(MetalLookAndFeel.java:2295)
javax.swing.plaf.metal.MetalLookAndFeel$AATextListener$1.run(MetalLookAndFeel.java:2370)
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
java.awt.EventQueue.dispatchEventImpl(EventQueue.java:673)
java.awt.EventQueue.access$300(EventQueue.java:96)
java.awt.EventQueue$2.run(EventQueue.java:634)
java.awt.EventQueue$2.run(EventQueue.java:632)
java.security.AccessController.doPrivileged(Native Method)
java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:108)
java.awt.EventQueue.dispatchEvent(EventQueue.java:643)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

As I mentioned before, these calls happen only very rarely and only on Java 1.6. 如前所述,这些调用仅在Java 1.6上很少发生。

我在出现线程问题的应用程序中看到了类似的症状-如果我是我,那么我将仔细检查是否所有的GUI都是在事件调度线程上构建的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM