【问题标题】:How to create a multi-layer JComboBox如何创建多层 JComboBox
【发布时间】:2014-08-13 23:38:27
【问题描述】:

我正在使用 Java Swing 创建一个模拟器。我使用 JComboBox 显示公用事业单位,例如“KW、KL、KM”等来测量功率、水和距离。将一堆项目添加到 JComboBox 很简单。用户选择一个单位,当单击“保存”按钮时,JFrame 将保存选择。

    JComboBox comboBox = new JComboBox();
    for(ValueUnits u: ValueUnits.values()){
        comboBox.addItem(u.returnUnits());
    }

    comboBox.setSelectedIndex(-1);
    unitColumn.setCellEditor(new DefaultCellEditor(comboBox));

现在我想创建一个多层 JComboBox(也许是 JMenu?)。这样的功能应该表现为多层JMenu。单击 JComboBox 时,将显示第一层 - 类别,例如“电、水、距离...”,然后当鼠标悬停在电上时,会显示电单位列表,例如“KW、MW、W ... “ 将会呈现。这些集合是从枚举中获取的。我想知道创建此类组件的最正确方法是什么。

非常感谢世界!

【问题讨论】:

    标签: java swing jcombobox jmenu multi-level


    【解决方案1】:

    也许使用 2 个组合框?也就是说,您在第一个中选择一个值,然后在第二个中显示单位:

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    
    public class ComboBoxTwo extends JPanel implements ActionListener
    {
        private JComboBox<String> mainComboBox;
        private JComboBox<String> subComboBox;
        private Hashtable<String, String[]> subItems = new Hashtable<String, String[]>();
    
        public ComboBoxTwo()
        {
            String[] items = { "Select Item", "Color", "Shape", "Fruit" };
            mainComboBox = new JComboBox<String>( items );
            mainComboBox.addActionListener( this );
    
            //  prevent action events from being fired when the up/down arrow keys are used
            mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
            add( mainComboBox );
    
            //  Create sub combo box with multiple models
    
            subComboBox = new JComboBox<String>();
            subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
            add( subComboBox );
    
            String[] subItems1 = { "Select Color", "Red", "Blue", "Green" };
            subItems.put(items[1], subItems1);
    
            String[] subItems2 = { "Select Shape", "Circle", "Square", "Triangle" };
            subItems.put(items[2], subItems2);
    
            String[] subItems3 = { "Select Fruit", "Apple", "Orange", "Banana" };
            subItems.put(items[3], subItems3);
        }
    
        public void actionPerformed(ActionEvent e)
        {
            String item = (String)mainComboBox.getSelectedItem();
            Object o = subItems.get( item );
    
            if (o == null)
            {
                subComboBox.setModel( new DefaultComboBoxModel() );
            }
            else
            {
                subComboBox.setModel( new DefaultComboBoxModel( (String[])o ) );
            }
        }
    
        private static void createAndShowUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( new ComboBoxTwo() );
            frame.setLocationByPlatform( true );
            frame.pack();
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }
    

    【讨论】:

    • 感谢 camickr!这正是我想要的。
    【解决方案2】:

    使用它...

    public class ComboLayer extends javax.swing.JPanel {
    
    String Category1 = null;
    String Category2 = null;
    String Category3 = null;
    Hashtable<String, String> hsItems;
    
    
    public ComboLayer() {
        this.hsItems = new Hashtable<>();
    
        hsItems.put("Main", "Power,Water,Distance");
        hsItems.put("Power", "KW,MW,W");
        hsItems.put("Water", "ML,L,KL");
        hsItems.put("Distance", "CM,M,KM");
        initComponents();
        String[] item = hsItems.get("Main").split(",");
        for (String i : item) {
            cmbItem.addItem(i);
        }
        cmbItem.addItem("Back");
        cmbItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String selectText = null;
                selectText = (String) cmbItem.getSelectedItem();
                Enumeration enmKeys = hsItems.keys();
                while (enmKeys.hasMoreElements()) {
                    String sKey = (String) enmKeys.nextElement();
                    if (selectText.equalsIgnoreCase("back")) {
                        if (hsItems.get(sKey).contains(cmbItem.getItemAt(0).toString())) {
                            Enumeration enumkeysBack = hsItems.keys();
                            while (enumkeysBack.hasMoreElements()) {
                                String sKeyBack = (String) enumkeysBack.nextElement();
                                if (hsItems.get(sKeyBack).contains(sKey)) {
                                    String[] item = hsItems.get(sKeyBack).split(",");
                                    cmbItem.removeAllItems();
                                    for (String i : item) {
                                        cmbItem.addItem(i);
                                    }
                                    if (!sKeyBack.equalsIgnoreCase("Main")) {
                                        cmbItem.addItem("Back");
                                    }
                                     break;
                                }
    
                            }
                        }
                    } else if (sKey.contains(selectText)) {
                        String[] item = hsItems.get(sKey).split(",");
                        cmbItem.removeAllItems();
                        for (String i : item) {
                            cmbItem.addItem(i);
                        }
                        if (!sKey.equalsIgnoreCase("Main")) {
                            cmbItem.addItem("Back");
                        }
                        break;
                    }
                }
    
            }
        });
    }
    
    public static void main(String... arg) {
        ComboLayer cmbLyr = new ComboLayer();
        JDialog dg = new JDialog();
        dg.add(cmbLyr);
        dg.setVisible(true);
    }
    

    【讨论】:

      【解决方案3】:

      这是一个具有JMenu 的自定义弹出窗口效果的组合。实际的弹出窗口被隐藏,并在适当的时候显示第二个弹出窗口。

      选择JMenuItem 后,组合中将仅填充一项,以面包屑格式显示。

      import java.awt.*;
      import java.awt.event.*;
      import java.util.*;
      import java.util.List;
      import javax.swing.*;
      import javax.swing.border.*;
      import javax.swing.plaf.basic.*;
      import javax.swing.plaf.metal.*;
      
      public class JMenuComboBoxDemo implements Runnable
      {
        private Map<String, String[]> menuData;
        private JComboBox<String> combo;
        private AbstractButton arrowButton;
        private JPopupMenu popupMenu;
        private List<String> flattenedData;
      
        public static void main(String[] args)
        {
          SwingUtilities.invokeLater(new JMenuComboBoxDemo());
        }
      
        public JMenuComboBoxDemo()
        {
          menuData = new HashMap<String, String[]>();
          menuData.put("Colors",  new String[]{"Black", "Blue"});
          menuData.put("Flavors", new String[]{"Lemon", "Lime"});
      
          popupMenu = new JPopupMenu();
          popupMenu.setBorder(new MatteBorder(1, 1, 1, 1, Color.DARK_GRAY));
      
          List<String> categories = new ArrayList<String>(menuData.keySet());
          Collections.sort(categories);
      
          // copy of the menuData, flattened into a List
          flattenedData = new ArrayList<String>();
      
          for (String category : categories)
          {
            JMenu menu = new JMenu(category);
            for (String itemName : menuData.get(category))
            {
              menu.add(createMenuItem(itemName));
              flattenedData.add(category + " > " + itemName);
            }
            popupMenu.add(menu);
          }
      
          combo = new JComboBox<String>();
          combo.setPrototypeDisplayValue("12345678901234567890");
          combo.setUI(new EmptyComboBoxUI());
      
          for (Component comp : combo.getComponents())
          {
            if (comp instanceof AbstractButton)
            {
              arrowButton = (AbstractButton) comp;
            }
          }
      
          arrowButton.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent event)
            {
              setPopupVisible(! popupMenu.isVisible());
            }
          });
      
          combo.addMouseListener(new MouseAdapter()
          {
            @Override
            public void mouseClicked(MouseEvent e)
            {
              setPopupVisible(! popupMenu.isVisible());
            }
          });
        }
      
        public void run()
        {
          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          Container c = frame.getContentPane();
          c.setLayout(new FlowLayout());
          c.add(new JLabel("Options"));
          c.add(combo);
      
          frame.setSize(300, 200);
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
        }
      
        /*
         * Toggle the visibility of the custom popup.
         */
        private void setPopupVisible(boolean visible)
        {
          if (visible)
          {
            popupMenu.show(combo, 0, combo.getSize().height);
          }
          else
          {
            popupMenu.setVisible(false);
          }
        }
      
        /*
         * Create a JMenuItem whose listener will display
         * the item in the combo.
         */
        private JMenuItem createMenuItem(final String name)
        {
          JMenuItem item = new JMenuItem(name);
          item.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent event)
            {
              setComboSelection(name);
            }
          });
          return item;
        }
      
        /*
         * Search for the given name in the flattened list of menu items.
         * If found, add that item to the combo and select it.
         */
        private void setComboSelection(String name)
        {
          Vector<String> items = new Vector<String>();
      
          for (String item : flattenedData)
          {
            /*
             * We're cheating here: if two items have the same name
             * (Fruit->Orange and Color->Orange, for example)
             * the wrong one may get selected. This should be more sophisticated
             * (left as an exercise to the reader)
             */
            if (item.endsWith(name))
            {
              items.add(item);
              break;
            }
          }
      
          combo.setModel(new DefaultComboBoxModel<String>(items));
      
          if (items.size() == 1)
          {
            combo.setSelectedIndex(0);
          }
        }
      
        /*
         * Prevents the default popup from being displayed
         */
        class EmptyComboBoxUI extends MetalComboBoxUI  
        {
          @Override
          protected ComboPopup createPopup()  
          {  
            BasicComboPopup thePopup = (BasicComboPopup) super.createPopup();  
            thePopup.setPreferredSize(new Dimension(0,0));  // oh, the horror!
            return thePopup;  
          }  
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-14
        • 1970-01-01
        • 2012-01-10
        • 1970-01-01
        • 2021-11-19
        • 2021-11-29
        • 1970-01-01
        • 2015-10-16
        相关资源
        最近更新 更多