单击两次时自定义 JComboBox 不关闭

Custom JComboBox not closing when clicked twice

如题所示,我创建的是自定义的JComboBox,写的时候自定义的BasicComboPopup不隐藏popup.hide();此外,如果你们知道制作 JComboBox 的更简单方法,该方法在主要组件中显示缩写值,但在弹出窗口中显示未缩写的内容,我会洗耳恭听。这是我的代码:

     import javax.swing.JComboBox;
     import java.awt.event.MouseEvent;
     import java.awt.event.MouseAdapter;
     import javax.swing.JFrame;
     import java.awt.GridBagLayout;
     import java.awt.Component;
     import java.awt.Container;
     import javax.swing.JButton;
     import java.awt.event.ActionListener;
     import java.awt.event.ActionEvent;
     import javax.swing.JPopupMenu;
     import javax.swing.plaf.basic.BasicComboPopup;

     class ChangingCombos extends JFrame
     {
        String[] abbrStr = new String[]{"--","TF","FF","SP"};
        String[] longStr = new String[]{"-Select One-","Thermo Film","Fashion Film","Specialty"};
        AbbreviatedComboBox<String> box = new AbbreviatedComboBox<String>(longStr,abbrStr);

        public ChangingCombos()
        {
           setLayout(new GridBagLayout());
           add(box);
           setDefaultCloseOperation(EXIT_ON_CLOSE);
           setLocation(300,300);
           pack();
           setVisible(true);
        }

        public static void main(String[]args)
        {
           new ChangingCombos();
        }

        class AbbreviatedComboBox<E> extends JComboBox<E>
        {
           E[] items = null;
           E[] abbreviations = null;
           BasicComboPopup popup = null;
           JComboBox self = this;
           JComboBox<E> abstractBox;

           public AbbreviatedComboBox(E[] items, E[] abbreviations)
           {
              super(abbreviations);
              this.items = items;
              this.abbreviations = abbreviations;
              abstractBox = new JComboBox<E>(items);
              popup = new BasicComboPopup(abstractBox);
              addCustomMouseListener(this);
              for(Component c: GUIUtilities.getAllSubcomponentsOf(this))addCustomMouseListener(c);

           }

           private void addCustomMouseListener(Component c)
           {
              c.addMouseListener(new MouseAdapter()
              {
                 public void mousePressed(MouseEvent e)
                 {
                    System.out.println("ohp");
                    if(!popup.isVisible())
                    {
                       popup.show(self,0,self.getHeight());
                    }
                    else popup.hide();
                 }
              });
           }
        }
     }

...另外,为了解释 GUIUtilities,它是另一个自定义 class 和方法 getAllSubcomponentsOf(Container c) 递归 returns 所述容器中包含的所有组件。这是我访问 JComboBox 上的小箭头按钮的快捷方式。将多个侦听器添加到同一对象似乎会产生问题,但它只会迭代一次操作,正如 System.out.println("ohp") 每次点击仅打印一次所验证的那样。

编辑:setVisible(false) 不起作用。我指的隐藏方法是ComboPopup.hide();它没有被弃用。当我执行 abstractBox.hidePopup() 时,它什么也没做,因为 abstractBox 没有显示在屏幕上,而且从来没有打算显示。只是它的弹出窗口。继续努力。

尝试使用 popup.hidePopup(); 我认为 .hide(); 已被弃用。

查看 this 了解有关当前方法的更多详细信息。

并且 this 了解为什么旧版本被弃用。

还有一个替代方法。你可以打电话给 popup.setVisible(false);

a simpler way of making a JComboBox that shows abbreviated values in the main component, but the un-abbreviated content in the popup

您将自定义对象存储在包含两个属性的 ComboBoxModel 中:

  1. 值 - 用于在您的程序中处理
  2. 描述 - 用于在组合框中显示

然后您可以为组合框使用自定义渲染器来显示描述值。

查看 ComboBox With Custom Renderer 了解更多信息和此方法的代码示例。

您还可以查看 Combo Box Prompt,它允许您在不将项目存储在 ComboBoxModel 中的情况下提示输入值。您需要将此解决方案合并到上述示例的渲染器中。

编辑:

可能我误解了你的要求。这是一个简单的示例,它以不同于组合框中显示的方式呈现下拉列表:

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

public class ComboBoxRenderer extends JPanel
{
    public ComboBoxRenderer()
    {
        String[] items = { "Red", "Green", "Blue" };
        JComboBox<String> comboBox = new JComboBox<String>( items );
        comboBox.setSelectedIndex(-1);
        comboBox.setPrototypeDisplayValue( "Select Color" );
        comboBox.setRenderer( new MyRenderer() );

        add(comboBox, BorderLayout.NORTH );
    }

    class MyRenderer extends BasicComboBoxRenderer
    {
        public Component getListCellRendererComponent(
            JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

            if (value == null)
                value = "Select Color";

            if (index == -1 && value != null)
            {
                setText(value.toString());
            }
            else
                setText(index + " : " + value);

            return this;
        }
    }

    private static void createAndShowGUI()
    {

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ComboBoxRenderer());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

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

这就是我最终使用的。

  import javax.swing.border.LineBorder;
  import java.awt.Dimension;
  import java.awt.event.ItemEvent;
  import java.awt.event.ItemListener;
  import javax.swing.JComboBox;
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseListener;
  import java.awt.Component;
  import javax.swing.JButton;
  import javax.swing.plaf.basic.BasicComboPopup;

  class AbbreviatedComboBox<E> extends JComboBox<E> implements MouseListener, ItemListener
  {
     AbbreviatedComboBox<E> self = this;
     E[] items = null;
     E[] abbreviations = null;
     JComboBox<E> abstractBox = null;
     BasicComboPopup popup = null;
     JButton comboBoxButton = null;
     int maximumRowCount = 0;

     public AbbreviatedComboBox(E[] items, E[] abbreviations)
     {
        super(abbreviations);
        this.items = items;
        this.abbreviations = abbreviations;
        abstractBox = new JComboBox<E>(items);
        new JComboBoxRowCountRetreival();
        popup = new BasicComboPopup(abstractBox);
        for(Component c: getComponents())if(c instanceof JButton)comboBoxButton = (JButton)c;
        for(MouseListener l: getMouseListeners())removeMouseListener(l);
        for(MouseListener l: comboBoxButton.getMouseListeners())comboBoxButton.removeMouseListener(l);
        addMouseListener(this);
        comboBoxButton.addMouseListener(this);
        abstractBox.addItemListener(this);
        popup.setPreferredSize(new Dimension(popup.getPreferredSize().width,popup.getPreferredSize().height/maximumRowCount*items.length+popup.getMargin().top+popup.getMargin().bottom+(((LineBorder)popup.getBorder()).getThickness()*2)));
        popup.addMouseListener(this);
     }

     public void itemStateChanged(ItemEvent e)
     {
        for(int i = 0; i < items.length; i++)if(items[i].equals(e.getItem()))setSelectedIndex(i);
        popup.hide();
     }

     public void mousePressed(MouseEvent e)
     {
        requestFocusInWindow();
        if(!popup.isVisible())
        {
           popup.show(this,0,getHeight());
        }
        else 
        {
           popup.hide();
        }
     }

     public void mouseReleased(MouseEvent e){}
     public void mouseClicked(MouseEvent e){}
     public void mouseEntered(MouseEvent e){}
     public void mouseExited(MouseEvent e){}

     class JComboBoxRowCountRetreival extends JComboBox
     {
        public JComboBoxRowCountRetreival()
        {
           super();
           self.maximumRowCount = super.maximumRowCount;
        }
     }
  }