-
Bug
-
Resolution: Fixed
-
P3
-
6
-
b96
-
x86
-
windows_xp
Consider this example of a pattern used regularly in the Windows UI classes (this example taken from WindowsComboBoxUI:
public void installUI( JComponent c ) {
if (XPStyle.getXP() != null && arrowButton != null) {
rolloverListener = new RolloverListener();
comboBox.addMouseListener(rolloverListener);
arrowButton.addMouseListener(rolloverListener);
}
}
public void uninstallUI(JComponent c ) {
if (XPStyle.getXP() != null) {
comboBox.removeMouseListener(rolloverListener);
arrowButton.removeMouseListener(rolloverListener);
}
}
Stuff is installed if XPStyle.getXP() != null and uninstalled if XPStyle.getXP() != null. So what happens if XPStyle.getXP() != null on install but == null in uninstall? Bogus stuff gets left around and exceptions happen. But how can this be happen? It turns out that getXP() returns null if the current theme is WindowsClassicLookAndFeel.
As such, switching from WindowsLookAndFeel to WindowsClassicLookAndFeel causes this exact scenario.
Try the following test case. Switch the combobox from Windows to Classic. Now move the mouse over the combobox and watch for exceptions.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.regex.*;
public class LAFTest extends JFrame implements ActionListener {
private JComboBox lafCombo;
public LAFTest() {
super("LAFTest");
lafCombo = new JComboBox(new String[] {"Windows", "Classic"});
lafCombo.addActionListener(this);
JPanel bottom = new JPanel();
bottom.add(lafCombo);
getContentPane().add(bottom, BorderLayout.SOUTH);
changeLAF();
}
public void actionPerformed(ActionEvent ae) {
changeLAF();
}
private void changeLAF() {
Object val = lafCombo.getSelectedItem();
String className = null;
if (val == "Windows") {
className = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
} else {
className = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";
}
try {
UIManager.setLookAndFeel(className);
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UIManager.put("swing.boldMetal", Boolean.FALSE);
LAFTest test = new LAFTest();
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.pack();
test.setLocationRelativeTo(null);
test.setVisible(true);
}
});
}
}
public void installUI( JComponent c ) {
if (XPStyle.getXP() != null && arrowButton != null) {
rolloverListener = new RolloverListener();
comboBox.addMouseListener(rolloverListener);
arrowButton.addMouseListener(rolloverListener);
}
}
public void uninstallUI(JComponent c ) {
if (XPStyle.getXP() != null) {
comboBox.removeMouseListener(rolloverListener);
arrowButton.removeMouseListener(rolloverListener);
}
}
Stuff is installed if XPStyle.getXP() != null and uninstalled if XPStyle.getXP() != null. So what happens if XPStyle.getXP() != null on install but == null in uninstall? Bogus stuff gets left around and exceptions happen. But how can this be happen? It turns out that getXP() returns null if the current theme is WindowsClassicLookAndFeel.
As such, switching from WindowsLookAndFeel to WindowsClassicLookAndFeel causes this exact scenario.
Try the following test case. Switch the combobox from Windows to Classic. Now move the mouse over the combobox and watch for exceptions.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.regex.*;
public class LAFTest extends JFrame implements ActionListener {
private JComboBox lafCombo;
public LAFTest() {
super("LAFTest");
lafCombo = new JComboBox(new String[] {"Windows", "Classic"});
lafCombo.addActionListener(this);
JPanel bottom = new JPanel();
bottom.add(lafCombo);
getContentPane().add(bottom, BorderLayout.SOUTH);
changeLAF();
}
public void actionPerformed(ActionEvent ae) {
changeLAF();
}
private void changeLAF() {
Object val = lafCombo.getSelectedItem();
String className = null;
if (val == "Windows") {
className = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
} else {
className = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";
}
try {
UIManager.setLookAndFeel(className);
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UIManager.put("swing.boldMetal", Boolean.FALSE);
LAFTest test = new LAFTest();
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.pack();
test.setLocationRelativeTo(null);
test.setVisible(true);
}
});
}
}
- duplicates
-
JDK-6458667 NPE from WindowsComboBoxUI$RolloverListener.mouseEntered(WindowsComboBoxUI.java:287)
- Closed