java swing多列自动完成combobox

我需要有效的产品项目搜索GUI到销售点应用程序,目前我在文本字段中使用弹出窗口,它包含到表格但效率不高。

在我的弹出窗口中只显示产品代码我需要显示其他产品细节,如CODE,类别,名称,价格等..以确定正确的产品。 ![在此处输入图像说明] [1]

以下图片是我的要求。

//////////////////////////////我有编辑mr.splungebob的答案来构建AutoCompleatecombobox,但它有List>过滤的问题请查看代码并帮助我开发它。

以下是我为回答// DetailedConboBox而添加的代码

/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package test; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Point; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.ComboPopup; import javax.swing.plaf.metal.MetalComboBoxUI; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /** * * @author WARRWijesinghe */ public class DetailedComboBox extends JComboBox { public static enum Alignment { LEFT, RIGHT } private List<List> tableData; private String[] columnNames; private int[] columnWidths; private int displayColumn; private Alignment popupAlignment = Alignment.LEFT; /** * Construct a TableComboBox object */ public DetailedComboBox(String[] colNames, int[] colWidths, int displayColumnIndex) { super(); this.columnNames = colNames; this.columnWidths = colWidths; this.displayColumn = displayColumnIndex; setUI(new TableComboBoxUI()); setEditable(true); this.setSelectedIndex(-1); JTextField field = (JTextField) this.getEditor().getEditorComponent(); field.setText(""); field.addKeyListener(new ComboKeyHandler(this)); } /** * Set the type of alignment for the popup table */ public void setPopupAlignment(Alignment alignment) { popupAlignment = alignment; } /** * Populate the combobox and drop-down table with the supplied data. If the * supplied List is non-null and non-empty, it is assumed that the data is a * List of Lists to be used for the drop-down table. The combobox is also * populated with the column data from the column defined by * displayColumn. */ public void setTableData(List<List> tableData) { this.tableData = (tableData == null ? new ArrayList<List>() : tableData); // even though the incoming data is for the table, we must also // populate the combobox's data, so first clear the previous list. removeAllItems(); // then load the combobox with data from the appropriate column Iterator<List> iter = this.tableData.iterator(); while (iter.hasNext()) { List rowData = iter.next(); addItem(rowData.get(displayColumn)); } } public List getSelectedRow() { return tableData.get(getSelectedIndex()); } public List getRowAt(int row) { return tableData.get(row); } /** * The handler for the combobox's components */ private class TableComboBoxUI extends MetalComboBoxUI { /** * Create a popup component for the ComboBox */ @Override protected ComboPopup createPopup() { return new TableComboPopup(comboBox, this); } /** * Return the JList component */ public JList getList() { return listBox; } } /** * The drop-down of the combobox, which is a JTable instead of a JList. */ private class TableComboPopup extends BasicComboPopup implements ListSelectionListener, ItemListener { private final JTable table; private TableComboBoxUI comboBoxUI; private PopupTableModel tableModel; private JScrollPane scroll; // private JList list = new JList(); // private ListSelectionListener selectionListener; // private ItemListener itemListener; /** * Construct a popup component that's a table */ public TableComboPopup(JComboBox combo, TableComboBoxUI ui) { super(combo); this.comboBoxUI = ui; tableModel = new PopupTableModel(); table = new JTable(tableModel); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.getTableHeader().setReorderingAllowed(false); TableColumnModel tableColumnModel = table.getColumnModel(); tableColumnModel.setColumnSelectionAllowed(false); for (int index = 0; index = 0 && column < columnNames.length) { columnName = columnNames[column].toString(); } return (columnName == null) ? super.getColumnName(column) : columnName; } } } class ComboKeyHandler extends KeyAdapter { private final DetailedComboBox comboBox; // private final Vector list = new Vector(); private final List<List> list = new ArrayList(); public ComboKeyHandler(DetailedComboBox combo) { this.comboBox = combo; for (int i = 0; i < comboBox.getModel().getSize(); i++) { List rowData = combo.getRowAt(i); // name.setText(rowData.get(1).toString()); // capital.setText(rowData.get(2).toString()); list.add(rowData); // list.addElement((String) comboBox.getItemAt(i)); } } private boolean shouldHide = false; @Override public void keyTyped(final KeyEvent e) { EventQueue.invokeLater(new Runnable() { @Override public void run() { String text = ((JTextField) e.getSource()).getText(); System.out.println(text); if (text.length() == 0) { setSuggestionModel(comboBox, list, ""); comboBox.hidePopup(); } else { List<List> m = getSuggestedModel(list, text); if (m.isEmpty() || shouldHide) { comboBox.hidePopup(); } else { setSuggestionModel(comboBox, m, text); comboBox.showPopup(); } } } }); } @Override public void keyPressed(KeyEvent e) { JTextField textField = (JTextField) e.getSource(); String text = textField.getText(); shouldHide = false; switch (e.getKeyCode()) { case KeyEvent.VK_RIGHT: for (Iterator<List> it = list.iterator(); it.hasNext();) { if (!it.next().contains("How")) { it.remove(); // NOTE: Iterator's remove method, not ArrayList's, is used. } return; } /* * for (String s : list { if (s.startsWith(text)) { * textField.setText(s); return; } } * */ break; case KeyEvent.VK_ENTER: if (!list.contains(text)) { list.add(new ArrayList(Arrays.asList(text, "a", "a"))); //setSuggestionModel(comboBox, new DefaultComboBoxModel(list), text); setSuggestionModel(comboBox, getSuggestedModel(list, text), text); } shouldHide = false; break; case KeyEvent.VK_ESCAPE: shouldHide = true; break; default: break; } } private static void setSuggestionModel(DetailedComboBox comboBox, List<List> newList, String str) { comboBox.setTableData(newList); comboBox.setSelectedIndex(-1); ((JTextField) comboBox.getEditor().getEditorComponent()).setText(str); } private static List<List> getSuggestedModel(List<List> list, String text) { List<List> m = new ArrayList(); for (Iterator<List> it = list.iterator(); it.hasNext();) { if (!it.next().contains(text)) { it.remove(); // NOTE: Iterator's remove method, not ArrayList's, is used. } m = (List<List>) it; } return m; /* * for (String s : list) { if (s.startsWith(text)) { m.addElement(s); } * } return m; * */ } }

// DetailedComboBoxDemo

  /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package test; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.*; /** * * @author WARRWijesinghe */ public class DetailedComboBoxDemo implements Runnable { private DetailedComboBox combo; private JTextField name; private JTextField capital; @Override public void run() { List<List> tableData = new ArrayList(); tableData.add(new ArrayList( Arrays.asList("MD", "Maryland", "Annapolis"))); tableData.add(new ArrayList( Arrays.asList("NH", "New Hampshire", "Concord"))); tableData.add(new ArrayList( Arrays.asList("NJ", "New Jersey", "Trenton"))); tableData.add(new ArrayList( Arrays.asList("NM", "New Mexico", "Santa Fe"))); tableData.add(new ArrayList( Arrays.asList("ND", "North Dakota", "Bismark"))); String[] columns = new String[]{"State", "Name", "Capital"}; int[] widths = new int[]{50, 100, 100}; combo = new DetailedComboBox(columns, widths, 0); combo.setTableData(tableData); combo.setSelectedIndex(-1); combo.setPopupAlignment(DetailedComboBox.Alignment.LEFT); combo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { showDetails(); } }); name = new JTextField(10); capital = new JTextField(10); name.setEditable(false); capital.setEditable(false); JPanel p = new JPanel(new FlowLayout()); p.add(new JLabel("State")); p.add(combo); p.add(new JLabel("Name")); p.add(name); p.add(new JLabel("Capital")); p.add(capital); JFrame frame = new JFrame("DetailedComboBox Demo"); frame.getContentPane().add(p, BorderLayout.CENTER); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } private void showDetails() { List rowData = combo.getSelectedRow(); name.setText(rowData.get(1).toString()); capital.setText(rowData.get(2).toString()); } public static void main(String[] args) { SwingUtilities.invokeLater(new DetailedComboBoxDemo()); } } 

