You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Setup: Application has a JTabbedPane with custom Tab Header components. The custom header is a JPanel that includes a JTextField. Application has a theme toggle with FlatLAF and system themes.
Apparent Bug: If the component part of the tab header (i.e., the JTextField) is clicked before switching between Light and Dark Flat themes, a Null Pointer Exception is thrown.
Steps to Reproduce:
Set theme to light or dark flat
Click on the tab header component (i.e., the Text Field). Note: error is not thrown if clicking in the tab area that is NOT part of the component.
Switch theme to light or dark flat (whatever is not currently selected) -- NPE is thrown
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */packageflattabtest;
importjava.awt.BorderLayout;
importjava.awt.Dimension;
importjava.awt.Window;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.util.logging.Level;
importjava.util.logging.Logger;
importjavax.swing.ButtonGroup;
importjavax.swing.JFrame;
importjavax.swing.JMenu;
importjavax.swing.JMenuBar;
importjavax.swing.JPanel;
importjavax.swing.JRadioButtonMenuItem;
importjavax.swing.JTabbedPane;
importjavax.swing.JTextField;
importjavax.swing.SwingUtilities;
importjavax.swing.UIManager;
importjavax.swing.UnsupportedLookAndFeelException;
/** * Displays a TabbedPane with no content with a menu that can switch between * different L&Fs. The tabbed pane header is a custom JPanel with a JTextField. * * Causes a Null Pointer Exception when doing the following: * 1) Start with or switch to Dark/Light Flat Theme * 2) Click on Tab Header -- in the COMPONENT (JTextField) area * 3) Switch to Light/Dark Flat Theme */publicclassFlatTabTest {
/** * @param args the command line arguments */publicstaticvoidmain(String[] args) {
SwingUtilities.invokeLater(newRunnable() {
@Overridepublicvoidrun() {
JFrameapp = newJFrame();
JPanelappPanel = newJPanel(newBorderLayout());
JTabbedPanetabbedPane = newJTabbedPane();
JMenuBarmenuBar = newJMenuBar();
JMenumenu = newJMenu("Theme");
JRadioButtonMenuItemv_noThemeMenuItem = newJRadioButtonMenuItem("Default Theme", true);
v_noThemeMenuItem.addActionListener(newThemeActionListener(UIManager.getCrossPlatformLookAndFeelClassName()));
JRadioButtonMenuItemv_defaultThemeMenuItem = newJRadioButtonMenuItem("System Theme", false);
v_defaultThemeMenuItem.addActionListener(newThemeActionListener(UIManager.getSystemLookAndFeelClassName()));
JRadioButtonMenuItemv_lightFlatLafMenuItem = newJRadioButtonMenuItem("Light Flat Theme", false);
v_lightFlatLafMenuItem.addActionListener(newThemeActionListener("com.formdev.flatlaf.FlatLightLaf"));
JRadioButtonMenuItemv_darkFlatLafMenuItem = newJRadioButtonMenuItem("Dark Flat Theme", false);
v_darkFlatLafMenuItem.addActionListener(newThemeActionListener("com.formdev.flatlaf.FlatDarkLaf"));
menu.add(v_noThemeMenuItem);
menu.add(v_defaultThemeMenuItem);
menu.add(v_lightFlatLafMenuItem);
menu.add(v_darkFlatLafMenuItem);
ButtonGroupthemeButtonGroup = newButtonGroup();
themeButtonGroup.add(v_noThemeMenuItem);
themeButtonGroup.add(v_defaultThemeMenuItem);
themeButtonGroup.add(v_lightFlatLafMenuItem);
themeButtonGroup.add(v_darkFlatLafMenuItem);
menuBar.add(menu);
tabbedPane.add("TEST TAB", newJPanel());
tabbedPane.setTabComponentAt(0, newCustomHeader("TEST TAB"));
appPanel.add(tabbedPane, BorderLayout.CENTER);
appPanel.add(menuBar, BorderLayout.NORTH);
app.setContentPane(appPanel);
app.setSize(newDimension(500, 500));
app.setLocationRelativeTo(null);
app.setVisible(true);
}
});
}
publicstaticvoidthemeChanged(Stringtheme) {
if (UIManager.getLookAndFeel().getClass().getName().equals(theme)) {
return;
}
try {
UIManager.setLookAndFeel(theme);
updateLAFRecursively();
Logger.getLogger(FlatTabTest.class.getName()).log(Level.INFO, "Set Look and Feel {0}", theme);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelExceptione) {
Logger.getLogger(FlatTabTest.class.getName()).log(Level.SEVERE, e.toString(), e);
}
}
/** * Updates the component tree UI for all frames and their children. */privatestaticvoidupdateLAFRecursively() {
for (Windowwindow : Window.getWindows()) {
updateLAFRecursively(window);
}
}
/** * Updates the component tree UI for all windows owned by the given window. * * @param window */privatestaticvoidupdateLAFRecursively(Windowwindow) {
for (WindowchildWindow : window.getOwnedWindows()) {
updateLAFRecursively(childWindow);
}
SwingUtilities.updateComponentTreeUI(window);
}
staticclassCustomHeaderextendsJPanel {
privateJTextFieldlabel;
publicCustomHeader(Stringtitle) {
setLayout(newBorderLayout());
label = newJTextField(title);
add(label, BorderLayout.CENTER);
}
}
staticclassThemeActionListenerimplementsActionListener {
privateStringtheme;
publicThemeActionListener(Stringtheme) {
this.theme = theme;
}
@OverridepublicvoidactionPerformed(ActionEvente) {
themeChanged(theme);
}
}
}
Stack trace:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.basic.BasicTabbedPaneUI.calculateTabHeight(BasicTabbedPaneUI.java:1736)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI.calculateTabHeight(FlatTabbedPaneUI.java:943)
at javax.swing.plaf.basic.BasicTabbedPaneUI.calculateMaxTabHeight(BasicTabbedPaneUI.java:1746)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI.calculateMaxTabHeight(FlatTabbedPaneUI.java:955)
at javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneLayout.calculateTabRects(BasicTabbedPaneUI.java:2590)
at javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneLayout.calculateLayoutInfo(BasicTabbedPaneUI.java:2516)
at javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneLayout.layoutContainer(BasicTabbedPaneUI.java:2411)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI$FlatTabbedPaneLayout.layoutContainer(FlatTabbedPaneUI.java:3012)
at java.awt.Container.layout(Container.java:1513)
at java.awt.Container.doLayout(Container.java:1502)
at java.awt.Container.validateTree(Container.java:1698)
at java.awt.Container.validate(Container.java:1633)
at javax.swing.plaf.basic.BasicTabbedPaneUI.ensureCurrentLayout(BasicTabbedPaneUI.java:1451)
at javax.swing.plaf.basic.BasicTabbedPaneUI.getTabBounds(BasicTabbedPaneUI.java:1471)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI.repaintTab(FlatTabbedPaneUI.java:834)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI.access$6400(FlatTabbedPaneUI.java:181)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI$FlatSelectedTabRepainter.repaintSelectedTab(FlatTabbedPaneUI.java:3636)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI$FlatSelectedTabRepainter.repaintSelectedTabs(FlatTabbedPaneUI.java:3630)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI$FlatSelectedTabRepainter.propertyChange(FlatTabbedPaneUI.java:3614)
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
at java.awt.KeyboardFocusManager.firePropertyChange(KeyboardFocusManager.java:1493)
at java.awt.KeyboardFocusManager.setGlobalPermanentFocusOwner(KeyboardFocusManager.java:780)
at java.awt.Component.removeNotify(Component.java:6999)
at java.awt.Container.removeNotify(Container.java:2823)
at javax.swing.JComponent.removeNotify(JComponent.java:4761)
at javax.swing.text.JTextComponent.removeNotify(JTextComponent.java:1602)
at java.awt.Container.removeNotify(Container.java:2807)
at javax.swing.JComponent.removeNotify(JComponent.java:4761)
at java.awt.Container.removeAll(Container.java:1300)
at javax.swing.plaf.basic.BasicTabbedPaneUI.uninstallTabContainer(BasicTabbedPaneUI.java:348)
at javax.swing.plaf.basic.BasicTabbedPaneUI.uninstallComponents(BasicTabbedPaneUI.java:332)
at com.formdev.flatlaf.ui.FlatTabbedPaneUI.uninstallComponents(FlatTabbedPaneUI.java:465)
at javax.swing.plaf.basic.BasicTabbedPaneUI.uninstallUI(BasicTabbedPaneUI.java:233)
at javax.swing.JComponent.uninstallUIAndProperties(JComponent.java:675)
at javax.swing.JComponent.setUI(JComponent.java:652)
at javax.swing.JTabbedPane.setUI(JTabbedPane.java:231)
at javax.swing.JTabbedPane.updateUI(JTabbedPane.java:247)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1238)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1253)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1229)
The text was updated successfully, but these errors were encountered:
Flatlaf Version: 3.2.1 (also tested with 3.1.1)
Setup: Application has a JTabbedPane with custom Tab Header components. The custom header is a JPanel that includes a JTextField. Application has a theme toggle with FlatLAF and system themes.
Apparent Bug: If the component part of the tab header (i.e., the JTextField) is clicked before switching between Light and Dark Flat themes, a Null Pointer Exception is thrown.
Steps to Reproduce:
Code sample that produces the error:
FlatLaf_NPE_Tabbed_Pane_Example.txt
Stack trace:
The text was updated successfully, but these errors were encountered: