From 61e7b3a9cb538a3ebf9cdf80957414b2f622487b Mon Sep 17 00:00:00 2001 From: iMoHax Date: Thu, 15 Oct 2015 15:10:00 +0300 Subject: [PATCH] optimise memory using --- .../src/main/java/ru/trader/EMDNUpdater.java | 4 +- .../trader/controllers/FilterController.java | 51 +++++++--- .../ru/trader/controllers/MainController.java | 1 + .../controllers/MissionsController.java | 47 +++++---- .../trader/controllers/OffersController.java | 59 +++++------ .../trader/controllers/ProfileController.java | 44 ++++++--- .../controllers/RouteSearchController.java | 50 +++++++--- .../controllers/RouteTrackController.java | 19 +--- .../trader/controllers/RouterController.java | 97 +++++++++++-------- .../trader/controllers/SearchController.java | 22 +++-- .../controllers/SystemsEditorController.java | 67 ++++++++++--- .../java/ru/trader/model/MarketModel.java | 62 ++++++------ .../java/ru/trader/model/ModelFabric.java | 69 +++++++++---- .../main/java/ru/trader/model/RouteModel.java | 4 +- .../java/ru/trader/model/StationModel.java | 11 +-- .../java/ru/trader/model/SystemModel.java | 20 +++- .../ru/trader/model/support/Notificator.java | 6 ++ .../AbstractSuggestionProvider.java | 41 ++++++++ .../support/autocomplete/AutoCompletion.java | 44 +++++---- .../CachedSuggestionProvider.java | 48 ++++----- .../autocomplete/StationStringConverter.java | 2 +- .../autocomplete/StationsProvider.java | 14 +-- .../autocomplete/SuggestionProvider.java | 14 +++ .../support/autocomplete/SystemsProvider.java | 16 +-- .../view/support/cells/StationListCell.java | 4 +- client/src/main/resources/view/filter.fxml | 5 +- client/src/main/resources/view/offers.fxml | 11 +-- client/src/main/resources/view/sEditor.fxml | 12 +-- client/src/main/resources/view/search.fxml | 2 +- .../model/support/PositionComputerTest.java | 16 +-- core/src/main/java/ru/trader/core/Market.java | 12 ++- core/src/main/java/ru/trader/core/Place.java | 4 + core/src/main/java/ru/trader/core/Vendor.java | 4 + .../ru/trader/store/berkeley/BDBMarket.java | 19 ++++ .../ru/trader/store/berkeley/PlaceProxy.java | 5 + .../ru/trader/store/berkeley/dao/PlaceDA.java | 8 ++ .../trader/store/berkeley/dao/VendorDA.java | 9 ++ 37 files changed, 599 insertions(+), 324 deletions(-) create mode 100644 client/src/main/java/ru/trader/view/support/autocomplete/AbstractSuggestionProvider.java create mode 100644 client/src/main/java/ru/trader/view/support/autocomplete/SuggestionProvider.java diff --git a/client/src/main/java/ru/trader/EMDNUpdater.java b/client/src/main/java/ru/trader/EMDNUpdater.java index 9517290..4fee2d2 100644 --- a/client/src/main/java/ru/trader/EMDNUpdater.java +++ b/client/src/main/java/ru/trader/EMDNUpdater.java @@ -121,9 +121,9 @@ public class EMDNUpdater { @Override public void run() { - market.systemsProperty().get().forEach(system -> { + market.getSystemNames().forEach(system -> { LOG.trace("Auto update {}", system); - Station emdnData = emdn.pop(system.getName()); + Station emdnData = emdn.pop(system); if (emdnData != null){ //TODO: implement new model //updater.init(system); diff --git a/client/src/main/java/ru/trader/controllers/FilterController.java b/client/src/main/java/ru/trader/controllers/FilterController.java index 3422c1b..cb6baa1 100644 --- a/client/src/main/java/ru/trader/controllers/FilterController.java +++ b/client/src/main/java/ru/trader/controllers/FilterController.java @@ -1,6 +1,5 @@ package ru.trader.controllers; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Parent; import javafx.scene.control.*; @@ -15,6 +14,9 @@ import ru.trader.model.SystemModel; import ru.trader.model.support.BindingsHelper; import ru.trader.view.support.Localization; import ru.trader.view.support.NumberField; +import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; +import ru.trader.view.support.autocomplete.SystemsProvider; import ru.trader.view.support.cells.CustomListCell; import java.util.Optional; @@ -22,15 +24,17 @@ public class FilterController { private final static Logger LOG = LoggerFactory.getLogger(FilterController.class); @FXML - private ComboBox center; + private TextField centerText; + private AutoCompletion center; @FXML private NumberField radius; @FXML private NumberField distance; @FXML - private ComboBox system; + private TextField systemText; + private AutoCompletion system; @FXML - private ComboBox station; + private ComboBox station; @FXML private CheckBox cbMarket; @FXML @@ -56,15 +60,29 @@ public class FilterController { @FXML private void initialize(){ - system.valueProperty().addListener((ov, o, n) -> station.setItems(n.getStationsList())); - excludes.setCellFactory(new CustomListCell<>(s -> String.format("%s (%s)", s.getSystem().getName(), s.getName()))); init(); + excludes.setCellFactory(new CustomListCell<>(s -> String.format("%s (%s)", s.getSystem().getName(), s.getName()))); + system.valueProperty().addListener((ov, o, n) -> { + station.setItems(n.getStationNamesList()); + station.getSelectionModel().selectFirst(); + }); } void init(){ market = MainController.getMarket(); - center.setItems(market.systemsListProperty()); - system.setItems(market.systemsProperty()); + SystemsProvider provider = market.getSystemsProvider(); + if (system == null){ + system = new AutoCompletion<>(systemText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system.setSuggestions(provider.getPossibleSuggestions()); + system.setConverter(provider.getConverter()); + } + if (center == null){ + center = new AutoCompletion<>(centerText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + center.setSuggestions(provider.getPossibleSuggestions()); + center.setConverter(provider.getConverter()); + } } private void createDialog(Parent owner, Parent content){ @@ -102,7 +120,7 @@ public class FilterController { private void clear(){ this.filter = null; - center.getSelectionModel().clearSelection(); + center.setValue(ModelFabric.NONE_SYSTEM); radius.clear(); distance.clear(); excludes.getItems().clear(); @@ -111,7 +129,7 @@ public class FilterController { private void save() { SystemModel s = center.getValue(); LOG.trace("Old filter", filter); - filter.setCenter(s == ModelFabric.NONE_SYSTEM ? null : market.getModeler().get(s)); + filter.setCenter(ModelFabric.isFake(s) ? null : market.getModeler().get(s)); filter.setRadius(radius.getValue().doubleValue()); filter.setDistance(distance.getValue().doubleValue()); if (cbMarket.isSelected()) filter.add(SERVICE_TYPE.MARKET); else filter.remove(SERVICE_TYPE.MARKET); @@ -145,11 +163,12 @@ public class FilterController { return result; } - public void add(ActionEvent actionEvent) { + @FXML + private void add() { SystemModel s = system.getValue(); if (s != null){ - StationModel st = station.getValue(); - if (st != null && st != ModelFabric.NONE_STATION){ + StationModel st = s.get(station.getValue()); + if (!ModelFabric.isFake(st)){ excludes.getItems().add(st); } else { excludes.getItems().addAll(s.getStations()); @@ -157,14 +176,16 @@ public class FilterController { } } - public void remove(ActionEvent actionEvent) { + @FXML + private void remove() { int index = excludes.getSelectionModel().getSelectedIndex(); if (index >= 0){ excludes.getItems().remove(index); } } - public void clean(ActionEvent actionEvent) { + @FXML + private void clean() { excludes.getItems().clear(); } diff --git a/client/src/main/java/ru/trader/controllers/MainController.java b/client/src/main/java/ru/trader/controllers/MainController.java index 766e219..fbd9ec2 100644 --- a/client/src/main/java/ru/trader/controllers/MainController.java +++ b/client/src/main/java/ru/trader/controllers/MainController.java @@ -101,6 +101,7 @@ public class MainController { } public void setMarket(MarketModel market) { + market.getNotificator().clear(); MainController.market = market; Screeners.reinitAll(); } diff --git a/client/src/main/java/ru/trader/controllers/MissionsController.java b/client/src/main/java/ru/trader/controllers/MissionsController.java index 8aaeb63..b590bfe 100644 --- a/client/src/main/java/ru/trader/controllers/MissionsController.java +++ b/client/src/main/java/ru/trader/controllers/MissionsController.java @@ -10,8 +10,11 @@ import javafx.scene.control.TextField; import ru.trader.model.*; import ru.trader.view.support.NumberField; import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.StationsProvider; +import java.util.Collection; + public class MissionsController { @FXML @@ -43,8 +46,6 @@ public class MissionsController { private final ObservableList missions; private StationModel station; - private StationsProvider receiverProvider; - private StationsProvider buyerProvider; public MissionsController() { missions = FXCollections.observableArrayList(); @@ -52,16 +53,11 @@ public class MissionsController { @FXML private void initialize(){ - MarketModel world = MainController.getWorld(); - receiverProvider = new StationsProvider(world); - receiver = new AutoCompletion<>(receiverText, receiverProvider, ModelFabric.NONE_STATION, receiverProvider.getConverter()); - buyerProvider = new StationsProvider(world); - buyer = new AutoCompletion<>(buyerText, buyerProvider, ModelFabric.NONE_STATION, buyerProvider.getConverter()); - item.setItems(world.itemsProperty()); - addCourierBtn.disableProperty().bind(Bindings.createBooleanBinding(() -> receiver.getCompletion() == null, receiver.completionProperty()) + init(); + addCourierBtn.disableProperty().bind(Bindings.createBooleanBinding(() -> receiver.getValue() == null, receiver.valueProperty()) .or(courierProfit.wrongProperty()) ); - addDeliveryBtn.disableProperty().bind(Bindings.createBooleanBinding(() -> buyer.getCompletion() == null, buyer.completionProperty()) + addDeliveryBtn.disableProperty().bind(Bindings.createBooleanBinding(() -> buyer.getValue() == null, buyer.valueProperty()) .or(deliveryCount.wrongProperty()) .or(deliveryProfit.wrongProperty()) ); @@ -71,21 +67,36 @@ public class MissionsController { ); } - StationsProvider getReceiverProvider() { - return receiverProvider; + void init(){ + MarketModel world = MainController.getWorld(); + item.setItems(world.itemsProperty()); + StationsProvider provider = new StationsProvider(world); + if (receiver == null){ + receiver = new AutoCompletion<>(receiverText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_STATION, provider.getConverter()); + } else { + receiver.setSuggestions(provider.getPossibleSuggestions()); + receiver.setConverter(provider.getConverter()); + } + if (buyer == null){ + buyer = new AutoCompletion<>(buyerText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_STATION, provider.getConverter()); + } else { + buyer.setSuggestions(provider.getPossibleSuggestions()); + buyer.setConverter(provider.getConverter()); + } } - StationsProvider getBuyerProvider() { - return buyerProvider; + void setStations(ObservableList stationNames) { + receiver.setSuggestions(stationNames); + buyer.setSuggestions(stationNames); } - ComboBox getItem() { - return item; + void setItems(ObservableList items){ + item.setItems(items); } @FXML private void addCourier(){ - StationModel station = receiver.getCompletion(); + StationModel station = receiver.getValue(); double profit = courierProfit.getValue().doubleValue(); if (station != null && profit > 0){ missions.add(new MissionModel(station, profit)); @@ -94,7 +105,7 @@ public class MissionsController { @FXML private void addDelivery(){ - StationModel station = buyer.getCompletion(); + StationModel station = buyer.getValue(); long count = deliveryCount.getValue().longValue(); double profit = deliveryProfit.getValue().doubleValue(); if (station != null && profit > 0){ diff --git a/client/src/main/java/ru/trader/controllers/OffersController.java b/client/src/main/java/ru/trader/controllers/OffersController.java index 939b06f..4a36f80 100644 --- a/client/src/main/java/ru/trader/controllers/OffersController.java +++ b/client/src/main/java/ru/trader/controllers/OffersController.java @@ -17,6 +17,9 @@ import ru.trader.model.support.ChangeMarketListener; import ru.trader.view.support.FactionStringConverter; import ru.trader.view.support.GovernmentStringConverter; import ru.trader.view.support.ViewUtils; +import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; +import ru.trader.view.support.autocomplete.SystemsProvider; import java.util.List; @@ -25,12 +28,12 @@ public class OffersController { private final static Logger LOG = LoggerFactory.getLogger(OffersController.class); private StationModel station; - private SystemModel system; @FXML private Insets stationsMargin; @FXML - private ListView systems; + private TextField systemText; + private AutoCompletion system; @FXML private SegmentedButton stationsBar; @FXML @@ -68,13 +71,10 @@ public class OffersController { // инициализируем форму данными @FXML private void initialize() { - systems.getSelectionModel().selectedItemProperty().addListener((ob, oldValue, newValue) ->{ - if (newValue != null){ - LOG.info("Change system to {}", newValue); - fillDetails(newValue); - } else { - systems.getSelectionModel().select(oldValue); - } + init(); + system.valueProperty().addListener((ob, oldValue, newValue) -> { + LOG.info("Change system to {}", newValue); + fillDetails(newValue); }); stationsGrp.selectedToggleProperty().addListener((v, o, n) -> { if (n != null){ @@ -103,23 +103,26 @@ public class OffersController { }); BindingsHelper.setTableViewItems(tblSell, sells); BindingsHelper.setTableViewItems(tblBuy, buys); - - init(); } void init(){ station = null; - system = null; MarketModel market = MainController.getMarket(); - market.getNotificator().add(new OffersChangeListener()); - systems.setItems(market.systemsProperty()); - systems.getSelectionModel().selectFirst(); + //TODO: create global notificator + market.getNotificator().add(offersChangeListener); + SystemsProvider provider = market.getSystemsProvider(); + if (system == null){ + system = new AutoCompletion<>(systemText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system.setSuggestions(provider.getPossibleSuggestions()); + system.setConverter(provider.getConverter()); + } } private void fillDetails(SystemModel system){ - this.system = system; - List stations = system.getStations(); + if (ModelFabric.isFake(system)) return; stationsBar.getButtons().clear(); + List stations = system.getStations(); stations.forEach(s -> stationsBar.getButtons().add(buildStationNode(s))); if (!stations.isEmpty()){ stationsBar.getButtons().get(0).setSelected(true); @@ -186,19 +189,21 @@ public class OffersController { } public SystemModel getSystem() { - return system; + return system.getValue(); } public StationModel getStation() { return station; } - public void addStation(ActionEvent actionEvent) { - Screeners.showAddStation(system); + @FXML + private void addStation() { + Screeners.showAddStation(getSystem()); } - public void editStation(ActionEvent actionEvent) { - Screeners.showEditStation(station); + @FXML + private void editStation() { + Screeners.showEditStation(getStation()); } @@ -226,10 +231,11 @@ public class OffersController { tblBuy.getItems().forEach(OfferModel::refresh); } - private class OffersChangeListener extends ChangeMarketListener { + private final ChangeMarketListener offersChangeListener = new ChangeMarketListener() { @Override public void priceChange(OfferModel offer, double oldPrice, double newPrice) { + StationModel station = getStation(); if (station.hasBuy(offer.getItem()) || station.hasSell(offer.getItem())){ ViewUtils.doFX(OffersController.this::sort); } @@ -237,7 +243,7 @@ public class OffersController { @Override public void add(OfferModel offer) { - if (offer.getStation().equals(station)){ + if (offer.getStation().equals(getStation())){ ViewUtils.doFX(()-> addOffer(offer)); } } @@ -253,7 +259,7 @@ public class OffersController { @Override public void remove(OfferModel offer) { - if (offer.getStation().equals(station)){ + if (offer.getStation().equals(getStation())){ ViewUtils.doFX(() -> removeOffer(offer)); } } @@ -267,6 +273,5 @@ public class OffersController { sort(); }); } - - } + }; } diff --git a/client/src/main/java/ru/trader/controllers/ProfileController.java b/client/src/main/java/ru/trader/controllers/ProfileController.java index 91d54b0..e312e6b 100644 --- a/client/src/main/java/ru/trader/controllers/ProfileController.java +++ b/client/src/main/java/ru/trader/controllers/ProfileController.java @@ -13,6 +13,7 @@ import ru.trader.model.*; import ru.trader.view.support.NumberField; import ru.trader.view.support.ViewUtils; import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.SystemsProvider; @@ -26,7 +27,7 @@ public class ProfileController { @FXML private TextField systemText; @FXML - private ComboBox station; + private ComboBox station; @FXML private CheckBox docked; @FXML @@ -54,10 +55,15 @@ public class ProfileController { @FXML private void initialize() { + init(); profile = MainController.getProfile(); - MarketModel world = MainController.getWorld(); - SystemsProvider provider = new SystemsProvider(world); - system = new AutoCompletion<>(systemText, provider, ModelFabric.NONE_SYSTEM, provider.getConverter()); + system.valueProperty().addListener((ov, o , n) -> { + doAndConsumeChanges(() -> { + station.setItems(n.getStationNamesList()); + station.getSelectionModel().selectFirst(); + }); + consumeChanges(() -> {profile.setSystem(n); profile.setStation(ModelFabric.NONE_STATION);}); + }); engine.setItems(FXCollections.observableList(Engine.getEngines())); engine.setConverter(new EngineStringConverter()); btnAddSystem.setOnAction(e -> { @@ -102,14 +108,21 @@ public class ProfileController { ignoreChanges = old; } + void init(){ + MarketModel world = MainController.getWorld(); + SystemsProvider provider = world.getSystemsProvider(); + if (system == null){ + system = new AutoCompletion<>(systemText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system.setSuggestions(provider.getPossibleSuggestions()); + system.setConverter(provider.getConverter()); + } + } + private void initListeners(){ name.textProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setName(n))); balance.numberProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setBalance(n.doubleValue()))); - system.completionProperty().addListener((ov, o , n) -> { - doAndConsumeChanges(() -> station.setItems(n.getStationsList())); - consumeChanges(() -> {profile.setSystem(n); profile.setStation(ModelFabric.NONE_STATION);}); - }); - station.valueProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setStation(n))); + station.valueProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setStation(getStation(n)))); docked.selectedProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setDocked(n))); mass.numberProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setShipMass(n.doubleValue()))); tank.numberProperty().addListener((ov, o, n) -> consumeChanges(() -> profile.setShipTank(n.doubleValue()))); @@ -126,7 +139,7 @@ public class ProfileController { name.setText(profile.getName()); balance.setValue(profile.getBalance()); system.setValue(profile.getSystem()); - station.setValue(profile.getStation()); + station.setValue(profile.getStation().getName()); docked.setSelected(profile.isDocked()); mass.setValue(profile.getShipMass()); tank.setValue(profile.getShipTank()); @@ -136,6 +149,11 @@ public class ProfileController { bind(); } + private StationModel getStation(String name){ + SystemModel s = system.getValue(); + return s == null ? ModelFabric.NONE_STATION : s.get(name); + } + private void bind(){ profile.nameProperty().addListener(nameListener); profile.balanceProperty().addListener(balanceListener); @@ -146,9 +164,7 @@ public class ProfileController { profile.shipTankProperty().addListener(tankListener); profile.shipCargoProperty().addListener(cargoListener); profile.shipEngineProperty().addListener(engineListener); - jumpRange.textProperty().bind(Bindings.createStringBinding(()-> { - return String.format("%.1f - %.1f", profile.getShipJumpRange(), profile.getMaxShipJumpRange()); - }, + jumpRange.textProperty().bind(Bindings.createStringBinding(()-> String.format("%.1f - %.1f", profile.getShipJumpRange(), profile.getMaxShipJumpRange()), profile.shipMassProperty(), profile.shipCargoProperty(), profile.shipTankProperty(), profile.shipEngineProperty() )); } @@ -170,7 +186,7 @@ public class ProfileController { private final ChangeListener nameListener = (ov, o, n) -> consumeChanges(() -> name.setText(n)); private final ChangeListener balanceListener = (ov, o, n) -> consumeChanges(() -> balance.setValue(n)); private final ChangeListener systemListener = (ov, o, n) -> consumeChanges(() -> system.setValue(n)); - private final ChangeListener stationListener = (ov, o, n) -> consumeChanges(() -> station.setValue(n)); + private final ChangeListener stationListener = (ov, o, n) -> consumeChanges(() -> station.setValue(n.getName())); private final ChangeListener dockedListener = (ov, o, n) -> consumeChanges(() -> docked.setSelected(n)); private final ChangeListener massListener = (ov, o, n) -> consumeChanges(() -> mass.setValue(n)); private final ChangeListener tankListener = (ov, o, n) -> consumeChanges(() -> tank.setValue(n)); diff --git a/client/src/main/java/ru/trader/controllers/RouteSearchController.java b/client/src/main/java/ru/trader/controllers/RouteSearchController.java index e7cee17..1e3f8c9 100644 --- a/client/src/main/java/ru/trader/controllers/RouteSearchController.java +++ b/client/src/main/java/ru/trader/controllers/RouteSearchController.java @@ -8,6 +8,7 @@ import javafx.scene.control.TextField; import ru.trader.analysis.CrawlerSpecificator; import ru.trader.model.*; import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.SystemsProvider; import java.util.Optional; @@ -18,12 +19,12 @@ public class RouteSearchController { private TextField fromSystemText; private AutoCompletion fromSystem; @FXML - private ComboBox fromStation; + private ComboBox fromStation; @FXML private TextField toSystemText; private AutoCompletion toSystem; @FXML - private ComboBox toStation; + private ComboBox toStation; @FXML private CheckBox cbFast; @FXML @@ -37,43 +38,60 @@ public class RouteSearchController { @FXML private void initialize(){ init(); + profile = MainController.getProfile(); missionsList.setItems(missionsController.getMissions()); initListeners(); } private void init(){ market = MainController.getMarket(); - profile = MainController.getProfile(); - SystemsProvider provider = new SystemsProvider(market); - fromSystem = new AutoCompletion<>(fromSystemText, provider, ModelFabric.NONE_SYSTEM, provider.getConverter()); - provider = new SystemsProvider(market); - toSystem = new AutoCompletion<>(toSystemText, provider, ModelFabric.NONE_SYSTEM, provider.getConverter()); + SystemsProvider provider = market.getSystemsProvider(); + if (fromSystem == null){ + fromSystem = new AutoCompletion<>(fromSystemText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + fromSystem.setSuggestions(provider.getPossibleSuggestions()); + fromSystem.setConverter(provider.getConverter()); + } + if (toSystem == null){ + toSystem = new AutoCompletion<>(toSystemText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + toSystem.setSuggestions(provider.getPossibleSuggestions()); + toSystem.setConverter(provider.getConverter()); + } + fromStation.setValue(ModelFabric.NONE_STATION.getName()); + toStation.setValue(ModelFabric.NONE_STATION.getName()); } private void initListeners(){ - fromSystem.completionProperty().addListener((ov, o , n) -> fromStation.setItems(n.getStationsList())); - fromStation.valueProperty().addListener((ov, o , n) -> missionsController.setStation(n)); - toSystem.completionProperty().addListener((ov, o , n) -> toStation.setItems(n.getStationsList())); + fromSystem.valueProperty().addListener((ov, o , n) -> { + fromStation.setItems(n.getStationNamesList()); + fromStation.getSelectionModel().selectFirst(); + }); + fromStation.valueProperty().addListener((ov, o , n) -> missionsController.setStation(fromSystem.getValue().get(n))); + toSystem.valueProperty().addListener((ov, o , n) -> { + toStation.setItems(n.getStationNamesList()); + toStation.getSelectionModel().selectFirst(); + }); } @FXML private void currentAsFrom(){ fromSystem.setValue(profile.getSystem()); - fromStation.setValue(profile.getStation()); + fromStation.setValue(profile.getStation().getName()); } @FXML private void loop(){ - toSystem.setValue(fromSystem.getCompletion()); + toSystem.setValue(fromSystem.getValue()); toStation.setValue(fromStation.getValue()); } @FXML private void search(){ - SystemModel f = fromSystem.getCompletion(); - SystemModel t = toSystem.getCompletion(); - StationModel fS = fromStation.getValue(); - StationModel tS = toStation.getValue(); + SystemModel f = fromSystem.getValue(); + SystemModel t = toSystem.getValue(); + StationModel fS = f != null ? f.get(fromStation.getValue()) : ModelFabric.NONE_STATION; + StationModel tS = t != null ? t.get(toStation.getValue()) : ModelFabric.NONE_STATION; CrawlerSpecificator specificator = new CrawlerSpecificator(); specificator.setByTime(cbFast.isSelected()); diff --git a/client/src/main/java/ru/trader/controllers/RouteTrackController.java b/client/src/main/java/ru/trader/controllers/RouteTrackController.java index c1c9ff3..a82ebe5 100644 --- a/client/src/main/java/ru/trader/controllers/RouteTrackController.java +++ b/client/src/main/java/ru/trader/controllers/RouteTrackController.java @@ -7,21 +7,13 @@ import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.*; -import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; -import javafx.scene.layout.VBox; -import ru.trader.analysis.CrawlerSpecificator; import ru.trader.model.*; +import ru.trader.model.support.BindingsHelper; import ru.trader.view.support.Track; import ru.trader.view.support.ViewUtils; -import ru.trader.view.support.autocomplete.AutoCompletion; -import ru.trader.view.support.autocomplete.SystemsProvider; -import ru.trader.view.support.cells.OfferListCell; import ru.trader.view.support.cells.OrderListCell; -import ru.trader.view.support.cells.StationListCell; -import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; public class RouteTrackController { @@ -93,11 +85,10 @@ public class RouteTrackController { if (index == -1) return; RouteEntryModel entry = route.get(index); missionsController.setStation(entry.getStation()); - ObservableList stations = FXCollections.observableArrayList(route.getStations(index)); - missionsController.getBuyerProvider().setPossibleSuggestions(stations); - missionsController.getReceiverProvider().setPossibleSuggestions(stations); - List items = route.getSellOffers(index).stream().map(OfferModel::getItem).collect(Collectors.toList()); - missionsController.getItem().getItems().setAll(items); + ObservableList stations = BindingsHelper.observableList(route.getStations(index), StationModel::getFullName); + missionsController.setStations(stations); + ObservableList items = FXCollections.observableList(route.getSellOffers(index).stream().map(OfferModel::getItem).collect(Collectors.toList())); + missionsController.setItems(items); station.setText(entry.getStation().getName()); system.setText(entry.getStation().getSystem().getName()); diff --git a/client/src/main/java/ru/trader/controllers/RouterController.java b/client/src/main/java/ru/trader/controllers/RouterController.java index 027d135..74d17c0 100644 --- a/client/src/main/java/ru/trader/controllers/RouterController.java +++ b/client/src/main/java/ru/trader/controllers/RouterController.java @@ -14,6 +14,7 @@ import ru.trader.model.support.ChangeMarketListener; import ru.trader.view.support.NumberField; import ru.trader.view.support.RouteNode; import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; import ru.trader.view.support.autocomplete.SystemsProvider; import java.util.Optional; @@ -49,14 +50,14 @@ public class RouterController { private AutoCompletion source; @FXML - private ComboBox sStation; + private ComboBox sStation; @FXML private TextField targetText; private AutoCompletion target; @FXML - private ComboBox tStation; + private ComboBox tStation; @FXML private TableView tblOrders; @@ -81,19 +82,21 @@ public class RouterController { cargo.numberProperty().addListener((ov, o, n) -> Main.SETTINGS.setCargo(n.intValue())); tank.numberProperty().addListener((ov, o, n) -> Main.SETTINGS.setTank(n.doubleValue())); jumps.numberProperty().addListener((ov, o, n) -> Main.SETTINGS.setJumps(n.intValue())); - source.completionProperty().addListener((ov, o, n) -> { + source.valueProperty().addListener((ov, o, n) -> { if (n != null) { - sStation.setItems(n.getStationsList()); + sStation.setItems(n.getStationNamesList()); } else { sStation.setItems(FXCollections.emptyObservableList()); } + sStation.getSelectionModel().selectFirst(); }); - target.completionProperty().addListener((ov, o, n) -> { + target.valueProperty().addListener((ov, o, n) -> { if (n != null) { - tStation.setItems(n.getStationsList()); + tStation.setItems(n.getStationNamesList()); } else { tStation.setItems(FXCollections.emptyObservableList()); } + tStation.getSelectionModel().selectFirst(); }); @@ -109,9 +112,9 @@ public class RouterController { jumps.setValue(Main.SETTINGS.getJumps()); addBtn.disableProperty().bind(Bindings.createBooleanBinding(()-> { - SystemModel system = target.getCompletion(); + SystemModel system = target.getValue(); return ModelFabric.isFake(system); - }, target.completionProperty())); + }, target.valueProperty())); editBtn.disableProperty().bind(tblOrders.getSelectionModel().selectedIndexProperty().isEqualTo(-1)); removeBtn.disableProperty().bind(Bindings.createBooleanBinding(()-> { @@ -134,15 +137,27 @@ public class RouterController { void init(){ + if (market != null){ + market.getNotificator().remove(routerChangeListener); + } market = MainController.getMarket(); - market.getNotificator().add(new RouterChangeListener()); - SystemsProvider provider = new SystemsProvider(market); - if (source != null) source.dispose(); - source = new AutoCompletion<>(sourceText, provider, ModelFabric.NONE_SYSTEM, provider.getConverter()); - if (target != null) target.dispose(); - provider = new SystemsProvider(market); - target = new AutoCompletion<>(targetText, provider, ModelFabric.NONE_SYSTEM, provider.getConverter()); + market.getNotificator().add(routerChangeListener); + SystemsProvider provider = market.getSystemsProvider(); + if (source == null){ + source = new AutoCompletion<>(sourceText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + source.setSuggestions(provider.getPossibleSuggestions()); + source.setConverter(provider.getConverter()); + } + if (target == null){ + target = new AutoCompletion<>(targetText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + target.setSuggestions(provider.getPossibleSuggestions()); + target.setConverter(provider.getConverter()); + } orders.clear(); + sStation.setValue(ModelFabric.NONE_STATION.getName()); + tStation.setValue(ModelFabric.NONE_STATION.getName()); totalBalance.setValue(balance.getValue()); totalProfit.setValue(0); } @@ -152,7 +167,7 @@ public class RouterController { totalProfit.add(order.getProfit()); totalBalance.add(order.getProfit()); source.setValue(order.getBuyer().getSystem()); - sStation.setValue(order.getBuyer()); + sStation.setValue(order.getBuyer().getName()); target.setValue(ModelFabric.NONE_SYSTEM); balance.setDisable(true); } @@ -161,7 +176,7 @@ public class RouterController { totalProfit.sub(order.getProfit()); totalBalance.sub(order.getProfit()); source.setValue(order.getSystem()); - sStation.setValue(order.getStation()); + sStation.setValue(order.getStation().getName()); target.setValue(ModelFabric.NONE_SYSTEM); if (orders.isEmpty()) { balance.setDisable(false); @@ -169,10 +184,10 @@ public class RouterController { } public void addStationToRoute(){ - SystemModel s = source.getCompletion(); - SystemModel t = target.getCompletion(); - StationModel sS = sStation.getValue(); - StationModel tS = tStation.getValue(); + SystemModel s = source.getValue(); + SystemModel t = target.getValue(); + StationModel sS = s != null ? s.get(sStation.getValue()) : ModelFabric.NONE_STATION; + StationModel tS = t != null ? t.get(tStation.getValue()) : ModelFabric.NONE_STATION; RouteModel r = market.getPath(s, sS, t, tS); if (r == null) return; if (route != null){ @@ -181,8 +196,8 @@ public class RouterController { route = r; } refreshPath(); - source.setValue(target.getCompletion()); - sStation.setValue(tS); + source.setValue(target.getValue()); + sStation.setValue(tS.getName()); } public void editOrders(){ @@ -256,10 +271,10 @@ public class RouterController { } public void showOrders(){ - SystemModel s = source.getCompletion(); - SystemModel t = target.getCompletion(); - StationModel sS = sStation.getValue(); - StationModel tS = tStation.getValue(); + SystemModel s = source.getValue(); + SystemModel t = target.getValue(); + StationModel sS = s != null ? s.get(sStation.getValue()) : ModelFabric.NONE_STATION; + StationModel tS = t != null ? t.get(tStation.getValue()) : ModelFabric.NONE_STATION; market.getOrders(s, sS, t, tS, totalBalance.getValue().doubleValue(), result -> { Optional order = Screeners.showOrders(result); if (order.isPresent()){ @@ -270,10 +285,10 @@ public class RouterController { } public void showRoutes(){ - SystemModel s = source.getCompletion(); - SystemModel t = target.getCompletion(); - StationModel sS = sStation.getValue(); - StationModel tS = tStation.getValue(); + SystemModel s = source.getValue(); + SystemModel t = target.getValue(); + StationModel sS = s != null ? s.get(sStation.getValue()) : ModelFabric.NONE_STATION; + StationModel tS = t != null ? t.get(tStation.getValue()) : ModelFabric.NONE_STATION; market.getRoutes(s, sS, t, tS, totalBalance.getValue().doubleValue(), new CrawlerSpecificator(), routes -> { Optional path = Screeners.showRouters(routes); if (path.isPresent()){ @@ -319,26 +334,26 @@ public class RouterController { path.setContent(null); } - private class RouterChangeListener extends ChangeMarketListener { + private final ChangeMarketListener routerChangeListener = new ChangeMarketListener() { @Override public void add(StationModel station) { - if (station.getSystem().equals(source.getCompletion())){ - sStation.getItems().add(station); + if (station.getSystem().equals(source.getValue())){ + sStation.getItems().add(station.getName()); } - if (station.getSystem().equals(target.getCompletion())){ - tStation.getItems().add(station); + if (station.getSystem().equals(target.getValue())){ + tStation.getItems().add(station.getName()); } } @Override public void remove(StationModel station) { - if (station.getSystem().equals(source.getCompletion())){ - sStation.getItems().remove(station); + if (station.getSystem().equals(source.getValue())){ + sStation.getItems().remove(station.getName()); } - if (station.getSystem().equals(target.getCompletion())){ - tStation.getItems().remove(station); + if (station.getSystem().equals(target.getValue())){ + tStation.getItems().remove(station.getName()); } } - } + }; } diff --git a/client/src/main/java/ru/trader/controllers/SearchController.java b/client/src/main/java/ru/trader/controllers/SearchController.java index 21cce18..c694c23 100644 --- a/client/src/main/java/ru/trader/controllers/SearchController.java +++ b/client/src/main/java/ru/trader/controllers/SearchController.java @@ -15,6 +15,9 @@ import ru.trader.model.*; import ru.trader.model.support.BindingsHelper; import ru.trader.model.support.ChangeMarketListener; import ru.trader.view.support.NumberField; +import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; +import ru.trader.view.support.autocomplete.SystemsProvider; import ru.trader.view.support.cells.CustomListCell; import java.util.Collection; @@ -25,7 +28,8 @@ public class SearchController { private final static Logger LOG = LoggerFactory.getLogger(SearchController.class); @FXML - private ComboBox source; + private TextField sourceText; + private AutoCompletion source; @FXML private RadioButton rbSeller; @FXML @@ -61,6 +65,7 @@ public class SearchController { @FXML private void initialize() { + init(); rbBuyer.setToggleGroup(offerType); rbBuyer.setUserData(OFFER_TYPE.BUY); rbSeller.setToggleGroup(offerType); @@ -80,17 +85,18 @@ public class SearchController { }); BindingsHelper.setTableViewItems(tblResults, results); items.setItems(itemsList); - init(); } void init(){ + if (market != null) market.getNotificator().remove(searchChangeListener); market = MainController.getMarket(); - market.getNotificator().add(new SearchChangeListener()); - source.setItems(market.systemsProperty()); + market.getNotificator().add(searchChangeListener); + SystemsProvider provider = market.getSystemsProvider(); + if (source != null) source.dispose(); + source = new AutoCompletion<>(sourceText, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); itemsList.clear(); itemsList.add(ModelFabric.NONE_ITEM); itemsList.addAll(market.itemsProperty().get()); - source.getSelectionModel().selectFirst(); } @@ -105,6 +111,7 @@ public class SearchController { @FXML private void searchStations(){ MarketFilter filter = new MarketFilter(); + //TODO: set center = source filter.setDistance(distance.getValue().doubleValue()); if (cbMarket.isSelected()) filter.add(SERVICE_TYPE.MARKET); else filter.remove(SERVICE_TYPE.MARKET); if (cbBlackMarket.isSelected()) filter.add(SERVICE_TYPE.BLACK_MARKET); else filter.remove(SERVICE_TYPE.BLACK_MARKET); @@ -195,8 +202,7 @@ public class SearchController { } - private class SearchChangeListener extends ChangeMarketListener { - + private final ChangeMarketListener searchChangeListener = new ChangeMarketListener() { @Override public void add(ItemModel item) { addItem(item); @@ -206,6 +212,6 @@ public class SearchController { public void remove(ItemModel item) { removeItem(item); } - } + }; } diff --git a/client/src/main/java/ru/trader/controllers/SystemsEditorController.java b/client/src/main/java/ru/trader/controllers/SystemsEditorController.java index c435c66..37667bc 100644 --- a/client/src/main/java/ru/trader/controllers/SystemsEditorController.java +++ b/client/src/main/java/ru/trader/controllers/SystemsEditorController.java @@ -13,9 +13,13 @@ import javafx.util.converter.DoubleStringConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.trader.model.MarketModel; +import ru.trader.model.ModelFabric; import ru.trader.model.SystemModel; import ru.trader.model.support.PositionComputer; import ru.trader.view.support.Localization; +import ru.trader.view.support.autocomplete.AutoCompletion; +import ru.trader.view.support.autocomplete.CachedSuggestionProvider; +import ru.trader.view.support.autocomplete.SystemsProvider; import ru.trader.view.support.cells.TextFieldCell; public class SystemsEditorController { @@ -45,23 +49,30 @@ public class SystemsEditorController { @FXML private TableColumn clnS6; @FXML - private ComboBox system1; + private TextField system1Text; + private AutoCompletion system1; @FXML - private ComboBox system2; + private TextField system2Text; + private AutoCompletion system2; @FXML - private ComboBox system3; + private TextField system3Text; + private AutoCompletion system3; @FXML - private ComboBox system4; + private TextField system4Text; + private AutoCompletion system4; @FXML - private ComboBox system5; + private TextField system5Text; + private AutoCompletion system5; @FXML - private ComboBox system6; + private TextField system6Text; + private AutoCompletion system6; private Dialog dlg; private MarketModel market; @FXML private void initialize() { + init(); clnName.setCellFactory(TextFieldCell.forTableColumn(new DefaultStringConverter())); clnX.setCellFactory(TextFieldCell.forTableColumn(new DoubleStringConverter())); clnY.setCellFactory(TextFieldCell.forTableColumn(new DoubleStringConverter())); @@ -81,17 +92,47 @@ public class SystemsEditorController { system4.valueProperty().addListener((ov, o, n) -> clnS4.setText(n != null ? n.getName() : "")); system5.valueProperty().addListener((ov, o, n) -> clnS5.setText(n != null ? n.getName() : "")); system6.valueProperty().addListener((ov, o, n) -> clnS6.setText(n != null ? n.getName() : "")); - init(); } void init(){ market = MainController.getMarket(); - system1.setItems(market.systemsProperty()); - system2.setItems(market.systemsProperty()); - system3.setItems(market.systemsProperty()); - system4.setItems(market.systemsProperty()); - system5.setItems(market.systemsProperty()); - system6.setItems(market.systemsProperty()); + SystemsProvider provider = market.getSystemsProvider(); + if (system1 == null){ + system1 = new AutoCompletion<>(system1Text, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system1.setSuggestions(provider.getPossibleSuggestions()); + system1.setConverter(provider.getConverter()); + } + if (system2 == null){ + system2 = new AutoCompletion<>(system2Text, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system2.setSuggestions(provider.getPossibleSuggestions()); + system2.setConverter(provider.getConverter()); + } + if (system3 == null){ + system3 = new AutoCompletion<>(system3Text, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system3.setSuggestions(provider.getPossibleSuggestions()); + system3.setConverter(provider.getConverter()); + } + if (system4 == null){ + system4 = new AutoCompletion<>(system4Text, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system4.setSuggestions(provider.getPossibleSuggestions()); + system4.setConverter(provider.getConverter()); + } + if (system5 == null){ + system5 = new AutoCompletion<>(system5Text, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system5.setSuggestions(provider.getPossibleSuggestions()); + system5.setConverter(provider.getConverter()); + } + if (system6 == null){ + system6 = new AutoCompletion<>(system6Text, new CachedSuggestionProvider<>(provider), ModelFabric.NONE_SYSTEM, provider.getConverter()); + } else { + system6.setSuggestions(provider.getPossibleSuggestions()); + system6.setConverter(provider.getConverter()); + } } private void createDialog(Parent owner, Parent content){ diff --git a/client/src/main/java/ru/trader/model/MarketModel.java b/client/src/main/java/ru/trader/model/MarketModel.java index b7edf02..b0c59cb 100644 --- a/client/src/main/java/ru/trader/model/MarketModel.java +++ b/client/src/main/java/ru/trader/model/MarketModel.java @@ -5,7 +5,6 @@ import javafx.beans.property.ListProperty; import javafx.beans.property.ReadOnlyListProperty; import javafx.beans.property.SimpleListProperty; import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,6 +20,8 @@ import ru.trader.model.support.Notificator; import ru.trader.services.OrdersSearchTask; import ru.trader.services.RoutesSearchTask; import ru.trader.view.support.Localization; +import ru.trader.view.support.autocomplete.StationsProvider; +import ru.trader.view.support.autocomplete.SystemsProvider; import java.util.Optional; import java.util.function.Consumer; @@ -34,10 +35,10 @@ public class MarketModel { private final ModelFabric modeler; private final Notificator notificator; - private final ListProperty systems; - private final ListProperty stations; - // with NONE_SYSTEM - private ListProperty systemsList; + private final ObservableList systemNames; + private final ObservableList stationNames; + private final SystemsProvider systemsProvider; + private final StationsProvider stationsProvider; private final ListProperty groups; private final ListProperty items; @@ -49,24 +50,12 @@ public class MarketModel { groups = new SimpleListProperty<>(BindingsHelper.observableList(market.getGroups(), modeler::get)); items = new SimpleListProperty<>(BindingsHelper.observableList(market.getItems(), modeler::get)); items.sort(ItemModel::compareTo); - systems = new SimpleListProperty<>(BindingsHelper.observableList(market.get(), modeler::get)); - systemsList = new SimpleListProperty<>(FXCollections.observableArrayList(ModelFabric.NONE_SYSTEM)); - systemsList.addAll(systems); - stations = new SimpleListProperty<>(BindingsHelper.observableList(market.getVendors(), modeler::get)); - systems.addListener(SYSTEMS_CHANGE_LISTENER); + systemNames = new SimpleListProperty<>(FXCollections.observableArrayList(market.getPlaceNames())); + stationNames = new SimpleListProperty<>(FXCollections.observableArrayList(market.getVendorNames())); + systemsProvider = new SystemsProvider(this); + stationsProvider = new StationsProvider(this); } - private ListChangeListener SYSTEMS_CHANGE_LISTENER = l -> { - while (l.next()) { - if (l.wasRemoved()) { - systemsList.removeAll(l.getRemoved()); - } - if (l.wasAdded()) { - systemsList.addAll(l.getAddedSubList()); - } - } - }; - public MarketAnalyzer getAnalyzer() { return analyzer; } @@ -79,15 +68,20 @@ public class MarketModel { return notificator; } - public ReadOnlyListProperty systemsProperty() { - return systems; - } - public ReadOnlyListProperty systemsListProperty() { - return systemsList; + public ObservableList getSystemNames() { + return systemNames; } - public ReadOnlyListProperty stationsProperty() { - return stations; + public ObservableList getStationNames() { + return stationNames; + } + + public SystemsProvider getSystemsProvider() { + return systemsProvider; + } + + public StationsProvider getStationsProvider() { + return stationsProvider; } public SystemModel get(String name){ @@ -102,23 +96,23 @@ public class MarketModel { SystemModel system = modeler.get(market.addPlace(name, x, y, z)); LOG.info("Add system {} to market {}", system, this); notificator.sendAdd(system); - systems.add(system); - stations.addAll(system.getStations()); + systemNames.add(system.getName()); + stationNames.addAll(system.getStationFullNames()); return system; } public void remove(SystemModel system) { LOG.info("Remove system {} from market {}", system, this); notificator.sendRemove(system); - stations.removeAll(system.getStations()); + stationNames.removeAll(system.getStationFullNames()); market.remove(system.getSystem()); - systems.remove(system); + systemNames.remove(system.getName()); } StationModel addStation(SystemModel system, String name) { StationModel station = modeler.get(system.getSystem().addVendor(name)); LOG.info("Add station {} to system {}", station, system); - stations.add(station); + stationNames.add(station.getFullName()); notificator.sendAdd(station); return station; } @@ -126,7 +120,7 @@ public class MarketModel { void removeStation(StationModel station) { LOG.info("Remove station {} from system {}", station, station.getSystem()); notificator.sendRemove(station); - stations.remove(station); + stationNames.remove(station.getFullName()); station.getSystem().getSystem().remove(station.getStation()); } diff --git a/client/src/main/java/ru/trader/model/ModelFabric.java b/client/src/main/java/ru/trader/model/ModelFabric.java index dbd252f..d21b2c3 100644 --- a/client/src/main/java/ru/trader/model/ModelFabric.java +++ b/client/src/main/java/ru/trader/model/ModelFabric.java @@ -10,6 +10,7 @@ import ru.trader.core.*; import java.lang.ref.WeakReference; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -180,18 +181,23 @@ public class ModelFabric { } @Override - public List getStations() { - throw new UnsupportedOperationException("Is fake system, change unsupported"); + public StationModel get(String name) { + return ModelFabric.NONE_STATION; } @Override - public ObservableList getStationsList() { - return FXCollections.observableArrayList(ModelFabric.NONE_STATION); + public List getStationNames() { + return Collections.emptyList(); } @Override - public List getStations(SERVICE_TYPE service) { - throw new UnsupportedOperationException("Is fake system, change unsupported"); + public ObservableList getStationNamesList() { + return FXCollections.observableArrayList(ModelFabric.NONE_STATION.getName()); + } + + @Override + public List getStationNames(SERVICE_TYPE service) { + return Collections.emptyList(); } @Override @@ -213,7 +219,7 @@ public class ModelFabric { @Override Vendor getStation() { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override @@ -221,19 +227,44 @@ public class ModelFabric { return ""; } + @Override + public String getFullName() { + return ""; + } + + @Override + public FACTION getFaction() { + throw new UnsupportedOperationException("Is fake station, unsupported"); + } + + @Override + public void setFaction(FACTION faction) { + throw new UnsupportedOperationException("Is fake station, unsupported"); + } + + @Override + public GOVERNMENT getGovernment() { + throw new UnsupportedOperationException("Is fake station, unsupported"); + } + + @Override + public void setGovernment(GOVERNMENT government) { + throw new UnsupportedOperationException("Is fake station, unsupported"); + } + @Override public void setName(String value) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public double getDistance() { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public void setDistance(double value) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override @@ -243,42 +274,42 @@ public class ModelFabric { @Override public Collection getServices() { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public void addService(SERVICE_TYPE service) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public void removeService(SERVICE_TYPE service) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public SystemModel getSystem() { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public List getSells() { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public List getBuys() { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public OfferModel add(OFFER_TYPE type, ItemModel item, double price, long count) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override public void remove(OfferModel offer) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override @@ -293,7 +324,7 @@ public class ModelFabric { @Override public double getDistance(StationModel other) { - throw new UnsupportedOperationException("Is fake system, unsupported"); + throw new UnsupportedOperationException("Is fake station, unsupported"); } @Override diff --git a/client/src/main/java/ru/trader/model/RouteModel.java b/client/src/main/java/ru/trader/model/RouteModel.java index dfafaf6..3d1d848 100644 --- a/client/src/main/java/ru/trader/model/RouteModel.java +++ b/client/src/main/java/ru/trader/model/RouteModel.java @@ -209,7 +209,9 @@ public class RouteModel { Collection res = new HashSet<>(); int startIndex = _route.isLoop() ? 1 : offset+1; if (startIndex >= entries.size()) return res; - entries.subList(startIndex, entries.size()).stream().map(RouteEntryModel::getStation) + entries.subList(startIndex, entries.size()).stream() + .filter(e -> !e.isTransit()) + .map(RouteEntryModel::getStation) .filter(station -> station != ModelFabric.NONE_STATION) .forEach(res::add); return res; diff --git a/client/src/main/java/ru/trader/model/StationModel.java b/client/src/main/java/ru/trader/model/StationModel.java index bae5b94..437afba 100644 --- a/client/src/main/java/ru/trader/model/StationModel.java +++ b/client/src/main/java/ru/trader/model/StationModel.java @@ -1,11 +1,8 @@ package ru.trader.model; -import javafx.beans.binding.Bindings; -import javafx.beans.binding.StringBinding; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.trader.core.*; -import ru.trader.model.support.ModelBindings; import java.util.Collection; import java.util.List; @@ -46,6 +43,10 @@ public class StationModel { station.setName(value); } + public String getFullName(){ + return station.getFullName(); + } + public FACTION getFaction() {return station.getFaction();} public void setFaction(FACTION faction) { @@ -133,10 +134,6 @@ public class StationModel { return station.getDistance(other.station); } - public StringBinding asString(){ - return Bindings.createStringBinding(() -> getSystem().getName()+": "+getName()); - } - @Override public String toString() { if (LOG.isTraceEnabled()){ diff --git a/client/src/main/java/ru/trader/model/SystemModel.java b/client/src/main/java/ru/trader/model/SystemModel.java index 40bd615..6fb9f45 100644 --- a/client/src/main/java/ru/trader/model/SystemModel.java +++ b/client/src/main/java/ru/trader/model/SystemModel.java @@ -9,6 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.trader.core.*; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -100,17 +101,26 @@ public class SystemModel { return system.get().stream().map(this::asModel).collect(Collectors.toList()); } - public ObservableList getStationsList() { - ObservableList res = FXCollections.observableArrayList(ModelFabric.NONE_STATION); - res.addAll(getStations()); + public Collection getStationNames() { + return system.getVendorNames(); + } + + public List getStationFullNames() { + return system.get().stream().map(Vendor::getFullName).collect(Collectors.toList()); + } + + public ObservableList getStationNamesList() { + ObservableList res = FXCollections.observableArrayList(ModelFabric.NONE_STATION.getName()); + res.addAll(getStationNames()); return res; } - public List getStations(final SERVICE_TYPE service) { - return system.get().stream().filter(v -> v.has(service)).map(this::asModel).collect(Collectors.toList()); + public List getStationNames(final SERVICE_TYPE service) { + return system.get().stream().filter(v -> v.has(service)).map(Vendor::getName).collect(Collectors.toList()); } public StationModel get(String name){ + if (name == null) return ModelFabric.NONE_STATION; return asModel(system.get(name)); } diff --git a/client/src/main/java/ru/trader/model/support/Notificator.java b/client/src/main/java/ru/trader/model/support/Notificator.java index 8d767a6..eb5a887 100644 --- a/client/src/main/java/ru/trader/model/support/Notificator.java +++ b/client/src/main/java/ru/trader/model/support/Notificator.java @@ -29,6 +29,12 @@ public class Notificator { } } + public void remove(ChangeMarketListener listener){ + synchronized (this.listener){ + this.listener.remove(listener); + } + } + public void clear() { synchronized (listener){ listener.clear(); diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/AbstractSuggestionProvider.java b/client/src/main/java/ru/trader/view/support/autocomplete/AbstractSuggestionProvider.java new file mode 100644 index 0000000..48be48c --- /dev/null +++ b/client/src/main/java/ru/trader/view/support/autocomplete/AbstractSuggestionProvider.java @@ -0,0 +1,41 @@ +package ru.trader.view.support.autocomplete; + + +import javafx.collections.ObservableList; +import org.controlsfx.control.textfield.AutoCompletionBinding; + +import java.util.*; +import java.util.stream.Collectors; + +public abstract class AbstractSuggestionProvider implements SuggestionProvider { + private ObservableList possibleSuggestions; + + protected AbstractSuggestionProvider(ObservableList possibleSuggestions) { + this.possibleSuggestions = possibleSuggestions; + } + + @Override + public ObservableList getPossibleSuggestions() { + return possibleSuggestions; + } + + @Override + public void setPossibleSuggestions(ObservableList possibleSuggestions){ + this.possibleSuggestions = possibleSuggestions; + } + + @Override + public final Collection call(final AutoCompletionBinding.ISuggestionRequest request) { + List suggestions = new ArrayList<>(); + if(!request.getUserText().isEmpty()){ + suggestions = possibleSuggestions.stream().filter(s -> isMatch(s, request)) + .sorted(getComparator()) + .collect(Collectors.toList()); + } + return suggestions; + } + + protected abstract Comparator getComparator(); + protected abstract boolean isMatch(T suggestion, AutoCompletionBinding.ISuggestionRequest request); + +} diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/AutoCompletion.java b/client/src/main/java/ru/trader/view/support/autocomplete/AutoCompletion.java index 7a6b218..4367654 100644 --- a/client/src/main/java/ru/trader/view/support/autocomplete/AutoCompletion.java +++ b/client/src/main/java/ru/trader/view/support/autocomplete/AutoCompletion.java @@ -3,6 +3,7 @@ package ru.trader.view.support.autocomplete; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; +import javafx.collections.ObservableList; import javafx.scene.control.TextField; import javafx.util.Callback; import javafx.util.StringConverter; @@ -23,27 +24,29 @@ public class AutoCompletion { }; } + private final SuggestionProvider suggestionProvider; private final ObjectProperty completion = new SimpleObjectProperty<>(); - private final StringConverter converter; private final AutoTextFieldBinding binding; private final T notFoundItem; + private StringConverter converter; - public AutoCompletion(final TextField textField, final Callback> suggestionProvider) { + public AutoCompletion(final TextField textField, final SuggestionProvider suggestionProvider) { this(textField, suggestionProvider, null, defaultStringConverter()); } - public AutoCompletion(final TextField textField, final Callback> suggestionProvider, T notFoundItem, final StringConverter converter) { + public AutoCompletion(final TextField textField, final SuggestionProvider suggestionProvider, T notFoundItem, final StringConverter converter) { this.converter = converter; this.notFoundItem = notFoundItem; + this.suggestionProvider = suggestionProvider; binding = new AutoTextFieldBinding(textField, suggestionProvider); - binding.setOnAutoCompleted(e -> completion.setValue(e.getCompletion())); + binding.setOnAutoCompleted(e -> completion.setValue(converter.fromString(e.getCompletion()))); } - public AutoCompletionBinding getBinding() { + public AutoCompletionBinding getBinding() { return binding; } - public T getCompletion() { + public T getValue() { return completion.get(); } @@ -51,7 +54,7 @@ public class AutoCompletion { return binding.getCompletionTarget(); } - public ObjectProperty completionProperty() { + public ObjectProperty valueProperty() { return completion; } @@ -61,14 +64,22 @@ public class AutoCompletion { public void setValue(T value) { completion.setValue(value); - binding.completeUserInput(value); + binding.completeUserInput(converter.toString(value)); } - private class AutoTextFieldBinding extends AutoCompletionBinding{ - public AutoTextFieldBinding(final TextField textField, - Callback> suggestionProvider) { + public void setConverter(StringConverter converter){ + this.converter = converter; + } - super(textField, suggestionProvider, converter); + public void setSuggestions(ObservableList suggestions){ + suggestionProvider.setPossibleSuggestions(suggestions); + } + + private class AutoTextFieldBinding extends AutoCompletionBinding{ + public AutoTextFieldBinding(final TextField textField, + Callback> suggestionProvider) { + + super(textField, suggestionProvider, defaultStringConverter()); getCompletionTarget().textProperty().addListener(textChangeListener); getCompletionTarget().focusedProperty().addListener(focusChangedListener); @@ -86,10 +97,9 @@ public class AutoCompletion { } /** {@inheritDoc} */ - @Override protected void completeUserInput(T completion){ - String newText = converter.toString(completion); - getCompletionTarget().setText(newText); - getCompletionTarget().positionCaret(newText.length()); + @Override protected void completeUserInput(String completion){ + getCompletionTarget().setText(completion); + getCompletionTarget().positionCaret(completion.length()); } private final ChangeListener textChangeListener = (obs, oldText, newText) -> { @@ -100,7 +110,7 @@ public class AutoCompletion { }; private final ChangeListener focusChangedListener = (obs, oldFocused, newFocused) -> { - if(newFocused == false) + if(newFocused != null && !newFocused) hidePopup(); }; } diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/CachedSuggestionProvider.java b/client/src/main/java/ru/trader/view/support/autocomplete/CachedSuggestionProvider.java index 3dc2bdb..25bdb74 100644 --- a/client/src/main/java/ru/trader/view/support/autocomplete/CachedSuggestionProvider.java +++ b/client/src/main/java/ru/trader/view/support/autocomplete/CachedSuggestionProvider.java @@ -1,30 +1,40 @@ package ru.trader.view.support.autocomplete; -import javafx.collections.ListChangeListener; +import javafx.beans.InvalidationListener; 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 implements Callback> { +public class CachedSuggestionProvider implements SuggestionProvider { private final List cache = new ArrayList<>(); private final ReentrantLock lock = new ReentrantLock(); - private ObservableList possibleSuggestions; + private final AbstractSuggestionProvider provider; private AutoCompletionBinding.ISuggestionRequest lastRequest; - protected CachedSuggestionProvider(ObservableList possibleSuggestions) { - this.possibleSuggestions = possibleSuggestions; - possibleSuggestions.addListener(listChangeListener); + public CachedSuggestionProvider(AbstractSuggestionProvider provider) { + this.provider = provider; + provider.getPossibleSuggestions().addListener(listChangeListener); } + @Override + public ObservableList getPossibleSuggestions() { + return provider.getPossibleSuggestions(); + } + + @Override public void setPossibleSuggestions(ObservableList possibleSuggestions){ - this.possibleSuggestions.removeListener(listChangeListener); - this.possibleSuggestions = possibleSuggestions; - cache.clear(); - this.possibleSuggestions.addListener(listChangeListener); + lock.lock(); + try { + provider.getPossibleSuggestions().removeListener(listChangeListener); + provider.setPossibleSuggestions(possibleSuggestions); + cache.clear(); + provider.getPossibleSuggestions().addListener(listChangeListener); + } finally { + lock.unlock(); + } } @Override @@ -36,17 +46,12 @@ public abstract class CachedSuggestionProvider implements Callback iterator = cache.iterator(); while (iterator.hasNext()) { T possibleSuggestion = iterator.next(); - if (!isMatch(possibleSuggestion, request)) { + if (!provider.isMatch(possibleSuggestion, request)) { iterator.remove(); } } @@ -66,14 +71,11 @@ public abstract class CachedSuggestionProvider implements Callback getComparator(); - protected abstract boolean isMatch(T suggestion, AutoCompletionBinding.ISuggestionRequest request); - public void dispose(){ - possibleSuggestions.removeListener(listChangeListener); + provider.getPossibleSuggestions().removeListener(listChangeListener); } - private final ListChangeListener listChangeListener = c -> { + private final InvalidationListener listChangeListener = o -> { lock.lock(); try { lastRequest = null; diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/StationStringConverter.java b/client/src/main/java/ru/trader/view/support/autocomplete/StationStringConverter.java index 5b9cd28..d33ef41 100644 --- a/client/src/main/java/ru/trader/view/support/autocomplete/StationStringConverter.java +++ b/client/src/main/java/ru/trader/view/support/autocomplete/StationStringConverter.java @@ -18,7 +18,7 @@ public class StationStringConverter extends StringConverter { @Override public String toString(StationModel station) { - return station.getSystem().getName()+": "+station.getName(); + return station.getFullName(); } @Override diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/StationsProvider.java b/client/src/main/java/ru/trader/view/support/autocomplete/StationsProvider.java index 0b9705e..b7f6051 100644 --- a/client/src/main/java/ru/trader/view/support/autocomplete/StationsProvider.java +++ b/client/src/main/java/ru/trader/view/support/autocomplete/StationsProvider.java @@ -7,26 +7,26 @@ import ru.trader.model.StationModel; import java.util.Comparator; -public class StationsProvider extends CachedSuggestionProvider { +public class StationsProvider extends AbstractSuggestionProvider { private final StringConverter converter; - private final Comparator comparator; + private final Comparator comparator; public StationsProvider(MarketModel market) { - super(market.stationsProperty()); + super(market.getStationNames()); converter = new StationStringConverter(market); - comparator = (s1, s2) -> converter.toString(s1).toLowerCase().compareTo(converter.toString(s2).toLowerCase()); + comparator = (s1, s2) -> s1.toLowerCase().compareTo(s2.toLowerCase()); } @Override - protected Comparator getComparator() { + protected Comparator getComparator() { return comparator; } @Override - protected boolean isMatch(StationModel suggestion, AutoCompletionBinding.ISuggestionRequest request) { - String s = converter.toString(suggestion).toLowerCase(); + protected boolean isMatch(String suggestion, AutoCompletionBinding.ISuggestionRequest request) { + String s = suggestion.toLowerCase(); return s.contains(request.getUserText().toLowerCase()); } diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/SuggestionProvider.java b/client/src/main/java/ru/trader/view/support/autocomplete/SuggestionProvider.java new file mode 100644 index 0000000..93a8718 --- /dev/null +++ b/client/src/main/java/ru/trader/view/support/autocomplete/SuggestionProvider.java @@ -0,0 +1,14 @@ +package ru.trader.view.support.autocomplete; + +import javafx.collections.ObservableList; +import javafx.util.Callback; +import org.controlsfx.control.textfield.AutoCompletionBinding; + +import java.util.Collection; + + +public interface SuggestionProvider extends Callback> { + ObservableList getPossibleSuggestions(); + + void setPossibleSuggestions(ObservableList possibleSuggestions); +} diff --git a/client/src/main/java/ru/trader/view/support/autocomplete/SystemsProvider.java b/client/src/main/java/ru/trader/view/support/autocomplete/SystemsProvider.java index 39aaed1..033d9d3 100644 --- a/client/src/main/java/ru/trader/view/support/autocomplete/SystemsProvider.java +++ b/client/src/main/java/ru/trader/view/support/autocomplete/SystemsProvider.java @@ -7,27 +7,27 @@ import ru.trader.model.SystemModel; import java.util.Comparator; -public class SystemsProvider extends CachedSuggestionProvider { +public class SystemsProvider extends AbstractSuggestionProvider { private final StringConverter converter; - private final Comparator comparator; + private final Comparator comparator; public SystemsProvider(MarketModel market) { - super(market.systemsProperty()); + super(market.getSystemNames()); converter = new SystemsStringConverter(market); - comparator = (s1, s2) -> converter.toString(s1).toLowerCase().compareTo(converter.toString(s2).toLowerCase()); + comparator = (s1, s2) -> s1.toLowerCase().compareTo(s2.toLowerCase()); } @Override - protected Comparator getComparator() { + protected Comparator getComparator() { return comparator; } @Override - protected boolean isMatch(SystemModel suggestion, AutoCompletionBinding.ISuggestionRequest request) { - String s = converter.toString(suggestion).toLowerCase(); - return s.contains(request.getUserText().toLowerCase()); + protected boolean isMatch(String suggestion, AutoCompletionBinding.ISuggestionRequest request) { + String s = suggestion.toLowerCase(); + return s.startsWith(request.getUserText().toLowerCase()); } public StringConverter getConverter() { diff --git a/client/src/main/java/ru/trader/view/support/cells/StationListCell.java b/client/src/main/java/ru/trader/view/support/cells/StationListCell.java index 91f644b..7aa545e 100644 --- a/client/src/main/java/ru/trader/view/support/cells/StationListCell.java +++ b/client/src/main/java/ru/trader/view/support/cells/StationListCell.java @@ -18,12 +18,10 @@ public class StationListCell implements Callback, ListCel super.updateItem(station, empty); if (!empty){ if (s != station){ - textProperty().unbind(); - textProperty().bind(station.asString()); + setText(station.getFullName()); s = station; } } else { - textProperty().unbind(); s = null; setText(null); setGraphic(null); diff --git a/client/src/main/resources/view/filter.fxml b/client/src/main/resources/view/filter.fxml index e3a350d..a56506f 100644 --- a/client/src/main/resources/view/filter.fxml +++ b/client/src/main/resources/view/filter.fxml @@ -12,6 +12,7 @@ + @@ -20,7 +21,7 @@