Java 阶梯式组合框刷新

Java 阶梯式组合框刷新,java,swing,jcombobox,Java,Swing,Jcombobox,A对于使下拉弹出窗口比文本字段更宽非常有用。但是,当新内容添加到列表中时,弹出窗口将恢复其初始宽度 默认情况下 刷新后(新元素) 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.

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

默认情况下

刷新后(新元素)

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);
    }
}
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.Rectangle;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入java.util.Vector;
导入javax.swing.ComboxModel;
导入javax.swing.DefaultComboxModel;
导入javax.swing.JButton;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.plaf.basic.basicmbopopup;
导入javax.swing.plaf.basic.ComboPopup;
导入javax.swing.plaf.metal.metalcomboxUI;
公共类SteppedComboxRefresh扩展了JFrame{
私人名单;
私有最终步进mbobox组合;
公共SteppedComboxRefresh(){
超级(“步进邮箱刷新”);
this.list=new ArrayList(Arrays.asList)(新字符串[]){
“AAA”,“AAAAA”
}));
this.combo=newsteppedcomboBox(this.list.toArray());
此.combo.setDimensions(50);
JButton addButton=新JButton(“添加更长的字符串”);
addButton.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
list.add(list.get(list.size()-1)+“AAA”);
setModel(新的DefaultComboxModel(list.toArray());
组合设置尺寸(50);
}
});
getContentPane().setLayout(新的FlowLayout());
getContentPane().add(this.combo);
getContentPane().add(添加按钮);
}
公共静态void main(字符串参数[]){
SteppedComboxRefresh f=新的SteppedComboxRefresh();
f、 addWindowListener(新的WindowAdapter(){
@凌驾
公共无效窗口关闭(WindowEvent e){
系统出口(0);
}
});
f、 设置大小(300100);
f、 setVisible(真);
}
}
类SteppedComboxUI扩展了MetalComboxUI{
@凌驾
受保护的ComboPopup createPopup(){
BasicComboPopup=新建BasicComboPopup(this.comboBox){
@凌驾
公开展览({
维度PopusSize=((SteppedComboBox)this.comboBox).GetPopusSize();
PopusSize.setSize(PopusSize.width,
GetPopUpsightForRowCount(this.comboBox.getMaximumRowCount());
矩形PopubBounds=computePopupBounds(0,
this.comboBox.getBounds().height,popupSize.width,popupSize.height);
this.scroller.setMaximumSize(popubbounds.getSize());
this.scroller.setPreferredSize(popubbounds.getSize());
this.scroller.setMinimumSize(popubbounds.getSize());
this.list.invalidate();
int-selectedIndex=this.comboBox.getSelectedIndex();
if(selectedIndex==-1){
this.list.clearSelection();
}否则{
this.list.setSelectedIndex(selectedIndex);
}
this.list.ensureIndexIsVisible(this.list.getSelectedIndex());
setLightWeightPopupEnabled(this.comboBox.isLightWeightPopupEnabled());
显示(this.comboBox,popubbounds.x,popubbounds.y);
}
};
popup.getAccessibleContext().setAccessibleParent(this.comboBox);
返回弹出窗口;
}
}
类SteppedComboBox扩展了JComboBox{
受保护的宽度;
公共步进mbobox(ComboBoxModel aModel){
超级(阿莫代尔);
setUI(新的steppedcomboxui());
this.popuwidth=0;
}
公共步进mbobox(最终对象[]项){
超级(项目);
setUI(新的steppedcomboxui());
this.popuwidth=0;
}
公共步进框(矢量项){
超级(项目);
setUI(新的steppedcomboxui());
this.popuwidth=0;
}
公共void setPopupWidth(整型宽度){
this.popuwidth=宽度;
}
公共维度getPopusSize(){
维度大小=getSize();
if(this.popuwidth<1){
this.popuwidth=size.width;
}
返回新维度(this.popuvWidth、size.height);
}
公共void setDimensions(整型宽度){
维度d=getPreferredSize();
setPreferredSize(新尺寸(宽度、d.高度));
设置PopUpWidth(d.宽度);
}
}

组合框仍使用以前的首选大小。需要将首选大小设置回
null
,以便获得列表中新内容首选的大小

void javax.swing.JComponent.setPreferredSize(维度preferredSize)

设置此组件的首选大小。如果preferredSize为空,则会向UI询问首选大小

结果

您可以使用

它是阶梯式组合框的更灵活版本。最重要的是,它可以用于任何组合框,因为逻辑是在“PopupMenuListener”中实现的

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

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