Samitha Chathuranga
Samitha Chathuranga

Reputation: 1749

How to reduce the default size(height of a item) of a Combo box in SWT?

The size of the combo box I created by swt has a fixed size(height of a item cannot be changed). Is there any way to change this default height.? Even thought I tried by reducing the font size of items, but no success.

Upvotes: 0

Views: 1321

Answers (2)

18446744073709551615
18446744073709551615

Reputation: 16832

There is one more trick that can be done: you can specify a border with zero or negative top and bottom insets for your combo box. What you get will depend on the look-and-feel that you use (and on the font too). For some look-and-feels there is no problem with the height of combo boxes (or, one could say, all controls share the same problem, they all waste screen space, not just combo boxes). You have to subclass DefaultListCellRenderer.

In the image below, no artifacts are visible: the trick may be not so bad

But in the next image, there are problems (note that zero insets are ok): The trick with custom border

It is safe to specify zero insets, but this gives you only 2 px. It may be ok to specify negative insets if you use uppercase text without diacritic signs and do no plan any internationalization-localization. In the general case, negative insets do not work because the space that they let you use is reserved for some purpose, like diacritic signs above capital letters. It just may happen that with the text that you use the space below the baseline and above the cap height is not needed and may be reused.

Note that some kinds of strings do not require internationalization, for example: mathematical functions and constants (e.g. cos), chemical elements (e.g. Ca for calcium), software product and component names (e.g. GTK, Ubuntu). So this very particular case that all combo box options are in uppercase Latin (and therefore negative insets may be used) may happen in practice.

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;

class HelloWorldSwing {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("ComboBox With Custom EmptyBorder");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        frame.getContentPane().add(panel);


        String[] items = {"BQbdgqpSŚń", "foo", "bar", "baz", "qux"};
        panel.add(new JLabel("1,1 (standard):"));
        panel.add(new JComboBox<>(items));
        panel.add(new JLabel("0,0:"));
        panel.add(new LowComboBox<>(items, 0, 0));
        panel.add(new JLabel("-1,-3:"));
        panel.add(new LowComboBox<>(items, -1, -3));
        panel.add(new JLabel("-2,-2:"));
        panel.add(new LowComboBox<>(items, -2, -2));

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(HelloWorldSwing::createAndShowGUI);
    }
}

class LowComboBox<T> extends JComboBox<T> {
    public LowComboBox(T[] items, int top, int bottom) {
        super(items);
        setRenderer(new LowComboboxToolTipRenderer(top, bottom));
    }

    static class LowComboboxToolTipRenderer extends DefaultListCellRenderer {
        private final EmptyBorder standardBorder = new EmptyBorder(1, 1, 1, 1);
        private final EmptyBorder customBorder;

        public LowComboboxToolTipRenderer(int top, int bottom) {
            customBorder = new EmptyBorder(top, 1, bottom, 1);
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                                                      int index, boolean isSelected, boolean cellHasFocus) {
            JComponent component = (JComponent) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (isBorderTrickNeeded()) {
                if (index < 0) {
                    component.setBorder(customBorder);
                } else {
                    component.setBorder(standardBorder);
                }
            }
            return component;
        }

        static boolean isBorderTrickNeeded() {
            // Check for look-and-feels that benefit from low combo boxes.
            // The Motif and GTK look-and-feels are not among them.
            return "Metal".equals(UIManager.getLookAndFeel().getName());
        }
    }
}

Upvotes: 0

R&#252;diger Herrmann
R&#252;diger Herrmann

Reputation: 20985

The short answer is: you cannot explicitly set the height of a combo item.

Like all SWT widgets, the Combo box uses the native widget of the OS/Window system and hence is restricted to the respecive widgets capabilities. On Windows the item height adapts to the font size

combo.setFont( new Font( combo.getDisplay(), "Arial", 27, SWT.NONE ) ); Combo with arge font

combo.setFont( new Font( combo.getDisplay(), "Arial", 7, SWT.NONE ) ); Combo with small font

But other platforms may only adapt to a certain degree or not adapt at all.

Upvotes: 2

Related Questions