implement autocomplete system name
This commit is contained in:
@@ -87,6 +87,14 @@ public class MarketModel {
|
|||||||
return systemsList;
|
return systemsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SystemModel get(String name){
|
||||||
|
Place s = market.get(name);
|
||||||
|
if (s == null){
|
||||||
|
return ModelFabric.NONE_SYSTEM;
|
||||||
|
}
|
||||||
|
return modeler.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
public SystemModel add(String name, double x, double y, double z) {
|
public SystemModel add(String name, double x, double y, double z) {
|
||||||
SystemModel system = modeler.get(market.addPlace(name, x, y, z));
|
SystemModel system = modeler.get(market.addPlace(name, x, y, z));
|
||||||
LOG.info("Add system {} to market {}", system, this);
|
LOG.info("Add system {} to market {}", system, this);
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package ru.trader.view.support.autocomplete;
|
||||||
|
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.util.Callback;
|
||||||
|
import javafx.util.StringConverter;
|
||||||
|
import org.controlsfx.control.textfield.AutoCompletionBinding;
|
||||||
|
import org.controlsfx.control.textfield.TextFields;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class AutoCompletion<T> {
|
||||||
|
private final ObjectProperty<T> completion = new SimpleObjectProperty<>();
|
||||||
|
private final StringConverter<T> converter;
|
||||||
|
private final AutoCompletionBinding<T> binding;
|
||||||
|
|
||||||
|
public AutoCompletion(final TextField textField, final Callback<AutoCompletionBinding.ISuggestionRequest, Collection<T>> suggestionProvider, final StringConverter<T> converter) {
|
||||||
|
this.converter = converter;
|
||||||
|
binding = TextFields.bindAutoCompletion(textField, suggestionProvider, converter);
|
||||||
|
binding.setOnAutoCompleted(e -> completion.setValue(e.getCompletion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoCompletionBinding<T> getBinding() {
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getCompletion() {
|
||||||
|
return completion.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectProperty<T> completionProperty() {
|
||||||
|
return completion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose(){
|
||||||
|
binding.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(T value) {
|
||||||
|
completion.setValue(value);
|
||||||
|
((TextField)binding.getCompletionTarget()).setText(converter.toString(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package ru.trader.view.support.autocomplete;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.collections.ListChangeListener;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.util.Callback;
|
||||||
|
import org.controlsfx.control.textfield.AutoCompletionBinding;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public abstract class CachedSuggestionProvider<T> implements Callback<AutoCompletionBinding.ISuggestionRequest, Collection<T>> {
|
||||||
|
private final List<T> cache = new ArrayList<>();
|
||||||
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
|
private final ObservableList<T> possibleSuggestions;
|
||||||
|
private AutoCompletionBinding.ISuggestionRequest lastRequest;
|
||||||
|
|
||||||
|
protected CachedSuggestionProvider(ObservableList<T> possibleSuggestions) {
|
||||||
|
this.possibleSuggestions = possibleSuggestions;
|
||||||
|
possibleSuggestions.addListener(listChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Collection<T> call(final AutoCompletionBinding.ISuggestionRequest request) {
|
||||||
|
List<T> suggestions = new ArrayList<>();
|
||||||
|
if(!request.getUserText().isEmpty()){
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
boolean cached = lastRequest != null && isContinue(lastRequest, request);
|
||||||
|
if (!cached){
|
||||||
|
cache.clear();
|
||||||
|
for (T possibleSuggestion : possibleSuggestions) {
|
||||||
|
if (isMatch(possibleSuggestion, request)) {
|
||||||
|
cache.add(possibleSuggestion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(cache, getComparator());
|
||||||
|
} else {
|
||||||
|
Iterator<T> iterator = cache.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
T possibleSuggestion = iterator.next();
|
||||||
|
if (!isMatch(possibleSuggestion, request)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
suggestions.addAll(cache);
|
||||||
|
lastRequest = request;
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isContinue(final AutoCompletionBinding.ISuggestionRequest lastRequest, final AutoCompletionBinding.ISuggestionRequest request){
|
||||||
|
String last = lastRequest.getUserText();
|
||||||
|
String current = request.getUserText();
|
||||||
|
return last != null && current != null && current.toLowerCase().startsWith(last.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Comparator<T> getComparator();
|
||||||
|
protected abstract boolean isMatch(T suggestion, AutoCompletionBinding.ISuggestionRequest request);
|
||||||
|
|
||||||
|
public void dispose(){
|
||||||
|
possibleSuggestions.removeListener(listChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ListChangeListener<T> listChangeListener = c -> {
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
lastRequest = null;
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package ru.trader.view.support.autocomplete;
|
||||||
|
|
||||||
|
import javafx.util.StringConverter;
|
||||||
|
import org.controlsfx.control.textfield.AutoCompletionBinding;
|
||||||
|
import ru.trader.model.MarketModel;
|
||||||
|
import ru.trader.model.SystemModel;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
public class SystemsProvider extends CachedSuggestionProvider<SystemModel> {
|
||||||
|
|
||||||
|
private final StringConverter<SystemModel> converter;
|
||||||
|
private final Comparator<SystemModel> comparator;
|
||||||
|
|
||||||
|
|
||||||
|
public SystemsProvider(MarketModel market) {
|
||||||
|
super(market.systemsProperty());
|
||||||
|
converter = new SystemsStringConverter(market);
|
||||||
|
comparator = (s1, s2) -> converter.toString(s1).toLowerCase().compareTo(converter.toString(s2).toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Comparator<SystemModel> getComparator() {
|
||||||
|
return comparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isMatch(SystemModel suggestion, AutoCompletionBinding.ISuggestionRequest request) {
|
||||||
|
String s = converter.toString(suggestion).toLowerCase();
|
||||||
|
return s.contains(request.getUserText().toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringConverter<SystemModel> getConverter() {
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.trader.view.support.autocomplete;
|
||||||
|
|
||||||
|
import javafx.util.StringConverter;
|
||||||
|
import ru.trader.model.MarketModel;
|
||||||
|
import ru.trader.model.SystemModel;
|
||||||
|
|
||||||
|
public class SystemsStringConverter extends StringConverter<SystemModel> {
|
||||||
|
private final MarketModel market;
|
||||||
|
|
||||||
|
public SystemsStringConverter(MarketModel market) {
|
||||||
|
this.market = market;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(SystemModel system) {
|
||||||
|
return system.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SystemModel fromString(String name) {
|
||||||
|
return market.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user