如何创建一个多层JComboBox

时间:2014-08-13 23:38:27

标签: java swing jcombobox jmenu multi-level

我正在使用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 ......” “ 将会呈现。这些集合是从Enumerations中获取的。我想知道创建这样的组件最正确的方法是什么。

非常感谢你!

3 个答案:

答案 0 :(得分:0)

使用它......

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

答案 1 :(得分:0)

也许使用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();
            }
        });
    }
}

答案 2 :(得分:0)

这是一个自定义弹出窗口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;  
    }  
  }
}