如果我在可见时添加项目,则不会调整 JComboBox 弹出窗口的大小

2022-01-20 00:00:00 popup java swing jcombobox

JComboBox 弹出窗口有问题.我的 JComboBox 有一个类似于 google 搜索框的自动完成实现.

I have a problem with a JComboBox popup. My JComboBox has an autocompletition implementation like google search box.

所以,问题是如果我在弹出窗口可见时添加或删除项目,它没有调整大小,我需要关闭并重新打开它.但是这个火 popupBecomeInvisible 和 popupBecomeVisible ,所以我不能将这个事件用于我真正的 porpouse.

So, the problem is if I add or remove items when popup is visible it is not resized, I need to close and reopen it. But this fire popupBecomeInvisible and popupBecomeVisible and so i can't use this events for my real porpouse.

有一种方法可以根据包含的项目数刷新"弹出窗口大小,而无需关闭并重新打开它?

There is a way to "refresh" popup size in according to count of items that it contains, without close and reopen it?

谢谢.

推荐答案

在包含组合框的面板上调用 revalidate().这将导致组件根据其首选尺寸重新布局.

Invoke revalidate() on the panel containing the combobox. This will cause the components to be layed out again based on their preferred sizes.

这与在可见 GUI 上添加/删除组件的概念相同.

This is the same concept as adding/removing a component on a visible GUI.

只需重新阅读您的问题.我不确定您是否可以在弹出窗口打开时动态调整其大小,但您可以查看 组合框弹出.它向您展示了如何覆盖弹出窗口的首选宽度.此代码在即将显示弹出菜单时执行.但是您也许可以使用这些概念来访问弹出窗口并动态更改宽度.

Just reread your question. I'm not sure if you can dynamically resize the popup when it is open but you can check out Combo Box Popup. It shows you how to override the preferred width of the popup. This code is executed when the popup menu is about to be shown. But you may be able to use the concepts to access the popup and change the width dynamically.

编辑 2:

这是一个展示基本概念的示例.弹出窗口将每 2 秒调整一次宽度.但是,我不知道这是否有助于解决您的问题,因为如果您从弹出窗口中动态添加/删除项目,那么每次弹出窗口更改时您都需要重新创建弹出窗口.这可能会导致弹出窗口隐藏/显示,这意味着无论如何您都需要忍受一点闪烁.

Here is an example that shows the basic concept. The popup will adjust its width every 2 seconds. However, I don't know if this will help with your problem because if you are dynamicallyl adding/removing items from the popup, then you will need to recreate the popup every time the popup is changed. This will probably result in the popup hiding/showing which means you will need to live with a little flicker anyway.

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

public class ComboBoxExample extends JPanel implements ActionListener
{
    private JComboBox comboBox;

    public ComboBoxExample()
    {
        String[] petStrings = { "Select Pet", "Bird", "Cat", "Dog", "Rabbit", "Pig", "Other" };
        comboBox = new JComboBox( petStrings );
        add( comboBox, BorderLayout.PAGE_START );

        Timer timer = new javax.swing.Timer(2000, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        comboBox.showPopup();
        Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
        BasicComboPopup popup = (BasicComboPopup)child;
        JList list = popup.getList();
        Container c = SwingUtilities.getAncestorOfClass(JScrollPane.class, list);
        JScrollPane scrollPane = (JScrollPane)c;

        Dimension size = scrollPane.getSize();

        if (size.width > 20)
            size.width -= 5;

        scrollPane.setPreferredSize(size);
        scrollPane.setMaximumSize(size);

        Dimension popupSize = popup.getSize();
        popupSize.width = size.width;
        Component parent = popup.getParent();
        parent.setSize(popupSize);

        parent.validate();
        parent.repaint();

        Window mainFrame = SwingUtilities.windowForComponent(comboBox);
        Window popupWindow = SwingUtilities.windowForComponent(popup);

        //  For heavy weight popups you need to pack the window

        if (popupWindow != mainFrame)
            popupWindow.pack();
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame( "ComboBoxExample" );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        JComponent newContentPane = new ComboBoxExample();
        newContentPane.setOpaque( true );
        frame.setContentPane( newContentPane );
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

相关文章