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

标签 java swing user-interface default

在使用多个自己的 UI(例如 JTabbedPane)的 Java Swing 应用程序中,有时启动后,整个应用程序的外观 (L&F) 会变回默认值。它很快显示一切正确,然后在一秒或更短的时间内,整个应用程序更改为丑陋的默认值。

不幸的是,这很难重现。当我使用 java-1.6.0-openjdk-amd64 直接从 Eclipse 中启动它时,这种情况很少发生,到目前为止仅在 Ubuntu 下发生。我也安装了较新的java版本,但我使用1.6来测试兼容性。

由于这种情况要么发生在所有组件上,要么没有发生在任何组件上,所以看起来我如何派生 UI 并不重要。它甚至会在不使用自定义 UI 的情况下改回这个小更改:

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

因此,如果发生这种情况,则会显示边框。

由于这很难重现,我无法给出总是发生这种情况的代码示例。实际上,上面的例子已经是一个例子,但并不总是这样。但我希望找到遇到类似问题的人,其中 L&F 或对其进行的任何更改突然且不需要地更改回默认值。如果是这样,如果您能分享您的经验并希望找到解决方案,我将不胜感激。

---------------- 编辑: 我找到了两个解决方法:

  1. 对于边框问题,我只是使用 textField.setBorder(new EmptyBorder()); 而不是将其设置为 null。
  2. 对于 UI 的重置(这确实是由对 updateUI 的不需要的调用引起的),我为自定义的 swing 对象创建了覆盖 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());
        }
    }
    

现在一切正常。

顺便说一句:对 updateUI 的调用具有以下堆栈跟踪(由上面代码中的注释 block 生成):

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)

正如我之前提到的,这些调用很少发生,并且仅发生在 Java 1.6 上。

最佳答案

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

关于具有自己的 L&F 的 Java Swing 有时会突然切换回默认 L&F,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18800687/

相关文章:

java - GLPK for Java - 二进制变量 MIP 给出小数结果

java - 线程 "AWT-EventQueue-0"java.lang.NullPointerException中的异常和JTable问题

Excel ActiveX 组合框显示上一个值问题

android - 为什么我的动画会留下痕迹?

java - 如何在android中制作具有两种颜色的imageview边框并固定尺寸边框宽度

java - 集合排序多项目

java - 将 LinkedHasHSet 的内容输出到 JTable 中

java - 通过 GUI 上的按钮在文本字段中输入数字

java - 测试领​​域模型 Junit Java

Java:我希望 JLabel 仅有时响应鼠标事件。有没有办法隐藏鼠标监听器直到需要为止?