Change JCombobox popup width [duplicate]
Asked Answered
T

1

0

How can I set a fixed width of a JComboboxs popup-menu that is using GridBagLayout and fill=HORIZONTAL?

One of the things I tried is to just override the getSize() method but dose not work.

public class ComboBoxSize extends JFrame {
    public static void main(String args[]) {

        // THE COMBOBOX
        String labels[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
        JComboBox<String> comboBox = new JComboBox<String>(labels) {
            public Dimension getSize() {
                Dimension d = getPreferredSize();
                d.width = 50;
                return d;
            }
        };
        comboBox.setMaximumRowCount(comboBox.getModel().getSize());

        // ADD COMBOBOX TO PANEL
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(comboBox, c);

        // ADD PANEL TO FRAME
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}
Thanatos answered 8/1, 2014 at 12:21 Comment(4)
don't forget to call pack() for popup after sizing is doneMclain
@StanislavL I'm think that Rob has very good workaround tooMclain
The easiest way to force the width is by passing a value to setPrototypeDisplayValue, which doesn't let you specify an exact size in pixels, but it's much cleaner, and it's not good UI practice to set a component's size in pixels anyway.Outlandish
Seems to be a duplicate. The other question is working nice on my example but not my main project. Seems like the problem is on my side.Thanatos
G
0

Here is the solution, this worked for me, add this PopupMenuListener to your JComboBox:

import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.ComboPopup;

public class CustomComboBoxPopupMenuListener implements PopupMenuListener {
    // ==============================================================================
    // Members
    // ==============================================================================
    private int bgTop = 0;
    private int bgLeft = 0;
    private int bgRight = 0;
    private int bgBottom = 0;

    // ==============================================================================
    // Constructors
    // ==============================================================================
    public CustomComboBoxPopupMenuListener() {
        super();
    }

    // ==============================================================================
    // Methods
    // ==============================================================================
    public void popupMenuCanceled(PopupMenuEvent e) {

    }

    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {

    }

    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        final JComboBox box = (JComboBox) e.getSource();
        final Object comp = box.getUI().getAccessibleChild(box, 0);
        if (!(comp instanceof JPopupMenu)) {
            return;
        }
        final JPopupMenu popupMenu = (JPopupMenu) comp;
        popupMenu.setBorder(null);
        if (popupMenu.getComponent(0) instanceof JScrollPane) {
        final JScrollPane scrollPane = (JScrollPane) popupMenu
                .getComponent(0);
        scrollPane.setBorder(BorderFactory.createEmptyBorder(bgTop, bgLeft,
                bgBottom, bgRight));
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        if (popupMenu instanceof ComboPopup) {
            final ComboPopup popup = (ComboPopup) popupMenu;
            final JList list = popup.getList();
            list.setBorder(null);
            final Dimension size = list.getPreferredSize();
            size.width = Math.max(box.getPreferredSize().width + bgLeft
                    + bgRight, box.getWidth());
            size.height = Math.min(scrollPane.getPreferredSize().height
                    + bgTop + bgBottom, size.height + bgTop + bgBottom);
            scrollPane.setPreferredSize(size);
            scrollPane.setMaximumSize(size);
        }
    }
}
}

Example in your code:

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ComboBoxSize extends JFrame {
public static void main(String args[]) {

    // THE COMBOBOX
    String labels[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
    JComboBox<String> comboBox = new JComboBox<String>(labels);
    comboBox.setMaximumRowCount(comboBox.getModel().getSize());
    comboBox.addPopupMenuListener(new CustomComboBoxPopupMenuListener());
    // ADD COMBOBOX TO PANEL
    JPanel panel = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.weightx = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    panel.add(comboBox, c);

    // ADD PANEL TO FRAME
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(panel);
    frame.setSize(300, 200);
    frame.setVisible(true);
}
}

Source: click here

Gut answered 8/1, 2014 at 13:21 Comment(4)
You really should format your codeOlfactory
OK did it. Code is formatted now.Gut
This solution are giving me a space after the scrollbar: imgur.com/WR8oi73Thanatos
Change these field initialization in PopupMenuListener class:- private int bgTop = 0; private int bgLeft = 0; private int bgRight = 0; private int bgBottom = 0; This will resolve your issue. Updated my answer.Gut

© 2022 - 2024 — McMap. All rights reserved.