Archived
0

change items combobox to autocomplete fields

This commit is contained in:
Mo
2016-04-24 18:30:00 +03:00
parent b2321d0b20
commit a23ac408d9
8 changed files with 113 additions and 65 deletions

View File

@@ -3,7 +3,6 @@ package ru.trader.controllers;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
@@ -12,6 +11,7 @@ import ru.trader.view.support.DurationField;
import ru.trader.view.support.NumberField; import ru.trader.view.support.NumberField;
import ru.trader.view.support.autocomplete.AutoCompletion; import ru.trader.view.support.autocomplete.AutoCompletion;
import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.CachedSuggestionProvider;
import ru.trader.view.support.autocomplete.ItemsProvider;
import ru.trader.view.support.autocomplete.StationsProvider; import ru.trader.view.support.autocomplete.StationsProvider;
import java.time.Duration; import java.time.Duration;
@@ -23,7 +23,8 @@ public class MissionsController {
private TextField starportText; private TextField starportText;
private AutoCompletion<StationModel> starport; private AutoCompletion<StationModel> starport;
@FXML @FXML
private ComboBox<ItemModel> cargo; private TextField itemText;
private AutoCompletion<ItemModel> cargo;
@FXML @FXML
private NumberField quantity; private NumberField quantity;
@FXML @FXML
@@ -55,7 +56,7 @@ public class MissionsController {
if (courierBtn.equals(n)){ if (courierBtn.equals(n)){
missionType = MISSION_TYPE.COURIER; missionType = MISSION_TYPE.COURIER;
starportText.setDisable(false); starportText.setDisable(false);
cargo.setDisable(true); itemText.setDisable(true);
quantity.setDisable(true); quantity.setDisable(true);
leftTime.setDisable(false); leftTime.setDisable(false);
reward.setDisable(false); reward.setDisable(false);
@@ -63,7 +64,7 @@ public class MissionsController {
if (deliveryBtn.equals(n)){ if (deliveryBtn.equals(n)){
missionType = MISSION_TYPE.DELIVERY; missionType = MISSION_TYPE.DELIVERY;
starportText.setDisable(false); starportText.setDisable(false);
cargo.setDisable(true); itemText.setDisable(true);
quantity.setDisable(false); quantity.setDisable(false);
leftTime.setDisable(false); leftTime.setDisable(false);
reward.setDisable(false); reward.setDisable(false);
@@ -74,14 +75,14 @@ public class MissionsController {
starport.setValue(station); starport.setValue(station);
} }
starportText.setDisable(false); starportText.setDisable(false);
cargo.setDisable(false); itemText.setDisable(false);
quantity.setDisable(false); quantity.setDisable(false);
leftTime.setDisable(false); leftTime.setDisable(false);
reward.setDisable(false); reward.setDisable(false);
} else { } else {
missionType = null; missionType = null;
starportText.setDisable(true); starportText.setDisable(true);
cargo.setDisable(true); itemText.setDisable(true);
quantity.setDisable(true); quantity.setDisable(true);
leftTime.setDisable(true); leftTime.setDisable(true);
reward.setDisable(true); reward.setDisable(true);
@@ -95,7 +96,6 @@ public class MissionsController {
void init(){ void init(){
MarketModel world = MainController.getWorld(); MarketModel world = MainController.getWorld();
cargo.setItems(world.itemsProperty());
StationsProvider provider = new StationsProvider(world); StationsProvider provider = new StationsProvider(world);
if (starport == null){ if (starport == null){
starport = new AutoCompletion<>(starportText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_STATION, provider.getConverter()); starport = new AutoCompletion<>(starportText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_STATION, provider.getConverter());
@@ -103,14 +103,21 @@ public class MissionsController {
starport.setSuggestions(provider.getPossibleSuggestions()); starport.setSuggestions(provider.getPossibleSuggestions());
starport.setConverter(provider.getConverter()); starport.setConverter(provider.getConverter());
} }
ItemsProvider itemsProvider = new ItemsProvider(world);
if (cargo == null){
cargo = new AutoCompletion<>(itemText, new CachedSuggestionProvider<>(itemsProvider), ModelFabric.NONE_ITEM, itemsProvider.getConverter());
} else {
cargo.setSuggestions(itemsProvider.getPossibleSuggestions());
cargo.setConverter(itemsProvider.getConverter());
}
} }
void setStations(ObservableList<String> stationNames) { void setStations(ObservableList<String> stationNames) {
starport.setSuggestions(stationNames); starport.setSuggestions(stationNames);
} }
void setItems(ObservableList<ItemModel> items){ void setItems(ObservableList<String> itemNames){
cargo.setItems(items); cargo.setSuggestions(itemNames);
} }
public void add(){ public void add(){
@@ -119,13 +126,13 @@ public class MissionsController {
long count = quantity.getValue().longValue(); long count = quantity.getValue().longValue();
Duration time = leftTime.getValue(); Duration time = leftTime.getValue();
double profit = reward.getValue().doubleValue(); double profit = reward.getValue().doubleValue();
if (station != null && profit > 0){ if (!ModelFabric.isFake(station) && profit > 0){
switch (missionType){ switch (missionType){
case COURIER: missions.add(new MissionModel(station, time, profit)); case COURIER: missions.add(new MissionModel(station, time, profit));
break; break;
case DELIVERY: if (count > 0) missions.add(new MissionModel(station, count, time, profit)); case DELIVERY: if (count > 0) missions.add(new MissionModel(station, count, time, profit));
break; break;
case SUPPLY: if (item != null && count > 0) missions.add(new MissionModel(station, item, count, time, profit)); case SUPPLY: if (!ModelFabric.isFake(item) && count > 0) missions.add(new MissionModel(station, item, count, time, profit));
break; break;
} }
} }

View File

@@ -2,10 +2,11 @@ package ru.trader.controllers;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.RadioButton;
import javafx.util.StringConverter; import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import org.controlsfx.control.CheckComboBox; import org.controlsfx.control.CheckComboBox;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -21,8 +22,8 @@ import ru.trader.view.support.ServiceTypeStringConverter;
import ru.trader.view.support.StationTypeStringConverter; import ru.trader.view.support.StationTypeStringConverter;
import ru.trader.view.support.autocomplete.AutoCompletion; import ru.trader.view.support.autocomplete.AutoCompletion;
import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.CachedSuggestionProvider;
import ru.trader.view.support.autocomplete.ItemsProvider;
import ru.trader.view.support.autocomplete.SystemsProvider; import ru.trader.view.support.autocomplete.SystemsProvider;
import ru.trader.view.support.cells.CustomListCell;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -39,7 +40,8 @@ public class SearchController {
@FXML @FXML
private RadioButton rbBuyer; private RadioButton rbBuyer;
@FXML @FXML
private ComboBox<ItemModel> items; private TextField itemText;
private AutoCompletion<ItemModel> items;
@FXML @FXML
private NumberField distance; private NumberField distance;
@FXML @FXML
@@ -50,7 +52,6 @@ public class SearchController {
private TableView<ResultEntry> tblResults; private TableView<ResultEntry> tblResults;
private final List<ResultEntry> results = FXCollections.observableArrayList(); private final List<ResultEntry> results = FXCollections.observableArrayList();
private final ObservableList<ItemModel> itemsList = FXCollections.observableArrayList();
private final ToggleGroup offerType = new ToggleGroup(); private final ToggleGroup offerType = new ToggleGroup();
private MarketModel market; private MarketModel market;
@@ -67,20 +68,7 @@ public class SearchController {
rbSeller.setToggleGroup(offerType); rbSeller.setToggleGroup(offerType);
rbSeller.setUserData(OFFER_TYPE.SELL); rbSeller.setUserData(OFFER_TYPE.SELL);
rbSeller.setSelected(true); rbSeller.setSelected(true);
items.setCellFactory(new CustomListCell<>(ItemModel::getName));
items.setConverter(new StringConverter<ItemModel>() {
@Override
public String toString(ItemModel item) {
return item.getName();
}
@Override
public ItemModel fromString(String string) {
throw new UnsupportedOperationException("Is not editable field");
}
});
BindingsHelper.setTableViewItems(tblResults, results); BindingsHelper.setTableViewItems(tblResults, results);
items.setItems(itemsList);
} }
void init(){ void init(){
@@ -88,20 +76,19 @@ public class SearchController {
market = MainController.getMarket(); market = MainController.getMarket();
market.getNotificator().add(searchChangeListener); market.getNotificator().add(searchChangeListener);
SystemsProvider provider = market.getSystemsProvider(); SystemsProvider provider = market.getSystemsProvider();
if (source != null) source.dispose(); if (source == null) {
source = new AutoCompletion<>(sourceText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); source = new AutoCompletion<>(sourceText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter());
itemsList.clear(); } else {
itemsList.add(ModelFabric.NONE_ITEM); source.setSuggestions(provider.getPossibleSuggestions());
itemsList.addAll(market.itemsProperty().get()); source.setConverter(provider.getConverter());
} }
ItemsProvider itemsProvider = market.getItemsProvider();
if (items == null){
private void addItem(ItemModel item){ items = new AutoCompletion<>(itemText, new CachedSuggestionProvider<>(itemsProvider), ModelFabric.NONE_ITEM, itemsProvider.getConverter());
itemsList.add(item); } else {
items.setSuggestions(itemsProvider.getPossibleSuggestions());
items.setConverter(itemsProvider.getConverter());
} }
private void removeItem(ItemModel item){
itemsList.remove(item);
} }
@FXML @FXML
@@ -136,7 +123,10 @@ public class SearchController {
} }
} }
@FXML
private void currentAsSource(){
source.setValue(MainController.getProfile().getSystem());
}
public class ResultEntry { public class ResultEntry {
private final StationModel station; private final StationModel station;
@@ -193,15 +183,7 @@ public class SearchController {
} }
private final ChangeMarketListener searchChangeListener = new ChangeMarketListener() { private final ChangeMarketListener searchChangeListener = new ChangeMarketListener() {
@Override
public void add(ItemModel item) {
addItem(item);
}
@Override
public void remove(ItemModel item) {
removeItem(item);
}
}; };
} }

View File

@@ -20,6 +20,7 @@ import ru.trader.model.support.Notificator;
import ru.trader.services.OrdersSearchTask; import ru.trader.services.OrdersSearchTask;
import ru.trader.services.RoutesSearchTask; import ru.trader.services.RoutesSearchTask;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
import ru.trader.view.support.autocomplete.ItemsProvider;
import ru.trader.view.support.autocomplete.StationsProvider; import ru.trader.view.support.autocomplete.StationsProvider;
import ru.trader.view.support.autocomplete.SystemsProvider; import ru.trader.view.support.autocomplete.SystemsProvider;
@@ -40,8 +41,10 @@ public class MarketModel {
private final ObservableList<String> systemNames; private final ObservableList<String> systemNames;
private final ObservableList<String> stationNames; private final ObservableList<String> stationNames;
private final ObservableList<String> itemNames;
private final SystemsProvider systemsProvider; private final SystemsProvider systemsProvider;
private final StationsProvider stationsProvider; private final StationsProvider stationsProvider;
private final ItemsProvider itemsProvider;
private final ListProperty<GroupModel> groups; private final ListProperty<GroupModel> groups;
private final ListProperty<ItemModel> items; private final ListProperty<ItemModel> items;
@@ -55,8 +58,11 @@ public class MarketModel {
items.sort(ItemModel::compareTo); items.sort(ItemModel::compareTo);
systemNames = new SimpleListProperty<>(FXCollections.observableArrayList(market.getPlaceNames())); systemNames = new SimpleListProperty<>(FXCollections.observableArrayList(market.getPlaceNames()));
stationNames = new SimpleListProperty<>(FXCollections.observableArrayList(market.getVendorNames())); stationNames = new SimpleListProperty<>(FXCollections.observableArrayList(market.getVendorNames()));
List<String> iNames = items.stream().map(ItemModel::getName).collect(Collectors.toList());
itemNames = new SimpleListProperty<>(FXCollections.observableArrayList(iNames));
systemsProvider = new SystemsProvider(this); systemsProvider = new SystemsProvider(this);
stationsProvider = new StationsProvider(this); stationsProvider = new StationsProvider(this);
itemsProvider = new ItemsProvider(this);
} }
public MarketAnalyzer getAnalyzer() { public MarketAnalyzer getAnalyzer() {
@@ -79,6 +85,10 @@ public class MarketModel {
return stationNames; return stationNames;
} }
public ObservableList<String> getItemNames() {
return itemNames;
}
public SystemsProvider getSystemsProvider() { public SystemsProvider getSystemsProvider() {
return systemsProvider; return systemsProvider;
} }
@@ -87,6 +97,10 @@ public class MarketModel {
return stationsProvider; return stationsProvider;
} }
public ItemsProvider getItemsProvider() {
return itemsProvider;
}
public SystemModel get(String name){ public SystemModel get(String name){
Place s = market.get(name); Place s = market.get(name);
if (s == null){ if (s == null){
@@ -159,6 +173,7 @@ public class MarketModel {
LOG.info("Add item {} to market {}", item, this); LOG.info("Add item {} to market {}", item, this);
notificator.sendAdd(item); notificator.sendAdd(item);
items.add(item); items.add(item);
itemNames.add(item.getName());
return item; return item;
} }
@@ -167,6 +182,7 @@ public class MarketModel {
market.remove(ModelFabric.get(item)); market.remove(ModelFabric.get(item));
notificator.sendRemove(item); notificator.sendRemove(item);
items.remove(item); items.remove(item);
itemNames.remove(item.getName());
} }
ItemStat getStat(OFFER_TYPE type, Item item){ ItemStat getStat(OFFER_TYPE type, Item item){
@@ -333,5 +349,7 @@ public class MarketModel {
groups.get().forEach(GroupModel::updateName); groups.get().forEach(GroupModel::updateName);
items.get().forEach(ItemModel::updateName); items.get().forEach(ItemModel::updateName);
items.sort(ItemModel::compareTo); items.sort(ItemModel::compareTo);
List<String> iNames = items.stream().map(ItemModel::getName).collect(Collectors.toList());
itemNames.setAll(iNames);
} }
} }

View File

@@ -38,6 +38,7 @@ public class AutoCompletion<T> {
this.converter = converter; this.converter = converter;
this.notFoundItem = notFoundItem; this.notFoundItem = notFoundItem;
this.suggestionProvider = suggestionProvider; this.suggestionProvider = suggestionProvider;
completion.setValue(notFoundItem);
binding = new AutoTextFieldBinding(textField, suggestionProvider); binding = new AutoTextFieldBinding(textField, suggestionProvider);
binding.setOnAutoCompleted(e -> completion.setValue(converter.fromString(e.getCompletion()))); binding.setOnAutoCompleted(e -> completion.setValue(converter.fromString(e.getCompletion())));
} }

View File

@@ -1,13 +1,18 @@
package ru.trader.view.support; package ru.trader.view.support.autocomplete;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import ru.trader.controllers.MainController;
import ru.trader.model.ItemModel; import ru.trader.model.ItemModel;
import ru.trader.model.MarketModel;
import java.util.Optional; import java.util.Optional;
public class ItemStringConverter extends StringConverter<ItemModel> { public class ItemStringConverter extends StringConverter<ItemModel> {
private final MarketModel market;
public ItemStringConverter(MarketModel market) {
this.market = market;
}
@Override @Override
public String toString(ItemModel item) { public String toString(ItemModel item) {
@@ -16,7 +21,7 @@ public class ItemStringConverter extends StringConverter<ItemModel> {
@Override @Override
public ItemModel fromString(String name) { public ItemModel fromString(String name) {
Optional<ItemModel> item = MainController.getWorld().itemsProperty().stream().filter(i -> i.getName().equals(name)).findAny(); Optional<ItemModel> item = market.itemsProperty().stream().filter(i -> i.getName().equals(name)).findAny();
return item.orElse(null); return item.orElse(null);
} }
} }

View File

@@ -0,0 +1,36 @@
package ru.trader.view.support.autocomplete;
import javafx.util.StringConverter;
import org.controlsfx.control.textfield.AutoCompletionBinding;
import ru.trader.model.ItemModel;
import ru.trader.model.MarketModel;
import java.util.Comparator;
public class ItemsProvider extends AbstractSuggestionProvider<String> {
private final StringConverter<ItemModel> converter;
private final Comparator<String> comparator;
public ItemsProvider(MarketModel market) {
super(market.getItemNames());
converter = new ItemStringConverter(market);
comparator = (i1, i2) -> i1.toLowerCase().compareTo(i2.toLowerCase());
}
@Override
protected Comparator<String> getComparator() {
return comparator;
}
@Override
protected boolean isMatch(String suggestion, AutoCompletionBinding.ISuggestionRequest request) {
String s = suggestion.toLowerCase();
return s.startsWith(request.getUserText().toLowerCase());
}
public StringConverter<ItemModel> getConverter() {
return converter;
}
}

View File

@@ -3,10 +3,8 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.image.*?> <?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<?import ru.trader.view.support.cells.ItemListCell?>
<?import ru.trader.view.support.ItemStringConverter?>
<?import ru.trader.view.support.NumberField?>
<?import ru.trader.view.support.DurationField?> <?import ru.trader.view.support.DurationField?>
<?import ru.trader.view.support.NumberField?>
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" <GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="ru.trader.controllers.MissionsController" fx:controller="ru.trader.controllers.MissionsController"
hgap="10" vgap="5"> hgap="10" vgap="5">
@@ -37,10 +35,7 @@
<Label GridPane.rowIndex="1" text="%missions.label.starport"/> <Label GridPane.rowIndex="1" text="%missions.label.starport"/>
<TextField fx:id="starportText" GridPane.rowIndex="1" GridPane.columnIndex="1"/> <TextField fx:id="starportText" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
<Label GridPane.rowIndex="2" text="%missions.label.cargo"/> <Label GridPane.rowIndex="2" text="%missions.label.cargo"/>
<ComboBox fx:id="cargo" GridPane.rowIndex="2" GridPane.columnIndex="1"> <TextField fx:id="itemText" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<cellFactory><ItemListCell /></cellFactory>
<converter><ItemStringConverter /></converter>
</ComboBox>
<Label GridPane.rowIndex="3" text="%missions.label.quantity"/> <Label GridPane.rowIndex="3" text="%missions.label.quantity"/>
<NumberField fx:id="quantity" GridPane.rowIndex="3" GridPane.columnIndex="1" value="0"/> <NumberField fx:id="quantity" GridPane.rowIndex="3" GridPane.columnIndex="1" value="0"/>
<Label GridPane.rowIndex="4" text="%missions.label.leftTime"/> <Label GridPane.rowIndex="4" text="%missions.label.leftTime"/>

View File

@@ -5,6 +5,7 @@
<?import javafx.scene.control.cell.*?> <?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<?import org.controlsfx.control.CheckComboBox?> <?import org.controlsfx.control.CheckComboBox?>
<?import org.controlsfx.glyphfont.Glyph?>
<?import ru.trader.view.support.cells.DistanceCell?> <?import ru.trader.view.support.cells.DistanceCell?>
<?import ru.trader.view.support.NumberField?> <?import ru.trader.view.support.NumberField?>
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" <GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
@@ -24,13 +25,16 @@
<ColumnConstraints minWidth="150" maxWidth="150"/> <ColumnConstraints minWidth="150" maxWidth="150"/>
</columnConstraints> </columnConstraints>
<Label text="%search.text.from" /> <Label text="%search.text.from" />
<TextField fx:id="sourceText" prefWidth="150" GridPane.columnIndex="1" /> <HBox GridPane.columnIndex="1">
<TextField fx:id="sourceText" prefWidth="150" />
<Button minWidth="30" onAction="#currentAsSource"><graphic><Glyph text="FontAwesome|MAP_MARKER"/></graphic></Button>
</HBox>
<HBox GridPane.columnSpan="2" GridPane.rowIndex="1" spacing="10" alignment="BOTTOM_CENTER"> <HBox GridPane.columnSpan="2" GridPane.rowIndex="1" spacing="10" alignment="BOTTOM_CENTER">
<RadioButton fx:id="rbSeller" text="%market.order.seller"/> <RadioButton fx:id="rbSeller" text="%market.order.seller"/>
<RadioButton fx:id="rbBuyer" text="%market.order.buyer" /> <RadioButton fx:id="rbBuyer" text="%market.order.buyer" />
</HBox> </HBox>
<Label text="%search.text.item" GridPane.rowIndex="2"/> <Label text="%search.text.item" GridPane.rowIndex="2"/>
<ComboBox fx:id="items" prefWidth="150" GridPane.columnIndex="1" GridPane.rowIndex="2"/> <TextField fx:id="itemText" prefWidth="150" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Label text="%search.text.distance" GridPane.rowIndex="3" /> <Label text="%search.text.distance" GridPane.rowIndex="3" />
<NumberField fx:id="distance" GridPane.columnIndex="1" GridPane.rowIndex="3" /> <NumberField fx:id="distance" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label text="%label.station.type" GridPane.rowIndex="4"/> <Label text="%label.station.type" GridPane.rowIndex="4"/>