我的目标是创建一个过滤的组合框。
我创建了一个可编辑的组合框。当用户输入文本时,代码搜索模型中的匹配项。当用户离开组合框时,代码从列表中选择所选项。此外,编辑器组件中的文本获取所选项的值。
当焦点通过shift + tab返回组合框时,编辑器组件将获取所选元素的文本。释放shift键后,keylistener运行。在这种情况下,编辑器组件包含先前输入的文本,例如,焦点丢失时设置的值。
如何设置editorComponent的文本以使其保持不变?
以下是代码:
package de.ccw.reports.gui.incomingOrder.MyComboBox;
import java.awt.FlowLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.text.JTextComponent;
import de.ccw.commons.ui.comp.XComboBox;
public class FilterableComboBox<E> extends XComboBox<E> {
ComboBoxModel<E> originalModel;
DefaultComboBoxModel<E> filteredModel;
JTextComponent editorComp;
JList<E> list;
public FilterableComboBox(ComboBoxModel<E> aModel) {
super();
receivePopupList();
originalModel = aModel;
filteredModel = new DefaultComboBoxModel<>();
setModel(filteredModel);
editorComp = (JTextComponent) getEditor().getEditorComponent();
editorComp.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
System.out.println("focusLostStart=" + getSelectedItem() + "|" + editorComp.getText());
String text = editorComp.getText();
editorComp.setText("");
setSelectedItem(null);
if(list.getSelectedIndex() != -1 && text.isEmpty() == false){
setSelectedIndex(list.getSelectedIndex());
editorComp.setText(getSelectedItem().toString());
}
System.out.println("focusLostEnd=" + getSelectedItem() + "|" + editorComp.getText());
}
@Override
public void focusGained(FocusEvent e) {
System.out.println("focusGainedStart=" + getSelectedItem() + "|" + editorComp.getText());
E element = getSelectedItem();
String text = editorComp.getText();
performModelFilter(null);
showPopup();
setSelectedItem(element);
editorComp.setText(text);
editorComp.selectAll();
System.out.println("focusGainedEnd=" + getSelectedItem() + "|" + editorComp.getText());
}
});
editorComp.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
}
String filterBkp = "";
@Override
public void keyReleased(KeyEvent e) {
String filter = editorComp.getText();
System.out.println("keyReleased-" + filterBkp + filter);
if(filter.equals(filterBkp) == false)
refreshModel();
filterBkp = filter;
}
@Override
public void keyPressed(KeyEvent e) {
}
});
setEditable(true);
}
@SuppressWarnings("unchecked")
private void receivePopupList() {
BasicComboPopup popup = (BasicComboPopup) getAccessibleContext().getAccessibleChild(0);
list = popup.getList();
}
private void refreshModel() {
String filter = editorComp.getText();
performModelFilter(filter);
editorComp.setText(filter);
}
private void performModelFilter(String filter) {
System.out.println("performModelFilter-" + filter);
filteredModel.removeAllElements();
for(int i = 0; i < originalModel.getSize(); i++){
E element = originalModel.getElementAt(i);
String value = element.toString().toUpperCase();
if (filter == null || value.contains(filter.toUpperCase())) {
filteredModel.addElement(element);
}
}
}
public static void main(String args[]){
FilterableComboBox<String> combo = new FilterableComboBox<>(new DefaultComboBoxModel<>(new String[]{"abc", "def", "ghi", "jkl", "mnoabc", "pqrdef"}));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JTextField(20));
frame.add(combo);
frame.add(new JTextField(20));
frame.pack();
frame.setVisible(true);
}
}