Skip to content

Coping with long items in Roles combobox

Sergey Smolnikov edited this page Mar 3, 2018 · 6 revisions

Role, used for Lambda functions has name and ARN. ARN is pretty long and look like following:

arn:aws:iam::01234567891:role/lambda_basic_execution

Together with name it make combobox items very long:

lambda_basic_execution (arn:aws:iam::01234567891:role/lambda_basic_execution)

And the JComboBox gets a large width:

There are few options how this can be implemented more nice.

  • Replace the combobox with a textbox or label with a current value and open a popup dialog to change it. It is most reliable, but outstanding the current approach - I would keep it as the lest preferable.
  • Extend BasicComboBoxUI and customize its PopUp: workaround in the bug. It did not work well in my case.
  • Enlarge the popup size when it is invoked: example. in some reason did not work either. I could enlarge a width of the popup, but not the width of its containing list:
functionRoles.addPopupMenuListener(new PopupMenuListener() {
    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        JComboBox box = (JComboBox) e.getSource();
        Object comp = box.getUI().getAccessibleChild(box, 0);
        if (!(comp instanceof JPopupMenu))
            return;
        JPopupMenu popupMenu = (JPopupMenu) comp;
        JComponent scrollPane = (JComponent) popupMenu.getComponent(0);
        Dimension size = new Dimension();
        size.width = box.getPreferredSize().width;
        size.height = scrollPane.getPreferredSize().height;
        scrollPane.setPreferredSize(size);
        //  following line for Tiger
        //  scrollPane.setMaximumSize(size);
    }

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {

    }

    @Override
    public void popupMenuCanceled(PopupMenuEvent e) {

    }
});
  • Show only short name in the combobox items and display longer text in a tooltip for individual item: example. I chose this for now - displaying tooltips for individual items within the combobox and set the tooltip on the combobox itself. There is an issue, that a tooltip for an item is drawn within the popup boundaries and it is cut, when it's wider. I consider it as a reasonable solution for now:

private JComboBox functionRoles;
. . .
functionRoles.setRenderer(new JComboBoxItemToolTipRenderer(functionRoles));
. . .
functionRoles.removeAllItems();
for(RoleEntity entity : roles) {
   functionRoles.addItem(new JComboBoxToolTipProviderImpl(entity.getName(), entity.toString()));
}
. . .

public interface JComboBoxToolTipProvider {
    public String getToolTip();
}

public class JComboBoxToolTipProviderImpl implements JComboBoxToolTipProvider {
    final Object value;
    final String toolTip;

    public JComboBoxToolTipProviderImpl(Object value, String toolTip) {
        this.value = value;
        this.toolTip = toolTip;
    }

    @Override
    public String getToolTip() {
        return toolTip;
    }

    @Override
    public String toString() {
        return value.toString();
    }
}

public class JComboBoxItemToolTipRenderer extends DefaultListCellRenderer {
    private final JComboBox comboBox;

    public JComboBoxItemToolTipRenderer(JComboBox comboBox) {
        this.comboBox = comboBox;
    }

    @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 toolTipText = null;
        if (value instanceof JComboBoxToolTipProvider) {
            JComboBoxToolTipProvider toolTipProvider = (JComboBoxToolTipProvider) value;
            toolTipText = toolTipProvider.getToolTip();
        }
        list.setToolTipText(toolTipText);
        comboBox.setToolTipText(toolTipText);
        return component;
    }
}

Clone this wiki locally