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

时间:2015-11-21 23:33:18

标签: java user-interface popup jcombobox

正如标题所示,我正在创建一个自定义的JComboBox,当我编写popup.hide()时,自定义的BasicComboPopup不会隐藏;另外,如果你们知道一个更简单的方法来制作一个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,它是另一个自定义类,方法getAllSubcomponentsOf(Container c)递归地返回所述容器中包含的所有组件。这是我访问JComboBox上的小箭头按钮的快捷方式。看起来它可能会在向同一个对象添加多个侦听器时产生问题,但它只会迭代一次该操作,正如System.out.println("ohp")每次点击仅打印一次所证实的那样。

修改:setVisible(false)不起作用。我引用的隐藏方法是ComboPopup.hide();它没有被弃用。当我执行abstractBox.hidePopup()时,它不执行任何操作,因为abstractBox未在屏幕上显示,并且从未打算过。只是它的弹出窗口。继续尝试。

3 个答案:

答案 0 :(得分:1)

  

制作JComboBox的简单方法,在主要组件中显示缩写值,但弹出窗口中未缩写的内容

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

  1. 值 - 用于程序中的处理
  2. description - 用于在组合框中显示
  3. 然后,您可以使用组合框的自定义渲染器来显示描述值。

    查看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();
                }
            });
        }
    }
    

答案 1 :(得分:0)

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

检查this以获取有关当前方法的更多详细信息。

并且this说明为什么旧的不推荐使用。

还有另一种方法。你可以拨打popup.setVisible(false);

答案 2 :(得分:0)

这是我最终使用的结果。

  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;
        }
     }
  }