In Swing, is there a way to define mouseover text (or tool tip text) for each item in a JComboBox?
There is a much better way to do this than the ToolTipComboBox
answer already given.
First, make a custom ListCellRenderer
:
package com.example;
import javax.swing.*;
import java.awt.*;
import java.util.List;
public class ComboboxToolTipRenderer extends DefaultListCellRenderer {
List<String> tooltips;
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JComponent comp = (JComponent) super.getListCellRendererComponent(list,
value, index, isSelected, cellHasFocus);
if (-1 < index && null != value && null != tooltips) {
list.setToolTipText(tooltips.get(index));
}
return comp;
}
public void setTooltips(List<String> tooltips) {
this.tooltips = tooltips;
}
}
Then use it like this:
JComboBox comboBox = new JComboBox();
ComboboxToolTipRenderer renderer = new ComboboxToolTipRenderer();
comboBox.setRenderer(renderer);
...
//make a loop as needed
comboBox.addItem(itemString);
tooltips.add(tooltipString);
...
renderer.setTooltips(tooltips);
I like the simplicity of MountainX's solution but not the lack of encapsulation. An alternate solution which has more moving parts, but they are pretty simple and reusable.
An interface:
public interface ToolTipProvider {
public String getToolTip();
}
A wrapper class:
public class ToolTipWrapper implements ToolTipProvider {
final Object value;
final String toolTip;
public ToolTipWrapper(Object value, String toolTip) {
this.value = value;
this.toolTip = toolTip;
}
@Override
public String getToolTip() {
return toolTip;
}
@Override
public String toString() {
return value.toString();
}
}
And a variant of MountainX's renderer:
public class ToolTipRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JComponent component = (JComponent) super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
String tip = null;
if (value instanceof ToolTipProvider) {
ToolTipProvider ttp = (ToolTipProvider) value;
tip = ttp.getToolTip();
}
list.setToolTipText(tip);
return component;
}
}
with the adding now:
combobox.addItem(new ToolTipWrapper(itemString,tooltipString) );
Here's little bit fixed code from an online example:
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
/**
* @version 1.0 06/05/99
*/
public class ToolTipComboBox extends JFrame {
/**
*
*/
private static final long serialVersionUID = 2939624252688908292L;
String[] items = { "jw", "ja", "la" };
String[] tooltips = { "Javanese ", "Japanese ", "Latin " };
public ToolTipComboBox() {
super("ToolTip ComboBox Example");
JComboBox combo = new JComboBox(items);
combo.setRenderer(new MyComboBoxRenderer());
getContentPane().setLayout(new FlowLayout());
getContentPane().add(combo);
}
class MyComboBoxRenderer extends BasicComboBoxRenderer {
/**
*
*/
private static final long serialVersionUID = 2746090194775905713L;
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
if (-1 < index) {
list.setToolTipText(tooltips[index]);
}
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setFont(list.getFont());
setText((value == null) ? "" : value.toString());
return this;
}
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
ToolTipComboBox frame = new ToolTipComboBox();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setSize(200, 140);
frame.setVisible(true);
}
}
If your combo box is not editable, use setRenderer(ListCellRenderer)
. If it is editable, use setEditor(ComboBoxEditor)
, because:
The renderer is used if the JComboBox is not editable. If it is editable, the editor is used to render and edit the selected item.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With