在运行时更改 Java Swing 主题会导致 JTable 错误
Changing Java Swing themes on runtime causes JTable bugs
我想在我的 Java
Swing
GUI 中更改运行时的外观。
为此,我正在调用 UIManager.setLookAndFeel()
和 SwingUtilities.updateComponentTreeUI()
来刷新 GUI,这似乎有效,但后一种方法会导致严重的 GUI 错误:任何带有 JTable
的选项卡它会导致以下异常并且无法正确呈现:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.sun.java.swing.plaf.windows.WindowsTableHeaderUI$XPDefaultRenderer.paint(WindowsTableHeaderUI.java:171)
at javax.swing.CellRendererPane.paintComponent(CellRendererPane.java:151)
at javax.swing.plaf.basic.BasicTableHeaderUI.paintCell(BasicTableHeaderUI.java:710)
at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:652)
at javax.swing.plaf.synth.SynthTableHeaderUI.paint(SynthTableHeaderUI.java:173)
at javax.swing.plaf.synth.SynthTableHeaderUI.update(SynthTableHeaderUI.java:144)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JViewport.paint(JViewport.java:728)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent.paint(JComponent.java:1042)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
at java.awt.Container.paint(Container.java:1978)
at java.awt.Window.paint(Window.java:3906)
at javax.swing.RepaintManager.run(RepaintManager.java:842)
at javax.swing.RepaintManager.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access00(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch$$$capture(InvocationEvent.java:311)
只有当鼠标移到它们上面并且它不可用时,它才会呈现 "ghosting" 渲染项目的效果。
已经报告了一个 Java 错误 here。我是 运行 Java 版本 1.8.0_231
。有没有办法解决这个问题,或者我做错了什么?
private static void setHeaderAlignment(JTable table)
{
JTableHeader header = table.getTableHeader();
HeaderRenderer headerRenderer = new HeaderRenderer(table);
header.setDefaultRenderer(headerRenderer);
}
可能是因为您的 JTableHeader header
是静态方法的局部变量。
尝试将其作为 class 属性 提取到您的 class 中,并在某个时间将其设置到您的 JTable 中。然后调用你的静态方法。
它将在尝试设置自己的默认渲染器之前提供对 属性 的访问。
不设置默认渲染器修复了该错误。似乎我根本不需要 header 渲染器,所以我很高兴完全放弃它。
我想在我的 Java
Swing
GUI 中更改运行时的外观。
为此,我正在调用 UIManager.setLookAndFeel()
和 SwingUtilities.updateComponentTreeUI()
来刷新 GUI,这似乎有效,但后一种方法会导致严重的 GUI 错误:任何带有 JTable
的选项卡它会导致以下异常并且无法正确呈现:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.sun.java.swing.plaf.windows.WindowsTableHeaderUI$XPDefaultRenderer.paint(WindowsTableHeaderUI.java:171)
at javax.swing.CellRendererPane.paintComponent(CellRendererPane.java:151)
at javax.swing.plaf.basic.BasicTableHeaderUI.paintCell(BasicTableHeaderUI.java:710)
at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:652)
at javax.swing.plaf.synth.SynthTableHeaderUI.paint(SynthTableHeaderUI.java:173)
at javax.swing.plaf.synth.SynthTableHeaderUI.update(SynthTableHeaderUI.java:144)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JViewport.paint(JViewport.java:728)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent.paint(JComponent.java:1042)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
at java.awt.Container.paint(Container.java:1978)
at java.awt.Window.paint(Window.java:3906)
at javax.swing.RepaintManager.run(RepaintManager.java:842)
at javax.swing.RepaintManager.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access00(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch$$$capture(InvocationEvent.java:311)
只有当鼠标移到它们上面并且它不可用时,它才会呈现 "ghosting" 渲染项目的效果。
已经报告了一个 Java 错误 here。我是 运行 Java 版本 1.8.0_231
。有没有办法解决这个问题,或者我做错了什么?
private static void setHeaderAlignment(JTable table)
{
JTableHeader header = table.getTableHeader();
HeaderRenderer headerRenderer = new HeaderRenderer(table);
header.setDefaultRenderer(headerRenderer);
}
可能是因为您的 JTableHeader header
是静态方法的局部变量。
尝试将其作为 class 属性 提取到您的 class 中,并在某个时间将其设置到您的 JTable 中。然后调用你的静态方法。
它将在尝试设置自己的默认渲染器之前提供对 属性 的访问。
不设置默认渲染器修复了该错误。似乎我根本不需要 header 渲染器,所以我很高兴完全放弃它。