动态JComboBox尺寸

3

我有一个 JComboBox 包含了很长的 Strings,使得我的GUI占用了太多空间。我只需要在选择时看到完整的长度。所以,我希望 JComboBox 只在全尺寸时显示其完整长度,在其他情况下缩短。

以下代码似乎可行。但由于我是一个Java新手,我想知道是否有更好或更标准的方法来实现这个功能。

谢谢。

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class DynamicJComboBox{
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setLayout(new FlowLayout());
        frame.setSize(250, 100);

        JComboBox box = new JComboBox();
        box.addItem("Really Long Line Number One");
        box.addItem("Really Long Line Number Two");
        box.addItem("Really Long Line Number Three");
        box.addItem("Really Long Line Number Four");
        box.setPreferredSize(new Dimension(100, 30));
        box.addPopupMenuListener (new PopupMenuListener() {
            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {}

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                box.setSize(100,30);
            }
            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                box.setSize(200,30);    
            }
        });
        frame.add(box);
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception exc) {}

        SwingUtilities.invokeLater(() -> {
        createAndShowGUI();
        });
    }
}
2个回答

3
以下代码似乎可以工作。
实际上并不是这样,因为您更改了组合框的大小,这将导致组合框覆盖在其右侧显示的任何组件上。此外,组合框箭头绘制在组合框的中间。
请查看组合框弹出。该解决方案还使用了PopupMenuListener(因此您走在了正确的道路上),但它仅在显示弹出窗口时增加了弹出窗口的宽度,而不是组合框的宽度。

有趣的是,你提到的问题在我的实际 GUI 中并没有发生,只是在我在这里发布的简化版本中出现了。但是,我还是转而采用了你的建议,因为它更加灵活。谢谢。 - Greg Valvo
仅供我的学习体验,为什么popupMenuWillBecomeVisible会重新安排customizePopup方法在Swing事件线程上运行?我本以为popupMenuWillBecomeVisible已经在该线程上运行了。 - Greg Valvo
@GregValvo,是的,它正在运行EDT上。我不记得具体情况了,但也许问题在于尺寸还没有确定,因为菜单实际上还没有显示出来,所以我需要确保代码在尺寸已经确定之后执行,这样我才能覆盖它们。invokeLater()将自定义代码添加到EDT的末尾。 - camickr

0

enter image description here

一个小技巧,使得弹出菜单的大小足够大,即使组合框的大小可能较小

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

    import java.awt.Dimension;
    import java.util.Vector;

    import javax.swing.ComboBoxModel;
    import javax.swing.JComboBox;

    public class ComboBoxFullMenu<E> extends JComboBox<E> {

        public ComboBoxFullMenu(E[] items) {
            super(items);
            addActionListener(this);
        }

        public ComboBoxFullMenu(Vector<E> items) {
            super(items);
            addActionListener(this);
        }

        public ComboBoxFullMenu(ComboBoxModel<E> aModel) {
            super(aModel);
            addActionListener(this);
        }

        /**
         * Small hack to get pop up menu size bigger enough to show items even though
         * the combo box size could be smaller
         * */
        private boolean layingOut = false; 

        @Override
        public void doLayout(){ 
            try{ 
                layingOut = true; 
                super.doLayout(); 
            }finally{ 
                layingOut = false; 
            } 
        } 

        @Override
        public Dimension getSize(){ 
            Dimension dim = super.getSize(); 
            if ( !layingOut ) {
                dim.width = Math.max(dim.width, getPreferredSize().width);
            }
            return dim; 
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接