调整组合框的弹出窗口

Resize Popup of a Combobox

我的筛选组合框中还有一个问题。我尝试使用 setPreferredSize 方法从组合框中调整弹出窗口的大小。它工作正常,但底部的边框也没有调整大小。我已经尝试添加新边框,但没有结果。

如何调整组合框弹出窗口的大小?

    package de.ccw.reports.gui.incomingOrder.MyComboBox;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.text.JTextComponent;

import de.ccw.commons.ui.comp.XComboBox;

public class FilterableComboBox<E> extends XComboBox<E> {

    ComboBoxModel<E> originalModel;
    DefaultComboBoxModel<E> filteredModel;

    JTextComponent editorComp;
    String filterBkp = "";
    JList<E> list;
    BasicComboPopup popup;

    public FilterableComboBox(ComboBoxModel<E> aModel) {
        super();
        // setEditor(new BasicComboBoxEditor());
        receivePopupList();
        originalModel = aModel;

        filteredModel = new DefaultComboBoxModel<>();
        setModel(filteredModel);

        editorComp = (JTextComponent) getEditor().getEditorComponent();
        editorComp.addFocusListener(new FocusAdapter() {

            @Override
            public void focusLost(FocusEvent e) {
                System.out.println("focusLostStart=" + getSelectedItem() + "|"
                        + editorComp.getText());

                String text = editorComp.getText();
                editorComp.setText("");
                setSelectedItem(null);

                if (list.getSelectedIndex() != -1 && text.isEmpty() == false) {
                    setSelectedIndex(list.getSelectedIndex());
                    editorComp.setText(getSelectedItem().toString());
                }

                System.out.println("focusLostEnd=" + getSelectedItem() + "|"
                        + editorComp.getText());
            }

            @Override
            public void focusGained(FocusEvent e) {
                System.out.println("focusGainedStart=" + getSelectedItem()
                        + "|" + editorComp.getText());
                E element = getSelectedItem();
                String text = editorComp.getText();
                performModelFilter(null);
                showPopup();
                setSelectedItem(element);
                editorComp.setText(text);
                filterBkp = text;
                editorComp.selectAll();
                System.out.println("focusGainedEnd=" + getSelectedItem() + "|"
                        + editorComp.getText());
            }

        });
        editorComp.addKeyListener(new KeyAdapter() {

            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent e) {

                if (e.getKeyCode() != KeyEvent.VK_DOWN
                        && e.getKeyCode() != KeyEvent.VK_UP) {
                    String filter = editorComp.getText();

                    System.out.println("keyReleased-" + filterBkp + filter);

                    if (filter.equals(filterBkp) == false)
                        refreshModel();

                    filterBkp = filter;
                } else {
                    editorComp.selectAll();
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {
            }
        });

        setEditable(true);
    }

    @SuppressWarnings("unchecked")
    private void receivePopupList() {
        popup = (BasicComboPopup) getAccessibleContext()
                .getAccessibleChild(0);
        list = popup.getList();
        popup.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                validate();
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                // TODO DB Auto-generated method stub

            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
                // TODO DB Auto-generated method stub

            }
        });
    }

    private void refreshModel() {

        String filter = editorComp.getText();

        performModelFilter(filter);

        editorComp.setText(filter);

    }

    private void performModelFilter(String filter) {
        System.out.println("performModelFilter-" + filter);

        filteredModel.removeAllElements();

        for (int i = 0; i < originalModel.getSize(); i++) {
            E element = originalModel.getElementAt(i);
            String value = element.toString().toUpperCase();
            if (filter == null || value.contains(filter.toUpperCase())) {
                filteredModel.addElement(element);
            }
        }

        Dimension prefSize = new Dimension();
        prefSize.height = list.getPreferredSize().height+2;
        prefSize.width = getPreferredSize().width;
        popup.setPreferredSize(prefSize);
        popup.revalidate();
        popup.validate();
        popup.pack();
//      list.revalidate();
//      editorComp.revalidate();
//      revalidate();
        System.out.println("List=" + list.getPreferredSize());
        System.out.println("Popup=" + popup.getPreferredSize());
        System.out.println("ComboBox=" + getPreferredSize());
    }

    public static void main(String args[]) {
        FilterableComboBox<String> combo = new FilterableComboBox<>(
                new DefaultComboBoxModel<>(new String[] { "abc", "def", "ghi",
                        "jkl", "mnoabc", "pqrdef" }));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.add(new JTextField(20));
        frame.add(combo);
        frame.add(new JTextField(20));
        frame.pack();
        frame.setVisible(true);
    }

}
  • get/cast Window 来自 BasicComboPopup(你的代码已经完成了一半),这里是 (J)Component returns getPreferredSize(调整大小后的 pack() 在运行时已经可见 Window

  • 使用setPrototypeDisplayValue("I'm using String from max value from max pixels value - String height")

  • 可以覆盖 XxxListCellRenderer 中的 get/setPreferredSize,但这与良好实践无关

  • 再次使用标准 AutoCompleted JComboBox/JTextField 之一,没有来自 KeyListener

  • 的 listening/filtering 通知程序