Stepped ComboBox刷新

时间:2015-07-10 15:22:32

标签: java swing jcombobox

Stepped ComboBox对于使下拉弹出窗口比文本字段更宽,非常有用。但是,当新内容添加到列表中时,弹出窗口会返回其初始宽度。

默认情况下

enter image description here

刷新后(新元素)

enter image description here

SSCCE

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;

public class SteppedComboBoxRefresh extends JFrame {
    private List<String> list;
    private final SteppedComboBox combo;

    public SteppedComboBoxRefresh() {
        super("SteppedComboBox Refresh");

        this.list = new ArrayList<String>(Arrays.asList(new String[]{
                "AAA", "AAAAAA"
        }));

        this.combo = new SteppedComboBox(this.list.toArray());
        this.combo.setDimensions(50);

        JButton addButton = new JButton("Add longer string");
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                list.add(list.get(list.size()-1) + "AAA");
                combo.setModel(new DefaultComboBoxModel(list.toArray()));
                combo.setDimensions(50);
            }
        });

        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(this.combo);
        getContentPane().add(addButton);
    }

    public static void main (String args[]) {
        SteppedComboBoxRefresh f = new SteppedComboBoxRefresh();
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.setSize (300, 100);
        f.setVisible(true);
    }
}

class SteppedComboBoxUI extends MetalComboBoxUI {
    @Override
    protected ComboPopup createPopup() {
        BasicComboPopup popup = new BasicComboPopup( this.comboBox ) {

            @Override
            public void show() {
                Dimension popupSize = ((SteppedComboBox)this.comboBox).getPopupSize();
                popupSize.setSize( popupSize.width,
                        getPopupHeightForRowCount( this.comboBox.getMaximumRowCount() ) );
                Rectangle popupBounds = computePopupBounds( 0,
                        this.comboBox.getBounds().height, popupSize.width, popupSize.height);
                this.scroller.setMaximumSize( popupBounds.getSize() );
                this.scroller.setPreferredSize( popupBounds.getSize() );
                this.scroller.setMinimumSize( popupBounds.getSize() );
                this.list.invalidate();
                int selectedIndex = this.comboBox.getSelectedIndex();
                if ( selectedIndex == -1 ) {
                    this.list.clearSelection();
                } else {
                    this.list.setSelectedIndex( selectedIndex );
                }
                this.list.ensureIndexIsVisible( this.list.getSelectedIndex() );
                setLightWeightPopupEnabled( this.comboBox.isLightWeightPopupEnabled() );

                show( this.comboBox, popupBounds.x, popupBounds.y );
            }
        };
        popup.getAccessibleContext().setAccessibleParent(this.comboBox);
        return popup;
    }
}

class SteppedComboBox extends JComboBox {
    protected int popupWidth;

    public SteppedComboBox(ComboBoxModel aModel) {
        super(aModel);
        setUI(new SteppedComboBoxUI());
        this.popupWidth = 0;
    }

    public SteppedComboBox(final Object[] items) {
        super(items);
        setUI(new SteppedComboBoxUI());
        this.popupWidth = 0;
    }

    public SteppedComboBox(Vector items) {
        super(items);
        setUI(new SteppedComboBoxUI());
        this.popupWidth = 0;
    }

    public void setPopupWidth(int width) {
        this.popupWidth = width;
    }

    public Dimension getPopupSize() {
        Dimension size = getSize();
        if (this.popupWidth < 1) {
            this.popupWidth = size.width;
        }
        return new Dimension(this.popupWidth, size.height);
    }

    public void setDimensions(int width) {
        Dimension d = getPreferredSize();
        setPreferredSize(new Dimension(width, d.height));
        setPopupWidth(d.width);
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用Combo Box Popup

这是Stepped Combo Box的一个更灵活的版本。最重要的是它可以在任何组合框中使用,因为逻辑是在'PopupMenuListener&#39;中实现的。

您可以控制弹出窗口的最大宽度。您甚至可以在组合框上方而不是下方显示弹出窗口。

答案 1 :(得分:0)

ComboBox仍然使用其先前的PreferredSize。需要将首选大小设置回null,以便我们获得列表中新内容首选的大小。

  

void javax.swing.JComponent.setPreferredSize(Dimension preferredSize)

     

设置此组件的首选大小。如果preferredSize为null,则会要求UI提供首选大小。

public void setDimensions(int width) {
    setPreferredSize(null);
    Dimension d = getPreferredSize();
    setPreferredSize(new Dimension(width, d.height));
    setPopupWidth(d.width);
}

结果

enter image description here