#java #autocomplete #jcombobox #glazedlists
#java #автозаполнение #jcombobox #glazedlists
Вопрос:
Я пытаюсь заставить AutoCompleteSupport выполнять поиск по определенной строке в объекте, но когда я присваиваю EventList JComboBox, я не понимаю, как дать указание установщику запрашивать только свойство объекта Station «title». Только. Вместо этого функция AutoCompleteSupport выполняет поиск по всей строке имени объекта. Есть ли еще что-то, что мне нужно реализовать, чтобы указать AutoCompleteSupport выполнять поиск только по этому одному набору свойств в конкретном объекте?
Пока что код:
public class StationFinder extends JComboBox {
private EventList<Station> stations = new BasicEventList<Station>();
public StationFinder() {
setStations(); // this sets up the 'stations' property
SwingUtilities.invokeLater(new Runnable() {
public void run() {
AutoCompleteSupport.install(StationFinder.this, getStations());
}
});
}
}
Это объект Station:
public class Station {
private int id;
private String metaName;
private String title;
...
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMetaName() {
return metaName;
}
public void setMetaName(String metaName) {
this.metaName = metaName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Я пытался реализовать FilterableText внутри объекта Station, но это вообще не сработало.
Ответ №1:
Я не совсем понимаю, почему вы пытаетесь расширить поле со списком, чтобы установить поддержку автозаполнения.
Вот небольшой, но полный пример программы. Я не знал, какой тип станции вы имели в виду, поэтому в моем примере я думаю о радиостанциях в Великобритании. Я перечисляю их имя и местоположение.
Ключевым аспектом является TextFilterator. Если бы вы попытались установить без фильтратора, то обнаружили бы, что автозаполнение также соответствовало бы местоположению (потому что это выводится в toString () и по умолчанию именно там происходит фильтрация). Однако, как только он включен, я могу точно указать интересующие поля, то есть заголовок, и при фильтрации сопоставляется только название станции.
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.matchers.TextMatcherEditor;
import ca.odell.glazedlists.swing.AutoCompleteSupport;
import ca.odell.glazedlists.swing.EventComboBoxModel;
import java.awt.BorderLayout;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class StationFinderAutoComplete {
private JFrame mainFrame;
private JComboBox stationsComboBox;
private EventList<Station> stations = new BasicEventList<Station>();
public StationFinderAutoComplete() {
populateStations();
createGui();
mainFrame.setVisible(true);
}
private void populateStations() {
stations.add(new Station("Key 103", "Manchester"));
stations.add(new Station("Capital FM", "London"));
stations.add(new Station("BBC Radio Leeds", "Leeds"));
stations.add(new Station("BBC Radio 4", "London"));
}
private void createGui() {
mainFrame = new JFrame("GlazedLists Autocomplete Example");
mainFrame.setSize(600, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Use a GlazedLists EventComboBoxModel to connect the JComboBox with an EventList.
EventComboBoxModel<Station> model = new EventComboBoxModel<Station>(stations);
stationsComboBox = new JComboBox(model);
AutoCompleteSupport autocomplete = AutoCompleteSupport.install(stationsComboBox, stations, new StationTextFilterator());
// Try without the filterator to see the difference.
//AutoCompleteSupport autocomplete = AutoCompleteSupport.install(stationsComboBox, stations);
autocomplete.setFilterMode(TextMatcherEditor.CONTAINS);
JPanel panel = new JPanel(new BorderLayout());
panel.add(stationsComboBox, BorderLayout.NORTH);
mainFrame.setLayout(new BorderLayout());
mainFrame.getContentPane().add(panel, BorderLayout.CENTER);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new StationFinderAutoComplete();
}
});
}
class Station {
private String title;
private String location;
public Station(String title, String location) {
this.title = title;
this.location = location;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@Override
public String toString() {
return title " (" location ")";
}
}
class StationTextFilterator implements TextFilterator<Station> {
@Override
public void getFilterStrings(List<String> baseList, Station station) {
baseList.add(station.getTitle());
}
}
}
Комментарии:
1. Я имею в виду строку кода с
AutoCompleteSupport.install
. Да, все эти пакеты доступны со стандартным пакетом GlazedLists. Я хочу сказать, передаете ли вы TextFilteratorAutoCompleteSupport.install()
методу, и это никак не связано с установкой пакета в вашей системе.2. Извините, что нашел это. Искал расширение, а не реализацию. =)
3. @ChrisWalsh В моем примере или объяснении чего-то не хватает, что мешает вам пометить как отвеченный? Я бы с радостью расширил свой ответ, если это необходимо.
4. Хорошо, я думаю, ваш код сработал. =) Я удалил TextFilterator, как вы отметили, и эффективной разницы не было. Я не совсем понимаю эту часть, но она работает одинаково с или без. Спасибо! Теперь перейдем к прослушиванию события выбора =D
5. Этого не должно произойти. В моем примере кода, если вы используете закомментированный
AutoCompleteSupport.install()
метод (без фильтратора) и попытаетесь ввести «Лондон», вы получите сопоставление двух станций с Лондоном в качестве их местоположения. Если вы вернетесь к использованию исходного метода установки с помощью filterator и повторите попытку с помощью «London», вы не получите совпадений. В этом разница — вы видите это, когда запускаете сами?