这是一个JComboBox,它使用JTable来下拉而不是JList。 你需要给它表数据(列表列表)而不是通常的。 对不起,没有自动完成。

我多年来一直在使用它。 它有效,但我没有做出任何承诺。 哎呀,实验中可能还有一些死代码。 这只是我多年来从不同代码样本中抓取的不同想法的混合物。 我确信还有改进的余地。

DetailedComboBox:

 import java.awt.*; import java.awt.event.*; import java.util.*; import java.util.List; import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.basic.*; import javax.swing.plaf.metal.*; import javax.swing.table.*; /** * A JComboBox that has a JTable as a drop-down instead of a JList */ public class DetailedComboBox extends JComboBox { public static enum Alignment {LEFT, RIGHT} private List> tableData; private String[] columnNames; private int[] columnWidths; private int displayColumn; private Alignment popupAlignment = Alignment.LEFT; /** * Construct a TableComboBox object */ public DetailedComboBox(String[] colNames, int[] colWidths, int displayColumnIndex) { super(); this.columnNames = colNames; this.columnWidths = colWidths; this.displayColumn = displayColumnIndex; setUI(new TableComboBoxUI()); setEditable(false); } /** * Set the type of alignment for the popup table */ public void setPopupAlignment(Alignment alignment) { popupAlignment = alignment; } /** * Populate the combobox and drop-down table with the supplied data. * If the supplied List is non-null and non-empty, it is assumed that * the data is a List of Lists to be used for the drop-down table. * The combobox is also populated with the column data from the * column defined by displayColumn. */ public void setTableData(List> tableData) { this.tableData = (tableData == null ? new ArrayList>() : tableData); // even though the incoming data is for the table, we must also // populate the combobox's data, so first clear the previous list. removeAllItems(); // then load the combobox with data from the appropriate column Iterator> iter = this.tableData.iterator(); while (iter.hasNext()) { List rowData = iter.next(); addItem(rowData.get(displayColumn)); } } public List getSelectedRow() { return tableData.get(getSelectedIndex()); } /** * The handler for the combobox's components */ private class TableComboBoxUI extends MetalComboBoxUI { /** * Create a popup component for the ComboBox */ @Override protected ComboPopup createPopup() { return new TableComboPopup(comboBox, this); } /** * Return the JList component */ public JList getList() { return listBox; } } /** * The drop-down of the combobox, which is a JTable instead of a JList. */ private class TableComboPopup extends BasicComboPopup implements ListSelectionListener, ItemListener { private final JTable table; private TableComboBoxUI comboBoxUI; private PopupTableModel tableModel; private JScrollPane scroll; // private JList list = new JList(); // private ListSelectionListener selectionListener; // private ItemListener itemListener; /** * Construct a popup component that's a table */ public TableComboPopup(JComboBox combo, TableComboBoxUI ui) { super(combo); this.comboBoxUI = ui; tableModel = new PopupTableModel(); table = new JTable(tableModel); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.getTableHeader().setReorderingAllowed(false); TableColumnModel tableColumnModel = table.getColumnModel(); tableColumnModel.setColumnSelectionAllowed(false); for (int index = 0; index < table.getColumnCount(); index++) { TableColumn tableColumn = tableColumnModel.getColumn(index); tableColumn.setPreferredWidth(columnWidths[index]); } scroll = new JScrollPane(table); scroll.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); ListSelectionModel selectionModel = table.getSelectionModel(); selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); selectionModel.addListSelectionListener(this); combo.addItemListener(this); table.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent event) { Point p = event.getPoint(); int row = table.rowAtPoint(p); comboBox.setSelectedIndex(row); hide(); } }); table.setBackground(UIManager.getColor("ComboBox.listBackground")); table.setForeground(UIManager.getColor("ComboBox.listForeground")); } /** * This method is overridden from BasicComboPopup */ @Override public void show() { if (isEnabled()) { super.removeAll(); int scrollWidth = table.getPreferredSize().width + ((Integer) UIManager.get("ScrollBar.width")).intValue() + 1; int scrollHeight = comboBoxUI.getList(). getPreferredScrollableViewportSize().height; scroll.setPreferredSize(new Dimension(scrollWidth, scrollHeight)); super.add(scroll); ListSelectionModel selectionModel = table.getSelectionModel(); selectionModel.removeListSelectionListener(this); selectRow(); selectionModel.addListSelectionListener(this); int scrollX = 0; int scrollY = comboBox.getBounds().height; if (popupAlignment == Alignment.RIGHT) { scrollX = comboBox.getBounds().width - scrollWidth; } show(comboBox, scrollX, scrollY); } } /** * Implemention of ListSelectionListener */ public void valueChanged(ListSelectionEvent event) { comboBox.setSelectedIndex(table.getSelectedRow()); } /** * Implemention of ItemListener */ public void itemStateChanged(ItemEvent event) { if (event.getStateChange() != ItemEvent.DESELECTED) { ListSelectionModel selectionModel = table.getSelectionModel(); selectionModel.removeListSelectionListener(this); selectRow(); selectionModel.addListSelectionListener(this); } } /** * Sync the selected row of the table with the selected row of the combo. */ private void selectRow() { int index = comboBox.getSelectedIndex(); if (index != -1) { table.setRowSelectionInterval(index, index); table.scrollRectToVisible(table.getCellRect(index, 0, true)); } } } /** * A model for the popup table's data */ private class PopupTableModel extends AbstractTableModel { /** * Return the # of columns in the drop-down table */ public int getColumnCount() { return columnNames.length; } /** * Return the # of rows in the drop-down table */ public int getRowCount() { return tableData == null ? 0 : tableData.size(); } /** * Determine the value for a given cell */ public Object getValueAt(int row, int col) { if (tableData == null || tableData.size() == 0) { return ""; } return tableData.get(row).get(col); } /** * All cells in the drop-down table are uneditable */ @Override public boolean isCellEditable(int row, int col) { return false; } /** * Pull the column names out of the tableInfo object for the header */ @Override public String getColumnName(int column) { String columnName = null; if (column >= 0 && column < columnNames.length) { columnName = columnNames[column].toString(); } return (columnName == null) ? super.getColumnName(column) : columnName; } } } 

司机:

 import java.awt.*; import java.awt.event.*; import java.util.*; import java.util.List; import javax.swing.*; public class DetailedComboBoxDemo implements Runnable { private DetailedComboBox combo; private JTextField name; private JTextField capital; public void run() { List> tableData = new ArrayList>(); tableData.add(new ArrayList( Arrays.asList("MD", "Maryland", "Annapolis"))); tableData.add(new ArrayList( Arrays.asList("NH", "New Hampshire", "Concord"))); tableData.add(new ArrayList( Arrays.asList("NJ", "New Jersey", "Trenton"))); tableData.add(new ArrayList( Arrays.asList("NM", "New Mexico", "Santa Fe"))); tableData.add(new ArrayList( Arrays.asList("ND", "North Dakota", "Bismark"))); String[] columns = new String[]{"State", "Name", "Capital"}; int[] widths = new int[]{50, 100, 100}; combo = new DetailedComboBox(columns, widths, 0); combo.setTableData(tableData); combo.setSelectedIndex(-1); combo.setPopupAlignment(DetailedComboBox.Alignment.LEFT); combo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { showDetails(); } }); name = new JTextField(10); capital = new JTextField(10); name.setEditable(false); capital.setEditable(false); JPanel p = new JPanel(new FlowLayout()); p.add(new JLabel("State")); p.add(combo); p.add(new JLabel("Name")); p.add(name); p.add(new JLabel("Capital")); p.add(capital); JFrame frame = new JFrame("DetailedComboBox Demo"); frame.getContentPane().add(p, BorderLayout.CENTER); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } private void showDetails() { List rowData = combo.getSelectedRow(); name.setText(rowData.get(1).toString()); capital.setText(rowData.get(2).toString()); } public static void main(String[] args) { SwingUtilities.invokeLater(new DetailedComboBoxDemo()); } } 

要实现这一点,您需要使用BasicComboxUI和BasicComboPopup的自定义子类。 在BasicComboPopup返回的Popup中使用JTable而不是JList。