Home > Software design >  Multiple column in JComboBox in java swing
Multiple column in JComboBox in java swing

Time:04-05

how to create jcomboBox with two /multiple columns in the drop down let but when we select only one selected value show in Jcombobox

please give me any solution for this .

CodePudding user response:

You might be able to use JList#setLayoutOrientation(JList.VERTICAL_WRAP):

enter image description here

import java.awt.*;
import javax.accessibility.Accessible;
import javax.swing.*;
import javax.swing.plaf.basic.ComboPopup;

public class TwoColumnsDropdownTest {
  private Component makeUI() {
    DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
    model.addElement("111");
    model.addElement("2222");
    model.addElement("3");
    model.addElement("44444");
    model.addElement("55555");
    model.addElement("66");
    model.addElement("777");
    model.addElement("8");
    model.addElement("9999");
    int rowCount = (model.getSize()   1) / 2;
    JComboBox<String> combo = new JComboBox<String>(model) {
      @Override public Dimension getPreferredSize() {
        Insets i = getInsets();
        Dimension d = super.getPreferredSize();
        int w = Math.max(100, d.width);
        int h = d.height;
        int buttonWidth = 20; // ???
        return new Dimension(buttonWidth   w   i.left   i.right, h   i.top   i.bottom);
      }

      @Override public void updateUI() {
        super.updateUI();
        setMaximumRowCount(rowCount);
        setPrototypeDisplayValue("12345");

        Accessible o = getAccessibleContext().getAccessibleChild(0);
        if (o instanceof ComboPopup) {
          JList<?> list = ((ComboPopup) o).getList();
          list.setLayoutOrientation(JList.VERTICAL_WRAP);
          list.setVisibleRowCount(rowCount);
          list.setFixedCellWidth((getPreferredSize().width - 2) / 2);
        }
      }
    };
    JPanel p = new JPanel();
    p.add(combo);
    return p;
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      frame.getContentPane().add(new TwoColumnsDropdownTest().makeUI());
      frame.setSize(320, 240);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
    });
  }
}

CodePudding user response:

You need to do a few things.

By default, what is displayed in the JComboBox, as the selected item, is the value returned by method toString of the items in the ComboBoxModel. Based on your comment I wrote an Item class and overrode the toString method.

In order to display something different in the drop-down list, you need a custom ListCellRenderer.

In order for the drop-down list to display the entire details of each item, the drop-down list needs to be wider than the JComboBox. I used code from the following SO question to achieve that:
How can I change the width of a JComboBox dropdown list?

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.math.BigDecimal;
import java.text.NumberFormat;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicComboPopup;

public class MultiColumnCombo implements PopupMenuListener {
    private JComboBox<Item>  combo;

    public void popupMenuCanceled(PopupMenuEvent event) {
        // Do nothing.
    }

    public void popupMenuWillBecomeInvisible(PopupMenuEvent event) {
        // Do nothing.
    }

    public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
        AccessibleContext comboAccessibleContext = combo.getAccessibleContext();
        int comboAccessibleChildrenCount = comboAccessibleContext.getAccessibleChildrenCount();
        if (comboAccessibleChildrenCount > 0) {
            Accessible comboAccessibleChild0 = comboAccessibleContext.getAccessibleChild(0);
            if (comboAccessibleChild0 instanceof BasicComboPopup) {
                EventQueue.invokeLater(() -> {
                    BasicComboPopup comboPopup = (BasicComboPopup) comboAccessibleChild0;
                    JScrollPane scrollPane = (JScrollPane) comboPopup.getComponent(0);
                    Dimension d = setCurrentDimension(scrollPane.getPreferredSize());
                    scrollPane.setPreferredSize(d);
                    scrollPane.setMaximumSize(d);
                    scrollPane.setMinimumSize(d);
                    scrollPane.setSize(d);
                    Point location = combo.getLocationOnScreen();
                    int height = combo.getPreferredSize().height;
                    comboPopup.setLocation(location.x, location.y   height - 1);
                    comboPopup.setLocation(location.x, location.y   height);
                });
            }
        }
    }

    private void createAndDisplayGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createCombo());
        frame.setSize(450, 300);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createCombo() {
        JPanel panel = new JPanel();
        Item[] items = new Item[]{new Item("A", "Item A", new BigDecimal(1.99d), new BigDecimal(2.99d)),
                                  new Item("B", "Item B", new BigDecimal(7.5d), new BigDecimal(9.0d)),
                                  new Item("C", "Item C", new BigDecimal(0.25d), new BigDecimal(3.15d))};
        combo = new JComboBox<>(items);
        AccessibleContext comboAccessibleContext = combo.getAccessibleContext();
        int comboAccessibleChildrenCount = comboAccessibleContext.getAccessibleChildrenCount();
        if (comboAccessibleChildrenCount > 0) {
            Accessible comboAccessibleChild0 = comboAccessibleContext.getAccessibleChild(0);
            if (comboAccessibleChild0 instanceof BasicComboPopup) {
                BasicComboPopup comboPopup = (BasicComboPopup) comboAccessibleChild0;
                comboPopup.getList().setCellRenderer(new MultiColumnRenderer());
            }
        }
        combo.addPopupMenuListener(this);
        panel.add(combo);
        return panel;
    }

    private Dimension setCurrentDimension(Dimension dim) {
        Dimension d = new Dimension(dim);
        d.width = 120;
        return d;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new MultiColumnCombo().createAndDisplayGui());
    }
}

class Item {
    private String  code;
    private String  name;
    private BigDecimal  price;
    private BigDecimal  salePrice;

    public Item(String code, String name, BigDecimal price, BigDecimal salePrice) {
        this.code = code;
        this.name = name;
        this.price = price;
        this.salePrice = salePrice;
    }

    public String displayString() {
        return String.format("%s %s %s %s",
                             code,
                             name,
                             NumberFormat.getCurrencyInstance().format(price),
                             NumberFormat.getCurrencyInstance().format(salePrice));
    }

    public String toString() {
        return name;
    }
}

class MultiColumnRenderer implements ListCellRenderer<Object> {

    /** Component returned by method {@link #getListCellRendererComponent}. */
    private JLabel  cmpt;

    public MultiColumnRenderer() {
        cmpt = new JLabel();
        cmpt.setOpaque(true);
        cmpt.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    }

    public Component getListCellRendererComponent(JList<? extends Object> list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus) {
        String text;
        if (value == null) {
            text = "";
        }
        else {
            if (value instanceof Item) {
                text = ((Item) value).displayString();
            }
            else {
                text = value.toString();
            }
        }
        cmpt.setText(text);
        if (isSelected) {
            cmpt.setBackground(list.getSelectionBackground());
            cmpt.setForeground(list.getSelectionForeground());
        }
        else {
            cmpt.setBackground(list.getBackground());
            cmpt.setForeground(list.getForeground());
        }
        cmpt.setFont(list.getFont());
        return cmpt;
    }
}
  • Related