可编辑的 JCombobox,用于过滤列表并仅显示包含我编写的文本的文本
editable JCombobox that filters the list and show only text that contains the text I wrote
我需要一个包含元素的可编辑 JCombobox
:示例:
element 1
element 2
item one
item one two
element item
当我写例如 "one" 时,它必须只显示给我
item one
item one two
我之前找到的所有内容都是 AutocompleteJCombobox
,它将我滚动到以 "one".
开头的项目
提前致谢
使用例如algosome.com/articles/java-jcombobox-autocomplete.html 将 s.indexOf(value) == 0
替换为 s.indexOf(value) >=0
定义可搜索的数据结构:
public interface Searchable<E, V>{
public Collection<E> search(V value);
}
基本演示:
public class StringSearchable implements Searchable<String,String>{
private List<String> terms = new ArrayList<String>();
public StringSearchable(List<String> terms){
this.terms.addAll(terms);
}
@Override
public Collection<String> search(String value) {
List<String> founds = new ArrayList<String>();
for ( String s : terms ){
if ( s.indexOf(value) == 0 ){
founds.add(s);
}
}
return founds;
}
}
现在 JComboBox 自动完成:
public class AutocompleteJComboBox extends JComboBox{
static final long serialVersionUID = 4321421L;
private final Searchable<String,String> searchable;
public AutocompleteJComboBox(Searchable<String,String> s){
super();
this.searchable = s;
setEditable(true);
Component c = getEditor().getEditorComponent();
if ( c instanceof JTextComponent ){
final JTextComponent tc = (JTextComponent)c;
tc.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void changedUpdate(DocumentEvent arg0) {}
@Override
public void insertUpdate(DocumentEvent arg0) {
update();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
update();
}
public void update(){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
List<String> founds = new ArrayList<String>(searchable.search(tc.getText()));
Set<String> foundSet = new HashSet<String>();
for ( String s : founds ){
foundSet.add(s.toLowerCase());
}
Collections.sort(founds);//sort alphabetically
setEditable(false);
removeAllItems();
//if founds contains the search text, then only add once.
if ( !foundSet.contains( tc.getText().toLowerCase()) ){
addItem( tc.getText() );
}
for (String s : founds) {
addItem(s);
}
setEditable(true);
setPopupVisible(true);
}
});
}
});
tc.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent arg0) {
if ( tc.getText().length() > 0 ){
setPopupVisible(true);
}
}
@Override
public void focusLost(FocusEvent arg0) {
}
});
}else{
throw new IllegalStateException("Editing component is not a JTextComponent!");
}
}
}
StanislavL 的 AutocompleteJComboBox 在与同一 Window 中的其他组件一起使用时在键入时失去焦点(至少在我的情况下)。
不过有一个简单的解决方法——添加一个 requestFocus();在 运行 函数的末尾。
添加的代码:
public class AutocompleteJComboBox extends JComboBox{
static final long serialVersionUID = 4321421L;
private final Searchable<String,String> searchable;
public AutocompleteJComboBox(Searchable<String,String> s){
super();
this.searchable = s;
setEditable(true);
Component c = getEditor().getEditorComponent();
if ( c instanceof JTextComponent ){
final JTextComponent tc = (JTextComponent)c;
tc.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void changedUpdate(DocumentEvent arg0) {}
@Override
public void insertUpdate(DocumentEvent arg0) {
update();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
update();
}
public void update(){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
List<String> founds = new ArrayList<String>(searchable.search(tc.getText()));
Set<String> foundSet = new HashSet<String>();
for ( String s : founds ){
foundSet.add(s.toLowerCase());
}
Collections.sort(founds);//sort alphabetically
setEditable(false);
removeAllItems();
//if founds contains the search text, then only add once.
if ( !foundSet.contains( tc.getText().toLowerCase()) ){
addItem( tc.getText() );
}
for (String s : founds) {
addItem(s);
}
setEditable(true);
setPopupVisible(true);
requestFocus();
}
});
}
});
tc.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent arg0) {
if ( tc.getText().length() > 0 ){
setPopupVisible(true);
}
}
@Override
public void focusLost(FocusEvent arg0) {
}
});
}else{
throw new IllegalStateException("Editing component is not a JTextComponent!");
}
}
}
我需要一个包含元素的可编辑 JCombobox
:示例:
element 1
element 2
item one
item one two
element item
当我写例如 "one" 时,它必须只显示给我
item one
item one two
我之前找到的所有内容都是 AutocompleteJCombobox
,它将我滚动到以 "one".
提前致谢
使用例如algosome.com/articles/java-jcombobox-autocomplete.html 将 s.indexOf(value) == 0
替换为 s.indexOf(value) >=0
定义可搜索的数据结构:
public interface Searchable<E, V>{
public Collection<E> search(V value);
}
基本演示:
public class StringSearchable implements Searchable<String,String>{
private List<String> terms = new ArrayList<String>();
public StringSearchable(List<String> terms){
this.terms.addAll(terms);
}
@Override
public Collection<String> search(String value) {
List<String> founds = new ArrayList<String>();
for ( String s : terms ){
if ( s.indexOf(value) == 0 ){
founds.add(s);
}
}
return founds;
}
}
现在 JComboBox 自动完成:
public class AutocompleteJComboBox extends JComboBox{
static final long serialVersionUID = 4321421L;
private final Searchable<String,String> searchable;
public AutocompleteJComboBox(Searchable<String,String> s){
super();
this.searchable = s;
setEditable(true);
Component c = getEditor().getEditorComponent();
if ( c instanceof JTextComponent ){
final JTextComponent tc = (JTextComponent)c;
tc.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void changedUpdate(DocumentEvent arg0) {}
@Override
public void insertUpdate(DocumentEvent arg0) {
update();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
update();
}
public void update(){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
List<String> founds = new ArrayList<String>(searchable.search(tc.getText()));
Set<String> foundSet = new HashSet<String>();
for ( String s : founds ){
foundSet.add(s.toLowerCase());
}
Collections.sort(founds);//sort alphabetically
setEditable(false);
removeAllItems();
//if founds contains the search text, then only add once.
if ( !foundSet.contains( tc.getText().toLowerCase()) ){
addItem( tc.getText() );
}
for (String s : founds) {
addItem(s);
}
setEditable(true);
setPopupVisible(true);
}
});
}
});
tc.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent arg0) {
if ( tc.getText().length() > 0 ){
setPopupVisible(true);
}
}
@Override
public void focusLost(FocusEvent arg0) {
}
});
}else{
throw new IllegalStateException("Editing component is not a JTextComponent!");
}
}
}
StanislavL 的 AutocompleteJComboBox 在与同一 Window 中的其他组件一起使用时在键入时失去焦点(至少在我的情况下)。
不过有一个简单的解决方法——添加一个 requestFocus();在 运行 函数的末尾。
添加的代码:
public class AutocompleteJComboBox extends JComboBox{
static final long serialVersionUID = 4321421L;
private final Searchable<String,String> searchable;
public AutocompleteJComboBox(Searchable<String,String> s){
super();
this.searchable = s;
setEditable(true);
Component c = getEditor().getEditorComponent();
if ( c instanceof JTextComponent ){
final JTextComponent tc = (JTextComponent)c;
tc.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void changedUpdate(DocumentEvent arg0) {}
@Override
public void insertUpdate(DocumentEvent arg0) {
update();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
update();
}
public void update(){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
List<String> founds = new ArrayList<String>(searchable.search(tc.getText()));
Set<String> foundSet = new HashSet<String>();
for ( String s : founds ){
foundSet.add(s.toLowerCase());
}
Collections.sort(founds);//sort alphabetically
setEditable(false);
removeAllItems();
//if founds contains the search text, then only add once.
if ( !foundSet.contains( tc.getText().toLowerCase()) ){
addItem( tc.getText() );
}
for (String s : founds) {
addItem(s);
}
setEditable(true);
setPopupVisible(true);
requestFocus();
}
});
}
});
tc.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent arg0) {
if ( tc.getText().length() > 0 ){
setPopupVisible(true);
}
}
@Override
public void focusLost(FocusEvent arg0) {
}
});
}else{
throw new IllegalStateException("Editing component is not a JTextComponent!");
}
}
}