I'd like to be able to react when currently highlighted item in a JComboBox
drop down list changes. Note that I'm not looking for a way to get the currently selected item, but the highlighted one. When mouse hovers over this popup it highlights the item at mouse position, but this does not affect currently selected item, so I cannot simply listen via an ItemListener
or ActionListener
to achieve what I want.
I'm trying to create a component which consists of a JComboBox
and a coupled tooltip which displays additional information (documentation) for the currently highlighted item.
As my first attempt I'm adding some code to my constructor (extended JComboBox
):
import java.awt.BorderLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleState;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.ComboPopup;
public class SomeFrame extends JFrame {
private MyComboBox combo;
public SomeFrame() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(100,20);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
combo = new MyComboBox();
combo.setModel(new DefaultComboBoxModel(new String[]{"one", "two", "three", "four"}));
add(combo);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SomeFrame frame = new SomeFrame();
frame.setVisible(true);
}
});
}
// this is the important part
private static class MyComboBox extends JComboBox {
public MyComboBox() {
getAccessibleContext().addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (AccessibleContext.ACCESSIBLE_STATE_PROPERTY.equals(evt.getPropertyName())
&& AccessibleState.FOCUSED.equals(evt.getNewValue())
&& getAccessibleContext().getAccessibleChild(0) instanceof ComboPopup) {
ComboPopup popup = (ComboPopup) getAccessibleContext().getAccessibleChild(0);
JList list = popup.getList();
System.out.println("--> " + String.valueOf(list.getSelectedValue()));
}
}
});
}
}
}
It seems to work, but I got to this code through some shady channels and trial/error, so I'm thinking there has to be a better way of doing it. Any ideas? Is above code even production safe?