How can I change the width of a JComboBox dropdown list?

后端 未结 6 2041
自闭症患者
自闭症患者 2020-11-30 04:19

I have an editable JComboBox which contains a list of single letter values. Because of that the combobox is very small.

Every letter has a special mean

相关标签:
6条回答
  • 2020-11-30 04:22

    I believe the only way to do this with the public API is to write a custom UI (there are two bugs dealing with this).

    If you just want something quick-and-dirty, I found this way to use implementation details to do it (here):

    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        JComboBox box = (JComboBox) e.getSource();
        Object comp = box.getUI().getAccessibleChild(box, 0);
        if (!(comp instanceof JPopupMenu)) return;
        JComponent scrollPane = (JComponent) ((JPopupMenu) comp).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);
    }
    

    Put this in a PopupMenuListener and it might work for you.

    Or you could use the code from the first linked bug:

    class StyledComboBoxUI extends BasicComboBoxUI {
      protected ComboPopup createPopup() {
        BasicComboPopup popup = new BasicComboPopup(comboBox) {
          @Override
          protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
            return super.computePopupBounds(
                px,py,Math.max(comboBox.getPreferredSize().width,pw),ph
            );
          }
        };
        popup.getAccessibleContext().setAccessibleParent(comboBox);
        return popup;
      }
    }
    
    class StyledComboBox extends JComboBox {
      public StyledComboBox() {
        setUI(new StyledComboBoxUI());
      }
    }
    
    0 讨论(0)
  • 2020-11-30 04:26

    You might want to use setSize() method.

    combo.setSize(200, combo.getPreferredSize().height);
    
    0 讨论(0)
  • 2020-11-30 04:31

    Here is a great solution by Santhosh Kumar, without the need to mess with UI's and other nasty stuff like that!

    http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough

    import javax.swing.*; 
    import java.awt.*; 
    import java.util.Vector; 
    
    // got this workaround from the following bug: 
    //      http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4618607 
    public class WideComboBox extends JComboBox{ 
    
        public WideComboBox() { 
        } 
    
        public WideComboBox(final Object items[]){ 
            super(items); 
        } 
    
        public WideComboBox(Vector items) { 
            super(items); 
        } 
    
            public WideComboBox(ComboBoxModel aModel) { 
            super(aModel); 
        } 
    
        private boolean layingOut = false; 
    
        public void doLayout(){ 
            try{ 
                layingOut = true; 
                    super.doLayout(); 
            }finally{ 
                layingOut = false; 
            } 
        } 
    
        public Dimension getSize(){ 
            Dimension dim = super.getSize(); 
            if(!layingOut) 
                dim.width = Math.max(dim.width, getPreferredSize().width); 
            return dim; 
        } 
    }
    
    0 讨论(0)
  • 2020-11-30 04:33

    Sounds like you'll need to write your own ComboBoxUI.

    There is a good example here that shows how to accomplish this.

    Also note, the method you would probably be interested in is the createPopup() method. This is the method that creates the popup for the combo box and where you would be able to customize it.

    0 讨论(0)
  • 2020-11-30 04:38

    Here you have a simple piece of code without extends JComboBox nor other any class

    In this example the with of drop down is 500 always. You also can modify the height or the location.

            FaceCorrectiveReasonComboBox.getTextComponent().setUI(new BasicComboBoxUI() {
                @Override protected ComboPopup createPopup() {
                    return new BasicComboPopup(comboBox) {
                        protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
                            return super.computePopupBounds(px, py, 500, ph);
                        }                       
                    };
                }
            });
    
    0 讨论(0)
  • 2020-11-30 04:46

    Here is a nice solution from tutiez.

    Before setting up the Dimension of popup list, it gets the biggest item from it and calculated the width needed to show it completely.

    public class WiderDropDownCombo extends JComboBox {
    
        private String type;
        private boolean layingOut = false;
        private int widestLengh = 0;
        private boolean wide = false;
    
        public WiderDropDownCombo(Object[] objs) {
            super(objs);
        }
    
        public boolean isWide() {
            return wide;
        }
    
        // Setting the JComboBox wide
        public void setWide(boolean wide) {
            this.wide = wide;
            widestLengh = getWidestItemWidth();
    
        }
    
        public Dimension getSize() {
            Dimension dim = super.getSize();
            if (!layingOut && isWide())
                dim.width = Math.max(widestLengh, dim.width);
            return dim;
        }
    
        public int getWidestItemWidth() {
    
            int numOfItems = this.getItemCount();
            Font font = this.getFont();
            FontMetrics metrics = this.getFontMetrics(font);
            int widest = 0;
            for (int i = 0; i < numOfItems; i++) {
                Object item = this.getItemAt(i);
                int lineWidth = metrics.stringWidth(item.toString());
                widest = Math.max(widest, lineWidth);
            }
    
            return widest + 5;
        }
    
        public void doLayout() {
            try {
                layingOut = true;
                super.doLayout();
            } finally {
                layingOut = false;
            }
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String t) {
            type = t;
        }
    
        public static void main(String[] args) {
            String title = "Combo Test";
            JFrame frame = new JFrame(title);
    
            String[] items = {
                    "I need lot of width to be visible , oh am I visible now",
                    "I need lot of width to be visible , oh am I visible now" };
            WiderDropDownCombo simpleCombo = new WiderDropDownCombo(items);
            simpleCombo.setPreferredSize(new Dimension(180, 20));
            simpleCombo.setWide(true);
            JLabel label = new JLabel("Wider Drop Down Demo");
    
            frame.getContentPane().add(simpleCombo, BorderLayout.NORTH);
            frame.getContentPane().add(label, BorderLayout.SOUTH);
            int width = 200;
            int height = 150;
            frame.setSize(width, height);
            frame.setVisible(true);
    
        }
    }
    

    The code above has already a main for a quick test. But notice that the statement below may be adjusted to around 20 if you want to have a vertical scroll.

    return widest + 5;
    

    Hope it is useful for future reference!

    0 讨论(0)
提交回复
热议问题