Jump to content

[Snippet] FilteredComboBox


Recommended Posts

Posted (edited)

FilteredComboBox

 

91f7904bfbfd4c85de3edce0dc7e63db.gif

 

Inspiration: http://stackoverflow.com/questions/10368856/jcombobox-filter-in-java-look-and-feel-independent

 

Example:

	public static void main(String[] args) {
		JFrame frame = new JFrame("FilteredComboBoxExample");
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		JPanel content = new JPanel();
		frame.setContentPane(content);
		
		FilteredComboBox<Skill> filteredComboBox = new FilteredComboBox<>(Skill.values(), s -> s.toString());
		filteredComboBox.setPreferredSize(new Dimension(240, 60));
		content.add(filteredComboBox);
		
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

Snippet:

Not very MVC friendly but hey this is Swing after all.

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JTextField;

public class FilteredComboBox<T> extends JComboBox<T> {

	private static final long serialVersionUID = 283907792618669032L;
	
	@SuppressWarnings("unused")
	private List<T> full;
	private List<T> filtered;
	@SuppressWarnings("unused")
	private Function<T, String> fetcher;
	private JTextField field;

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public FilteredComboBox(List<T> full, Function<T, String> fetcher) {
		setModel(new DefaultComboBoxModel(full.toArray()));
		this.full = full;
		this.fetcher = fetcher;
		setSelectedIndex(0);
		setEditable(true);
		field = (JTextField) getEditor().getEditorComponent();
		field.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent k) {
				String input = field.getText();
				int code = k.getKeyCode();
				if(!k.isActionKey() && k.getModifiers() == 0 && code != KeyEvent.VK_ENTER && code != KeyEvent.VK_CONTROL && code != KeyEvent.VK_ESCAPE) {
					filtered = new ArrayList<>();
                    for (int i = 0; i < full.size(); i++) {
                        if (fetcher.apply(full.get(i)).toLowerCase().contains(input.toLowerCase())) {
                        	filtered.add(full.get(i));
                        }
                    }
                    if (filtered.size() > 0) {
                    	setModel(new DefaultComboBoxModel(filtered.toArray()));
                        setSelectedItem(input);
                        showPopup();
                    }
                    else {
                    	setModel(new DefaultComboBoxModel(full.toArray()));
                    	setSelectedItem("No result matching: \" " + input + " \"");
                    	field.selectAll();
                    	showPopup();
                    }
				}
            }
			
		});
	}
	
	public FilteredComboBox(T[] full, Function<T, String> fetcher) {
		this(Arrays.asList(full), fetcher);
	}
	
}
Edited by Botre
  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...