Archived
0

- update controlFX to 8.20.6

- support JDK 8u25
- refactoring models
This commit is contained in:
iMoHax
2014-11-08 18:43:17 +03:00
parent 92387f51df
commit eb8a8df171
48 changed files with 1356 additions and 1250 deletions

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@ import ru.trader.emdn.EMDN;
import ru.trader.emdn.ItemData; import ru.trader.emdn.ItemData;
import ru.trader.emdn.Station; import ru.trader.emdn.Station;
import ru.trader.model.MarketModel; import ru.trader.model.MarketModel;
import ru.trader.model.support.VendorUpdater; import ru.trader.model.support.StationUpdater;
import java.util.concurrent.*; import java.util.concurrent.*;
@@ -20,7 +20,7 @@ public class EMDNUpdater {
private static EMDNUpdate emdnUpdater; private static EMDNUpdate emdnUpdater;
private static long interval; private static long interval;
public static void updateFromEMDN(VendorUpdater updater){ public static void updateFromEMDN(StationUpdater updater){
Station emdnData = emdn.get(updater.getName()); Station emdnData = emdn.get(updater.getName());
if (emdnData != null){ if (emdnData != null){
update(updater, emdnData); update(updater, emdnData);
@@ -29,9 +29,9 @@ public class EMDNUpdater {
} }
} }
private static void update(VendorUpdater updater, Station emdnData){ private static void update(StationUpdater updater, Station emdnData){
LOG.trace("Update {} from EMDN", updater.getName()); LOG.trace("Update {} from EMDN", updater.getName());
for (VendorUpdater.FakeOffer offer : updater.getOffers()) { for (StationUpdater.FakeOffer offer : updater.getOffers()) {
if (offer.getItem().isMarketItem()){ if (offer.getItem().isMarketItem()){
ItemData data = emdnData.getData(offer.getItem().getId()); ItemData data = emdnData.getData(offer.getItem().getId());
LOG.trace("Update item {} to {}", offer.getItem().getName(), data); LOG.trace("Update item {} to {}", offer.getItem().getName(), data);
@@ -113,19 +113,20 @@ public class EMDNUpdater {
} }
private static class EMDNUpdate implements Runnable { private static class EMDNUpdate implements Runnable {
private final VendorUpdater updater; private final StationUpdater updater;
private EMDNUpdate() { private EMDNUpdate() {
updater = new VendorUpdater(market); updater = new StationUpdater(market);
} }
@Override @Override
public void run() { public void run() {
market.vendorsProperty().get().forEach((vendor) -> { market.systemsProperty().get().forEach(system -> {
LOG.trace("Auto update {}", vendor); LOG.trace("Auto update {}", system);
Station emdnData = emdn.pop(vendor.getName()); Station emdnData = emdn.pop(system.getName());
if (emdnData != null){ if (emdnData != null){
updater.init(vendor); //TODO: implement new model
//updater.init(system);
update(updater, emdnData); update(updater, emdnData);
updater.commit(); updater.commit();
updater.reset(); updater.reset();

View File

@@ -70,8 +70,8 @@ public class Main extends Application {
try { try {
if (World.getMarket().isChange()){ if (World.getMarket().isChange()){
Action res = Screeners.showConfirm(Localization.getString("dialog.confirm.save")); Action res = Screeners.showConfirm(Localization.getString("dialog.confirm.save"));
if (res == Dialog.Actions.YES) World.save(); if (res == Dialog.ACTION_YES) World.save();
else if (res == Dialog.Actions.CANCEL) we.consume(); else if (res == Dialog.ACTION_CANCEL) we.consume();
} }
EMDNUpdater.shutdown(); EMDNUpdater.shutdown();
SETTINGS.save(); SETTINGS.save();

View File

@@ -3,8 +3,8 @@ package ru.trader;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import ru.trader.core.Market; import ru.trader.core.Market;
import ru.trader.core.MarketAnalyzer; import ru.trader.core.MarketAnalyzer;
import ru.trader.model.ModelFabric;
import ru.trader.store.simple.SimpleMarket; import ru.trader.store.simple.SimpleMarket;
import ru.trader.model.ModelFabrica;
import ru.trader.store.simple.Store; import ru.trader.store.simple.Store;
import ru.trader.store.XSSFImporter; import ru.trader.store.XSSFImporter;
@@ -31,14 +31,12 @@ public class World {
public static void save() throws FileNotFoundException, UnsupportedEncodingException, XMLStreamException { public static void save() throws FileNotFoundException, UnsupportedEncodingException, XMLStreamException {
Store.saveToFile(world, new File("world.xml")); Store.saveToFile(world, new File("world.xml"));
world.setChange(false); world.commit();
} }
public static void imp(File file) throws IOException, SAXException { public static void imp(File file) throws IOException, SAXException {
XSSFImporter xssfImporter = new XSSFImporter(file); XSSFImporter xssfImporter = new XSSFImporter(file);
world = xssfImporter.doImport(); world = xssfImporter.doImport();
ModelFabrica.clear();
world.setChange(true);
} }
public static Market getMarket() { public static Market getMarket() {

View File

@@ -15,7 +15,7 @@ import ru.trader.model.*;
public class ItemDescController { public class ItemDescController {
private ItemDescModel item; private ItemModel item;
@FXML @FXML
private ListView<OfferModel> seller; private ListView<OfferModel> seller;
@@ -23,7 +23,7 @@ public class ItemDescController {
@FXML @FXML
private ListView<OfferModel> buyer; private ListView<OfferModel> buyer;
public void setItemDesc(ItemDescModel itemDesc){ public void setItemDesc(ItemModel itemDesc){
item = itemDesc; item = itemDesc;
if (popup!=null) popup.setDetachedTitle(item.nameProperty().get()); if (popup!=null) popup.setDetachedTitle(item.nameProperty().get());
fill(); fill();

View File

@@ -2,6 +2,7 @@ package ru.trader.controllers;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
@@ -10,6 +11,7 @@ import javafx.scene.input.MouseButton;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.model.*; import ru.trader.model.*;
import ru.trader.model.support.BindingsHelper;
import ru.trader.model.support.ChangeMarketListener; import ru.trader.model.support.ChangeMarketListener;
import ru.trader.model.support.ModelBindings; import ru.trader.model.support.ModelBindings;
@@ -18,14 +20,16 @@ public class ItemsController {
private final static Logger LOG = LoggerFactory.getLogger(ItemsController.class); private final static Logger LOG = LoggerFactory.getLogger(ItemsController.class);
@FXML @FXML
private TableView<ItemDescModel> tblItems; private TableView<ItemModel> tblItems;
@FXML @FXML
private TableColumn<ItemDescModel, Number> minProfit; private TableColumn<ItemModel, Number> minProfit;
@FXML @FXML
private TableColumn<ItemDescModel, Number> avgProfit; private TableColumn<ItemModel, Number> avgProfit;
@FXML @FXML
private TableColumn<ItemDescModel, Number> maxProfit; private TableColumn<ItemModel, Number> maxProfit;
private final ObservableList<ItemModel> items = FXCollections.observableArrayList();
@FXML @FXML
private void initialize() { private void initialize() {
@@ -38,24 +42,26 @@ public class ItemsController {
} }
}); });
minProfit.setCellValueFactory((data) -> { minProfit.setCellValueFactory((data) -> {
ItemDescModel iDesc = data.getValue(); ItemModel iDesc = data.getValue();
return ModelBindings.diff(iDesc.minBuyProperty(),iDesc.maxSellProperty()); return ModelBindings.diff(iDesc.minBuyProperty(),iDesc.maxSellProperty());
}); });
avgProfit.setCellValueFactory((data) -> { avgProfit.setCellValueFactory((data) -> {
ItemDescModel iDesc = data.getValue(); ItemModel iDesc = data.getValue();
return iDesc.avgBuyProperty().subtract(iDesc.avgSellProperty()); return iDesc.avgBuyProperty().subtract(iDesc.avgSellProperty());
}); });
maxProfit.setCellValueFactory((data) -> { maxProfit.setCellValueFactory((data) -> {
ItemDescModel iDesc = data.getValue(); ItemModel iDesc = data.getValue();
return ModelBindings.diff(iDesc.maxBuyProperty(), iDesc.minSellProperty()); return ModelBindings.diff(iDesc.maxBuyProperty(), iDesc.minSellProperty());
}); });
BindingsHelper.setTableViewItems(tblItems, items);
init(); init();
} }
void init(){ void init(){
MarketModel market = MainController.getMarket(); MarketModel market = MainController.getMarket();
market.addListener(new ItemsStatChangeListener()); market.getNotificator().add(new ItemsStatChangeListener());
tblItems.setItems(FXCollections.observableArrayList(market.itemsProperty())); items.clear();
items.addAll(market.itemsProperty());
sort(); sort();
} }
@@ -64,53 +70,41 @@ public class ItemsController {
tblItems.sort(); tblItems.sort();
} }
private void refresh(OfferModel offer){
LOG.info("Refresh item desc link with item of offer {}", offer);
for (ItemDescModel descModel : tblItems.getItems()) {
if (descModel.hasItem(offer)){
descModel.refresh(offer.getType());
sort();
return;
}
}
}
private void refresh(){ private void refresh(){
LOG.info("Refresh all stats"); LOG.info("Refresh all stats");
tblItems.getItems().forEach(ItemDescModel::refresh); tblItems.getItems().forEach(ItemModel::refresh);
sort(); sort();
} }
private void addItem(ItemDescModel item){ private void addItem(ItemModel item){
tblItems.getItems().add(item); items.add(item);
sort();
} }
private class ItemsStatChangeListener extends ChangeMarketListener { private class ItemsStatChangeListener extends ChangeMarketListener {
@Override @Override
public void add(ItemDescModel item) { public void add(ItemModel item) {
addItem(item); addItem(item);
} }
@Override @Override
public void add(OfferModel offer) { public void add(StationModel station) {
refresh(offer);
}
@Override
public void add(VendorModel vendor) {
refresh(); refresh();
} }
@Override
public void add(OfferModel offer) {
sort();
}
@Override @Override
public void remove(OfferModel offer) { public void remove(OfferModel offer) {
refresh(offer); sort();
} }
@Override @Override
public void priceChange(OfferModel offer, double price, double value) { public void priceChange(OfferModel offer, double price, double value) {
refresh(offer); sort();
} }
} }

View File

@@ -90,9 +90,7 @@ public class MainController {
} }
public void setMarket(MarketModel market) { public void setMarket(MarketModel market) {
MarketModel old = MainController.market;
MainController.market = market; MainController.market = market;
MainController.market.addAllListener(old.getListeners());
Screeners.reinitAll(); Screeners.reinitAll();
} }
@@ -134,19 +132,35 @@ public class MainController {
.showTextInput(); .showTextInput();
ItemModel item = null; ItemModel item = null;
if (res.isPresent()){ if (res.isPresent()){
item = market.newItem(res.get()); //TODO: implement groups
market.add(item); // item = market.add(res.get());
} }
return Optional.ofNullable(item); return Optional.ofNullable(item);
} }
public void addVendor(ActionEvent actionEvent) { public void addSystem(ActionEvent actionEvent){
Screeners.showAddVendor(); //TODO: implement
} }
public void editVendor(ActionEvent actionEvent) { public void editSystem(ActionEvent actionEvent){
Screeners.showEditVendor(offersController.getVendor()); //TODO: implement
}
public void removeSystem(ActionEvent actionEvent){
//TODO: implement
}
public void addStation(ActionEvent actionEvent) {
Screeners.showAddStation(offersController.getSystem());
}
public void editStation(ActionEvent actionEvent) {
Screeners.showEditStation(offersController.getStation());
}
public void removeStation(ActionEvent actionEvent){
//TODO: implement
} }
public void editSettings(){ public void editSettings(){

View File

@@ -3,81 +3,125 @@ package ru.trader.controllers;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.scene.control.ListView; import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton; import javafx.scene.input.MouseButton;
import javafx.scene.layout.Background;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import org.controlsfx.control.SegmentedButton;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import ru.trader.model.*; import ru.trader.model.*;
import ru.trader.model.support.BindingsHelper;
import ru.trader.model.support.ChangeMarketListener; import ru.trader.model.support.ChangeMarketListener;
import java.util.Collection; import java.util.List;
import java.util.Iterator;
public class OffersController { public class OffersController {
private final static Logger LOG = LoggerFactory.getLogger(OffersController.class); private final static Logger LOG = LoggerFactory.getLogger(OffersController.class);
private VendorModel vendor; private StationModel station;
private SystemModel system;
@FXML @FXML
private ListView<VendorModel> vendors; private Insets stationsMargin;
@FXML @FXML
private TableView<OfferDescModel> tblSell; private ListView<SystemModel> systems;
@FXML @FXML
private TableView<OfferDescModel> tblBuy; private SegmentedButton stationsBar;
@FXML
private TableView<OfferModel> tblSell;
@FXML
private TableView<OfferModel> tblBuy;
private final List<OfferModel> sells = FXCollections.observableArrayList();
private final List<OfferModel> buys = FXCollections.observableArrayList();
private final static ToggleGroup stationsGrp = new ToggleGroup();
// инициализируем форму данными // инициализируем форму данными
@FXML @FXML
private void initialize() { private void initialize() {
vendors.getSelectionModel().selectedItemProperty().addListener((ob, oldValue, newValue) ->{ systems.getSelectionModel().selectedItemProperty().addListener((ob, oldValue, newValue) ->{
if (newValue != null){ if (newValue != null){
LOG.info("Change vendor to {}", newValue); LOG.info("Change system to {}", newValue);
this.vendor = newValue; fillDetails(newValue);
fillTables(vendor);
} else { } else {
vendors.getSelectionModel().select(oldValue); systems.getSelectionModel().select(oldValue);
} }
}); });
stationsGrp.selectedToggleProperty().addListener((v, o, n) -> {
if (n != null){
fillTables((StationModel) n.getUserData());
} else {
fillTables(null);
}
});
stationsBar.setToggleGroup(stationsGrp);
tblSell.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> { tblSell.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> {
if (n!=null) Screeners.changeItemDesc(n); if (n != null) Screeners.changeItemDesc(n.getItem());
}); });
tblBuy.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> { tblBuy.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> {
if (n!=null) Screeners.changeItemDesc(n); if (n != null) Screeners.changeItemDesc(n.getItem());
}); });
tblSell.setOnMouseClicked((e) -> { tblSell.setOnMouseClicked((e) -> {
if (e.getButton() == MouseButton.SECONDARY){ if (e.getButton() == MouseButton.SECONDARY) {
Screeners.showItemDesc(tblSell); Screeners.showItemDesc(tblSell);
} }
}); });
tblBuy.setOnMouseClicked((e) -> { tblBuy.setOnMouseClicked((e) -> {
if (e.getButton() == MouseButton.SECONDARY){ if (e.getButton() == MouseButton.SECONDARY) {
Screeners.showItemDesc(tblBuy); Screeners.showItemDesc(tblBuy);
} }
}); });
BindingsHelper.setTableViewItems(tblSell, sells);
BindingsHelper.setTableViewItems(tblBuy, buys);
init(); init();
} }
void init(){ void init(){
MarketModel market = MainController.getMarket(); MarketModel market = MainController.getMarket();
market.addListener(new OffersChangeListener()); market.getNotificator().add(new OffersChangeListener());
vendors.setItems(market.vendorsProperty()); systems.setItems(market.systemsProperty());
vendors.getSelectionModel().selectFirst(); systems.getSelectionModel().selectFirst();
} }
private void fillTables(VendorModel vendor){ private void fillDetails(SystemModel system){
if (vendor != null){ this.system = system;
tblSell.setItems(FXCollections.observableList(vendor.getSells(this::asOfferDescModel))); List<StationModel> stations = system.getStations();
tblBuy.setItems(FXCollections.observableList(vendor.getBuys(this::asOfferDescModel))); stationsBar.getButtons().clear();
sort(); stations.forEach(s -> stationsBar.getButtons().add(buildStationNode(s)));
} else { if (!stations.isEmpty()){
tblSell.getItems().clear(); stationsBar.getButtons().get(0).setSelected(true);
tblBuy.getItems().clear(); }
station = stations.isEmpty() ? null : stations.get(0);
LOG.info("Change station to {}", station);
fillTables(station);
}
private ToggleButton buildStationNode(StationModel station){
ToggleButton stationBtn = new ToggleButton(station.getName());
stationBtn.setUserData(station);
return stationBtn;
}
private void fillTables(StationModel station){
sells.clear();
buys.clear();
if (station != null){
sells.addAll(station.getSells());
buys.addAll(station.getBuys());
} }
} }
@@ -94,108 +138,77 @@ public class OffersController {
@FXML @FXML
public void editPrice(TableColumn.CellEditEvent<OfferDescModel, Double> event){ public void editPrice(TableColumn.CellEditEvent<OfferModel, Double> event){
OfferModel offer = event.getRowValue().getOffer(); OfferModel offer = event.getRowValue();
offer.setPrice(event.getNewValue()); offer.setPrice(event.getNewValue());
} }
public VendorModel getVendor() { public SystemModel getSystem() {
return vendor; return system;
} }
public void addVendor(ActionEvent actionEvent) { public StationModel getStation() {
Screeners.showAddVendor(); return station;
} }
public void editVendor(ActionEvent actionEvent) { public void addStation(ActionEvent actionEvent) {
Screeners.showEditVendor(vendor); Screeners.showAddStation(system);
} }
public void editStation(ActionEvent actionEvent) {
private OfferDescModel asOfferDescModel(OfferModel offer){ Screeners.showEditStation(station);
return MainController.getMarket().asOfferDescModel(offer);
} }
private void addOffer(OfferModel offer){ private void addOffer(OfferModel offer){
switch (offer.getType()){ switch (offer.getType()){
case SELL: tblSell.getItems().add(asOfferDescModel(offer)); case SELL: sells.add(offer);
break; break;
case BUY: tblBuy.getItems().add(asOfferDescModel(offer)); case BUY: buys.add(offer);
break; break;
} }
} }
private void removeOffer(OfferModel offer){ private void removeOffer(OfferModel offer){
switch (offer.getType()){ switch (offer.getType()){
case SELL: remove(offer, tblSell.getItems()); case SELL: sells.remove(offer);
break; break;
case BUY: remove(offer, tblBuy.getItems()); case BUY: buys.remove(offer);
break; break;
} }
} }
private void remove(final OfferModel offer, final Collection<OfferDescModel> list){
Iterator<OfferDescModel> iterator = list.iterator();
while (iterator.hasNext()){
if (iterator.next().getOffer().equals(offer)){
iterator.remove();
break;
}
}
}
private void refresh(OfferModel offer){
LOG.info("Refresh lists link with item of offer {}", offer);
for (OfferDescModel descModel : tblSell.getItems()) {
if (descModel.hasItem(offer)){
descModel.refresh(offer.getType());
sort();
return;
}
}
for (OfferDescModel descModel : tblBuy.getItems()) {
if (descModel.hasItem(offer)){
descModel.refresh(offer.getType());
sort();
return;
}
}
}
private void refresh(){ private void refresh(){
LOG.info("Refresh lists"); LOG.info("Refresh lists");
tblSell.getItems().forEach(OfferDescModel::refresh); tblSell.getItems().forEach(OfferModel::refresh);
tblBuy.getItems().forEach(OfferDescModel::refresh); tblBuy.getItems().forEach(OfferModel::refresh);
sort();
} }
private class OffersChangeListener extends ChangeMarketListener { private class OffersChangeListener extends ChangeMarketListener {
@Override @Override
public void priceChange(OfferModel offer, double oldPrice, double newPrice) { public void priceChange(OfferModel offer, double oldPrice, double newPrice) {
if (vendor.hasBuy(offer.getItem()) || vendor.hasSell(offer.getItem())){ if (station.hasBuy(offer.getItem()) || station.hasSell(offer.getItem())){
sort(); sort();
} }
} }
@Override @Override
public void add(OfferModel offer) { public void add(OfferModel offer) {
refresh(offer); if (offer.getStation().equals(station)){
if (offer.hasVendor(vendor)){
addOffer(offer); addOffer(offer);
} }
} }
@Override @Override
public void add(VendorModel vendor) { public void add(StationModel station) {
refresh(); refresh();
sort();
} }
@Override @Override
public void remove(OfferModel offer) { public void remove(OfferModel offer) {
refresh(offer); if (offer.getStation().equals(station)){
if (offer.hasVendor(vendor)) {
removeOffer(offer); removeOffer(offer);
} }
} }

View File

@@ -1,31 +1,19 @@
package ru.trader.controllers; package ru.trader.controllers;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import org.controlsfx.control.ButtonBar; import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogAction;
import ru.trader.model.ItemModel; import ru.trader.model.ItemModel;
import ru.trader.view.support.NumberField; import ru.trader.view.support.NumberField;
import java.util.Optional; import java.util.Optional;
public class OffersEditorController { public class OffersEditorController {
private final Action OK = new AbstractAction("OK") { private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false);
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
dlg.hide();
}
};
@FXML @FXML
@@ -48,7 +36,7 @@ public class OffersEditorController {
Dialog dlg = new Dialog(parent, "Создание заказов"); Dialog dlg = new Dialog(parent, "Создание заказов");
dlg.setContent(content); dlg.setContent(content);
dlg.getActions().addAll(OK, Dialog.Actions.CANCEL); dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL);
dlg.setResizable(false); dlg.setResizable(false);
return Optional.ofNullable(dlg.show() == OK ? new DialogResult() : null); return Optional.ofNullable(dlg.show() == OK ? new DialogResult() : null);
} }

View File

@@ -2,7 +2,6 @@ package ru.trader.controllers;
import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
@@ -10,30 +9,22 @@ import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.LongStringConverter; import javafx.util.converter.LongStringConverter;
import org.controlsfx.control.ButtonBar; import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import ru.trader.model.OfferDescModel; import org.controlsfx.dialog.DialogAction;
import ru.trader.model.OfferModel; import ru.trader.model.OfferModel;
import ru.trader.model.OrderModel; import ru.trader.model.OrderModel;
import ru.trader.model.support.BindingsHelper; import ru.trader.model.support.BindingsHelper;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
public class OrdersController { public class OrdersController {
private final Action OK = new AbstractAction("OK") { private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false);
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
dlg.hide();
}
};
@FXML @FXML
private TableView<OrderModel> tblOrders; private TableView<OrderModel> tblOrders;
@@ -53,6 +44,8 @@ public class OrdersController {
@FXML @FXML
private TableColumn<OfferModel, Double> curDistance; private TableColumn<OfferModel, Double> curDistance;
private final List<OrderModel> orders = FXCollections.observableArrayList();
private final List<OfferModel> buyers = FXCollections.observableArrayList();
private OrderModel order; private OrderModel order;
@FXML @FXML
@@ -67,42 +60,41 @@ public class OrdersController {
}); });
curDistance.setCellValueFactory(param -> { curDistance.setCellValueFactory(param -> {
OfferModel offer = param.getValue(); OfferModel offer = param.getValue();
return new SimpleDoubleProperty(order !=null ? order.getVendor().getDistance(offer.getVendor()) :Double.NaN).asObject(); return new SimpleDoubleProperty(order !=null ? order.getStation().getDistance(offer.getStation()) :Double.NaN).asObject();
}); });
BindingsHelper.setTableViewItems(tblOrders, orders);
BindingsHelper.setTableViewItems(tblBuyers, buyers);
} }
public Collection<OrderModel> showDialog(Parent parent, Parent content, Collection<OfferDescModel> offers, double balance, long max) { public Collection<OrderModel> showDialog(Parent parent, Parent content, Collection<OfferModel> offers, double balance, long max) {
init(offers, balance, max); init(offers, balance, max);
Dialog dlg = new Dialog(parent, Localization.getString("orders.title")); Dialog dlg = new Dialog(parent, Localization.getString("orders.title"));
dlg.setContent(content); dlg.setContent(content);
dlg.getActions().addAll(OK, Dialog.Actions.CANCEL); dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL);
dlg.setResizable(false); dlg.setResizable(false);
Collection<OrderModel> res = dlg.show() == OK ? getOrders() : null; Collection<OrderModel> res = dlg.show() == OK ? getOrders() : null;
tblOrders.getItems().clear(); orders.clear();
return res; return res;
} }
private Collection<OrderModel> getOrders() { private List<OrderModel> getOrders() {
return tblOrders.getItems().filtered((o) -> o.getCount()>0 && o.getBuyOffer()!=null); return orders.stream().filter(o -> o.getCount() > 0 && o.getBuyOffer() != null).collect(toList());
} }
private void init(Collection<OfferDescModel> offers, double balance, long max) { private void init(Collection<OfferModel> offers, double balance, long max) {
tblOrders.setItems(BindingsHelper.observableList(offers, (o) -> new OrderModel(o, balance, max))); orders.clear();
if (tblOrders.getSortOrder().size()>0) offers.forEach(o -> orders.add(new OrderModel(o, balance, max)));
tblOrders.sort();
} }
private void changeOrder(OrderModel order) { private void changeOrder(OrderModel order) {
this.order = order; this.order = order;
if (order != null) tblBuyers.setItems(FXCollections.observableList(order.getBuyers())); buyers.clear();
else tblBuyers.setItems(FXCollections.emptyObservableList()); if (order != null) buyers.addAll(order.getBuyers());
tblBuyers.getSelectionModel().clearSelection(); tblBuyers.getSelectionModel().clearSelection();
if (tblBuyers.getSortOrder().size()>0)
tblBuyers.sort();
} }
private void setBuyer(OfferModel offer) { private void setBuyer(OfferModel offer) {

View File

@@ -1,40 +1,31 @@
package ru.trader.controllers; package ru.trader.controllers;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
import org.controlsfx.control.ButtonBar; import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogAction;
import ru.trader.model.PathRouteModel; import ru.trader.model.PathRouteModel;
import ru.trader.model.support.BindingsHelper;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
import java.util.Collection; import java.util.Collection;
import java.util.List;
public class PathsController { public class PathsController {
private final Action OK = new AbstractAction("OK") { private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false);
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
dlg.hide();
}
};
@FXML @FXML
private TableView<PathRouteModel> tblPaths; private TableView<PathRouteModel> tblPaths;
private final List<PathRouteModel> paths = FXCollections.observableArrayList();
@FXML @FXML
private void initialize() { private void initialize() {
BindingsHelper.setTableViewItems(tblPaths, paths);
} }
@@ -44,10 +35,10 @@ public class PathsController {
Dialog dlg = new Dialog(parent, Localization.getString("paths.title")); Dialog dlg = new Dialog(parent, Localization.getString("paths.title"));
dlg.setContent(content); dlg.setContent(content);
dlg.getActions().addAll(OK, Dialog.Actions.CANCEL); dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL);
dlg.setResizable(false); dlg.setResizable(false);
PathRouteModel res = dlg.show() == OK ? getPath() : null; PathRouteModel res = dlg.show() == OK ? getPath() : null;
tblPaths.getItems().clear(); paths.clear();
return res; return res;
} }
@@ -57,9 +48,8 @@ public class PathsController {
private void init(Collection<PathRouteModel> paths) { private void init(Collection<PathRouteModel> paths) {
tblPaths.getSelectionModel().clearSelection(); tblPaths.getSelectionModel().clearSelection();
tblPaths.setItems(FXCollections.observableArrayList(paths)); this.paths.clear();
if (tblPaths.getSortOrder().size()>0) this.paths.addAll(paths);
tblPaths.sort();
} }
} }

View File

@@ -11,9 +11,12 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
import ru.trader.Main; import ru.trader.Main;
import ru.trader.model.*; import ru.trader.model.*;
import ru.trader.model.support.BindingsHelper;
import ru.trader.view.support.NumberField; import ru.trader.view.support.NumberField;
import ru.trader.view.support.RouteNode; import ru.trader.view.support.RouteNode;
import java.util.List;
public class RouterController { public class RouterController {
@@ -38,9 +41,9 @@ public class RouterController {
private Button removeBtn; private Button removeBtn;
@FXML @FXML
private ComboBox<VendorModel> source; private ComboBox<SystemModel> source;
@FXML @FXML
private ComboBox<VendorModel> target; private ComboBox<SystemModel> target;
@FXML @FXML
private TableView<OrderModel> tblOrders; private TableView<OrderModel> tblOrders;
@@ -52,8 +55,8 @@ public class RouterController {
private NumberField totalBalance; private NumberField totalBalance;
private MarketModel market; private MarketModel market;
private PathRouteModel route; private PathRouteModel route;
private final List<OrderModel> orders = FXCollections.observableArrayList();
@FXML @FXML
private void initialize(){ private void initialize(){
@@ -63,19 +66,19 @@ public class RouterController {
Main.SETTINGS.setBalance(n.doubleValue()); Main.SETTINGS.setBalance(n.doubleValue());
}); });
cargo.numberProperty().addListener((ov, o, n) -> { cargo.numberProperty().addListener((ov, o, n) -> {
market.setCargo(n.intValue()); market.getAnalyzer().setCargo(n.intValue());
Main.SETTINGS.setCargo(n.intValue()); Main.SETTINGS.setCargo(n.intValue());
}); });
tank.numberProperty().addListener((ov, o, n) -> { tank.numberProperty().addListener((ov, o, n) -> {
market.setTank(n.doubleValue()); market.getAnalyzer().setTank(n.doubleValue());
Main.SETTINGS.setTank(n.doubleValue()); Main.SETTINGS.setTank(n.doubleValue());
}); });
distance.numberProperty().addListener((ov, o, n) -> { distance.numberProperty().addListener((ov, o, n) -> {
market.setDistance(n.doubleValue()); market.getAnalyzer().setMaxDistance(n.doubleValue());
Main.SETTINGS.setDistance(n.doubleValue()); Main.SETTINGS.setDistance(n.doubleValue());
}); });
jumps.numberProperty().addListener((ov, o, n) -> { jumps.numberProperty().addListener((ov, o, n) -> {
market.setJumps(n.intValue()); market.getAnalyzer().setJumps(n.intValue());
Main.SETTINGS.setJumps(n.intValue()); Main.SETTINGS.setJumps(n.intValue());
}); });
@@ -97,8 +100,7 @@ public class RouterController {
return sel == -1 || sel != tblOrders.getItems().size()-1; return sel == -1 || sel != tblOrders.getItems().size()-1;
}, tblOrders.getSelectionModel().selectedIndexProperty())); }, tblOrders.getSelectionModel().selectedIndexProperty()));
BindingsHelper.setTableViewItems(tblOrders, orders);
tblOrders.setItems(FXCollections.observableArrayList());
tblOrders.getItems().addListener((ListChangeListener<OrderModel>) c -> { tblOrders.getItems().addListener((ListChangeListener<OrderModel>) c -> {
while (c.next()) { while (c.next()) {
if (c.wasRemoved()){ if (c.wasRemoved()){
@@ -114,11 +116,12 @@ public class RouterController {
void init(){ void init(){
market = MainController.getMarket(); market = MainController.getMarket();
source.setItems(market.vendorsProperty()); source.setItems(market.systemsProperty());
source.getSelectionModel().selectFirst(); source.getSelectionModel().selectFirst();
target.setItems(FXCollections.observableArrayList(market.vendorsProperty())); target.setItems(FXCollections.observableArrayList(market.systemsProperty()));
target.getItems().add(0, null); target.getItems().add(0, ModelFabric.NONE_SYSTEM);
tblOrders.getItems().clear(); target.getSelectionModel().selectFirst();
orders.clear();
totalBalance.setValue(balance.getValue()); totalBalance.setValue(balance.getValue());
totalProfit.setValue(0); totalProfit.setValue(0);
} }
@@ -127,15 +130,15 @@ public class RouterController {
private void onAdd(OrderModel order){ private void onAdd(OrderModel order){
totalProfit.add(order.getProfit()); totalProfit.add(order.getProfit());
totalBalance.add(order.getProfit()); totalBalance.add(order.getProfit());
source.getSelectionModel().select(order.getBuyOffer().getVendor()); source.getSelectionModel().select(order.getBuyOffer().getSystem());
balance.setDisable(true); balance.setDisable(true);
} }
private void onRemove(OrderModel order) { private void onRemove(OrderModel order) {
totalProfit.sub(order.getProfit()); totalProfit.sub(order.getProfit());
totalBalance.sub(order.getProfit()); totalBalance.sub(order.getProfit());
source.getSelectionModel().select(order.getVendor()); source.getSelectionModel().select(order.getStation().getSystem());
if (tblOrders.getItems().isEmpty()) { if (orders.isEmpty()) {
balance.setDisable(false); balance.setDisable(false);
source.setDisable(false); source.setDisable(false);
} }
@@ -145,7 +148,7 @@ public class RouterController {
OrderModel sel = tblOrders.getSelectionModel().getSelectedItem(); OrderModel sel = tblOrders.getSelectionModel().getSelectedItem();
int index = tblOrders.getSelectionModel().getSelectedIndex(); int index = tblOrders.getSelectionModel().getSelectedIndex();
OrderModel order = Screeners.showOrders(market.getOrders(sel.getVendor(), sel.getBuyer(), sel.getBalance())); OrderModel order = Screeners.showOrders(market.getOrders(sel.getStation(), sel.getBuyer(), sel.getBalance()));
if (order!=null){ if (order!=null){
tblOrders.getItems().set(index, order); tblOrders.getItems().set(index, order);
} }
@@ -178,37 +181,38 @@ public class RouterController {
public void showTopOrders(){ public void showTopOrders(){
OrderModel order = Screeners.showOrders(market.getTop(totalBalance.getValue().doubleValue())); OrderModel order = Screeners.showOrders(market.getTop(totalBalance.getValue().doubleValue()));
if (order!=null){ if (order!=null){
tblOrders.getItems().add(order); orders.add(order);
addOrderToPath(order); addOrderToPath(order);
} }
} }
public void showOrders(){ public void showOrders(){
VendorModel s = source.getSelectionModel().getSelectedItem(); //TODO: fix set balanace
VendorModel t = target.getSelectionModel().getSelectedItem(); SystemModel s = source.getSelectionModel().getSelectedItem();
SystemModel t = target.getSelectionModel().getSelectedItem();
OrderModel order; OrderModel order;
if (t==null){ if (t == ModelFabric.NONE_SYSTEM){
order = Screeners.showOrders(market.getOrders(s, totalBalance.getValue().doubleValue())); order = Screeners.showOrders(market.getOrders(s, totalBalance.getValue().doubleValue()));
} else { } else {
order = Screeners.showOrders(market.getOrders(s, t, totalBalance.getValue().doubleValue())); order = Screeners.showOrders(market.getOrders(s, t, totalBalance.getValue().doubleValue()));
} }
if (order!=null){ if (order!=null){
tblOrders.getItems().add(order); orders.add(order);
addOrderToPath(order); addOrderToPath(order);
} }
} }
public void showRoutes(){ public void showRoutes(){
VendorModel s = source.getSelectionModel().getSelectedItem(); SystemModel s = source.getSelectionModel().getSelectedItem();
VendorModel t = target.getSelectionModel().getSelectedItem(); SystemModel t = target.getSelectionModel().getSelectedItem();
PathRouteModel path; PathRouteModel path;
if (t==null){ if (t == ModelFabric.NONE_SYSTEM){
path = Screeners.showRouters(market.getRoutes(s, totalBalance.getValue().doubleValue())); path = Screeners.showRouters(market.getRoutes(s, totalBalance.getValue().doubleValue()));
} else { } else {
path = Screeners.showRouters(market.getRoutes(s, t, totalBalance.getValue().doubleValue())); path = Screeners.showRouters(market.getRoutes(s, t, totalBalance.getValue().doubleValue()));
} }
if (path!=null){ if (path!=null){
tblOrders.getItems().addAll(path.getOrders()); orders.addAll(path.getOrders());
addRouteToPath(path); addRouteToPath(path);
} }
} }
@@ -216,7 +220,7 @@ public class RouterController {
public void showTopRoutes(){ public void showTopRoutes(){
PathRouteModel path = Screeners.showRouters(market.getTopRoutes(totalBalance.getValue().doubleValue())); PathRouteModel path = Screeners.showRouters(market.getTopRoutes(totalBalance.getValue().doubleValue()));
if (path!=null){ if (path!=null){
tblOrders.getItems().addAll(path.getOrders()); orders.addAll(path.getOrders());
addRouteToPath(path); addRouteToPath(path);
} }
} }

View File

@@ -31,7 +31,7 @@ public class Screeners {
private static MainController mainController; private static MainController mainController;
private static ItemDescController itemDescController; private static ItemDescController itemDescController;
private static VendorEditorController vEditorController; private static StationEditorController vEditorController;
private static OffersEditorController oEditorController; private static OffersEditorController oEditorController;
private static OrdersController ordersController; private static OrdersController ordersController;
private static TopOrdersController topOrdersController; private static TopOrdersController topOrdersController;
@@ -131,12 +131,12 @@ public class Screeners {
return Dialogs.create().owner(mainScreen).message(text).showConfirm(); return Dialogs.create().owner(mainScreen).message(text).showConfirm();
} }
public static void showAddVendor(){ public static void showAddStation(SystemModel system){
vEditorController.showDialog(mainScreen, vEditorScreen, null); vEditorController.showDialog(mainScreen, vEditorScreen, system, null);
} }
public static void showEditVendor(VendorModel vendor){ public static void showEditStation(StationModel station){
vEditorController.showDialog(mainScreen, vEditorScreen, vendor); vEditorController.showDialog(mainScreen, vEditorScreen, station);
} }
public static Parent getMainScreen(){ public static Parent getMainScreen(){
@@ -148,11 +148,11 @@ public class Screeners {
} }
public static Collection<OrderModel> showOrders(Collection<OfferDescModel> offers, double balance, long cargo) { public static Collection<OrderModel> showOrders(Collection<OfferModel> offers, double balance, long cargo) {
return ordersController.showDialog(mainScreen, ordersScreen, offers, balance, cargo); return ordersController.showDialog(mainScreen, ordersScreen, offers, balance, cargo);
} }
public static void changeItemDesc(ItemDescModel item){ public static void changeItemDesc(ItemModel item){
itemDescController.setItemDesc(item); itemDescController.setItemDesc(item);
} }

View File

@@ -1,21 +1,18 @@
package ru.trader.controllers; package ru.trader.controllers;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import org.controlsfx.control.ButtonBar; import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogAction;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.EMDNUpdater; import ru.trader.EMDNUpdater;
import ru.trader.Main; import ru.trader.Main;
import ru.trader.World;
import ru.trader.core.MarketAnalyzer; import ru.trader.core.MarketAnalyzer;
import ru.trader.emdn.EMDN;
import ru.trader.model.MarketModel; import ru.trader.model.MarketModel;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
import ru.trader.view.support.NumberField; import ru.trader.view.support.NumberField;
@@ -37,18 +34,8 @@ public class SettingsController {
@FXML @FXML
private NumberField pathsCount; private NumberField pathsCount;
private final Action actSave = new AbstractAction(Localization.getString("dialog.button.save")) { private final Action actSave = new DialogAction(Localization.getString("dialog.button.save"), ButtonBar.ButtonType.OK_DONE, false, true, false, (e) -> save());
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
save();
dlg.hide();
}
};
@FXML @FXML
private void initialize(){ private void initialize(){
@@ -73,11 +60,11 @@ public class SettingsController {
EMDNUpdater.setUpdateOnly(emdnUpdateOnly.isSelected()); EMDNUpdater.setUpdateOnly(emdnUpdateOnly.isSelected());
Main.SETTINGS.setEMDNAutoUpdate(emdnUpdateTime.getValue().longValue()); Main.SETTINGS.setEMDNAutoUpdate(emdnUpdateTime.getValue().longValue());
EMDNUpdater.setInterval(emdnUpdateTime.getValue().longValue()); EMDNUpdater.setInterval(emdnUpdateTime.getValue().longValue());
MarketModel market = MainController.getMarket(); MarketAnalyzer analyzer = MainController.getMarket().getAnalyzer();
Main.SETTINGS.setSegmentSize(segmentSize.getValue().intValue()); Main.SETTINGS.setSegmentSize(segmentSize.getValue().intValue());
market.setSegmetnSize(segmentSize.getValue().intValue()); analyzer.setSegmentSize(segmentSize.getValue().intValue());
Main.SETTINGS.setPathsCount(pathsCount.getValue().intValue()); Main.SETTINGS.setPathsCount(pathsCount.getValue().intValue());
market.setLimit(pathsCount.getValue().intValue()); analyzer.setPathsCount(pathsCount.getValue().intValue());
} }
@@ -85,7 +72,7 @@ public class SettingsController {
init(); init();
Dialog dlg = new Dialog(parent, Localization.getString("settings.title")); Dialog dlg = new Dialog(parent, Localization.getString("settings.title"));
dlg.setContent(content); dlg.setContent(content);
dlg.getActions().addAll(actSave, Dialog.Actions.CANCEL); dlg.getActions().addAll(actSave, Dialog.ACTION_CANCEL);
dlg.setResizable(false); dlg.setResizable(false);
return dlg.show(); return dlg.show();
} }

View File

@@ -1,23 +1,19 @@
package ru.trader.controllers; package ru.trader.controllers;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import org.controlsfx.control.ButtonBar; import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.DefaultDialogAction;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogAction;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.EMDNUpdater; import ru.trader.EMDNUpdater;
import ru.trader.emdn.ItemData;
import ru.trader.emdn.Station;
import ru.trader.model.*; import ru.trader.model.*;
import ru.trader.model.support.VendorUpdater; import ru.trader.model.support.StationUpdater;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
import ru.trader.view.support.NumberField; import ru.trader.view.support.NumberField;
import ru.trader.view.support.PriceStringConverter; import ru.trader.view.support.PriceStringConverter;
@@ -27,46 +23,18 @@ import ru.trader.view.support.cells.EditOfferCell;
import java.util.Optional; import java.util.Optional;
public class VendorEditorController { public class StationEditorController {
private final static Logger LOG = LoggerFactory.getLogger(VendorEditorController.class); private final static Logger LOG = LoggerFactory.getLogger(StationEditorController.class);
private final Action actSave = new AbstractAction(Localization.getString("dialog.button.save")) {
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
items.getSelectionModel().selectFirst();
updater.commit();
items.getSelectionModel().clearSelection();
dlg.hide();
}
};
private final Action actCancel = new DefaultDialogAction(impl.org.controlsfx.i18n.Localization.asKey("dlg.cancel.button")) {
{
ButtonBar.setType(this, ButtonBar.ButtonType.CANCEL_CLOSE);
}
@Override
public void handle(ActionEvent event) {
items.getSelectionModel().selectFirst();
items.getSelectionModel().clearSelection();
super.handle(event);
}
};
@FXML @FXML
private TextField name; private TextField name;
@FXML @FXML
private TableView<VendorUpdater.FakeOffer> items; private TableView<StationUpdater.FakeOffer> items;
@FXML @FXML
private TableColumn<VendorUpdater.FakeOffer, Double> buy; private TableColumn<StationUpdater.FakeOffer, Double> buy;
@FXML @FXML
private TableColumn<VendorUpdater.FakeOffer, Double> sell; private TableColumn<StationUpdater.FakeOffer, Double> sell;
@FXML @FXML
private NumberField x; private NumberField x;
@@ -75,8 +43,18 @@ public class VendorEditorController {
@FXML @FXML
private NumberField z; private NumberField z;
private VendorUpdater updater; private StationUpdater updater;
private final Action actSave = new DialogAction("dialog.button.save", ButtonBar.ButtonType.OK_DONE, false, true, false, (e) -> {
items.getSelectionModel().selectFirst();
updater.commit();
items.getSelectionModel().clearSelection();
});
private final Action actCancel = new DialogAction(impl.org.controlsfx.i18n.Localization.asKey("dlg.cancel.button"), ButtonBar.ButtonType.CANCEL_CLOSE, true, true, true, (e) -> {
items.getSelectionModel().selectFirst();
items.getSelectionModel().clearSelection();
});
@FXML @FXML
private void initialize() { private void initialize() {
@@ -95,7 +73,7 @@ public class VendorEditorController {
} }
private void init(){ private void init(){
updater = new VendorUpdater(MainController.getMarket()); updater = new StationUpdater(MainController.getMarket());
name.textProperty().bindBidirectional(updater.nameProperty()); name.textProperty().bindBidirectional(updater.nameProperty());
x.numberProperty().bindBidirectional(updater.xProperty()); x.numberProperty().bindBidirectional(updater.xProperty());
y.numberProperty().bindBidirectional(updater.yProperty()); y.numberProperty().bindBidirectional(updater.yProperty());
@@ -103,9 +81,13 @@ public class VendorEditorController {
items.setItems(updater.getOffers()); items.setItems(updater.getOffers());
} }
public void showDialog(Parent parent, Parent content, VendorModel vendor){ public void showDialog(Parent parent, Parent content, StationModel station){
updater.init(vendor); showDialog(parent, content, station.getSystem(), station);
Dialog dlg = new Dialog(parent, Localization.getString(vendor == null ? "vEditor.title.add" : "vEditor.title.edit")); }
public void showDialog(Parent parent, Parent content, SystemModel system, StationModel station){
updater.init(system, station);
Dialog dlg = new Dialog(parent, Localization.getString(station == null ? "vEditor.title.add" : "vEditor.title.edit"));
dlg.setContent(content); dlg.setContent(content);
dlg.getActions().addAll(actSave, actCancel); dlg.getActions().addAll(actSave, actCancel);
dlg.setResizable(false); dlg.setResizable(false);
@@ -116,7 +98,7 @@ public class VendorEditorController {
public void up(){ public void up(){
int index = items.getSelectionModel().getSelectedIndex(); int index = items.getSelectionModel().getSelectedIndex();
if (index>0){ if (index>0){
VendorUpdater.FakeOffer offer = items.getItems().remove(index); StationUpdater.FakeOffer offer = items.getItems().remove(index);
items.getItems().add(index-1, offer); items.getItems().add(index-1, offer);
selectRow(index - 1); selectRow(index - 1);
} }
@@ -125,7 +107,7 @@ public class VendorEditorController {
public void down(){ public void down(){
int index = items.getSelectionModel().getSelectedIndex(); int index = items.getSelectionModel().getSelectedIndex();
if (index>=0 && index<items.getItems().size()-1){ if (index>=0 && index<items.getItems().size()-1){
VendorUpdater.FakeOffer offer = items.getItems().remove(index); StationUpdater.FakeOffer offer = items.getItems().remove(index);
items.getItems().add(index+1, offer); items.getItems().add(index+1, offer);
selectRow(index + 1); selectRow(index + 1);
} }

View File

@@ -1,7 +1,6 @@
package ru.trader.controllers; package ru.trader.controllers;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
@@ -9,27 +8,18 @@ import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.LongStringConverter; import javafx.util.converter.LongStringConverter;
import org.controlsfx.control.ButtonBar; import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogAction;
import ru.trader.model.OrderModel; import ru.trader.model.OrderModel;
import ru.trader.model.support.BindingsHelper;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
import java.util.Collection; import java.util.Collection;
import java.util.List;
public class TopOrdersController { public class TopOrdersController {
private final Action OK = new AbstractAction("OK") { private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false);
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
dlg.hide();
}
};
@FXML @FXML
private TableView<OrderModel> tblOrders; private TableView<OrderModel> tblOrders;
@@ -39,10 +29,13 @@ public class TopOrdersController {
private OrderModel order; private OrderModel order;
private final List<OrderModel> orders = FXCollections.observableArrayList();
@FXML @FXML
private void initialize() { private void initialize() {
count.setCellFactory(TextFieldTableCell.forTableColumn(new LongStringConverter())); count.setCellFactory(TextFieldTableCell.forTableColumn(new LongStringConverter()));
tblOrders.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> changeOrder(n)); tblOrders.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> changeOrder(n));
BindingsHelper.setTableViewItems(tblOrders, orders);
} }
@@ -52,19 +45,17 @@ public class TopOrdersController {
Dialog dlg = new Dialog(parent, Localization.getString("topOrders.title")); Dialog dlg = new Dialog(parent, Localization.getString("topOrders.title"));
dlg.setContent(content); dlg.setContent(content);
dlg.getActions().addAll(OK, Dialog.Actions.CANCEL); dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL);
dlg.setResizable(false); dlg.setResizable(false);
OrderModel res = dlg.show() == OK ? order : null; OrderModel res = dlg.show() == OK ? order : null;
tblOrders.getItems().clear(); this.orders.clear();
return res; return res;
} }
private void init(Collection<OrderModel> orders) { private void init(Collection<OrderModel> orders) {
tblOrders.getSelectionModel().clearSelection(); tblOrders.getSelectionModel().clearSelection();
tblOrders.setItems(FXCollections.observableArrayList(orders)); this.orders.addAll(orders);
if (tblOrders.getSortOrder().size()>0)
tblOrders.sort();
} }
private void changeOrder(OrderModel order) { private void changeOrder(OrderModel order) {

View File

@@ -1,40 +0,0 @@
package ru.trader.model;
import javafx.beans.property.*;
import ru.trader.core.OFFER_TYPE;
import java.util.List;
public interface ItemDescModel {
ItemModel getItem();
ReadOnlyStringProperty nameProperty();
ReadOnlyDoubleProperty avgBuyProperty();
ReadOnlyObjectProperty<OfferModel> minBuyProperty();
ReadOnlyObjectProperty<OfferModel> maxBuyProperty();
ReadOnlyObjectProperty<OfferModel> bestBuyProperty();
ReadOnlyDoubleProperty avgSellProperty();
ReadOnlyObjectProperty<OfferModel> minSellProperty();
ReadOnlyObjectProperty<OfferModel> maxSellProperty();
ReadOnlyObjectProperty<OfferModel> bestSellProperty();
boolean hasItem(OfferModel offer);
List<OfferModel> getSeller();
List<OfferModel> getBuyer();
void refresh();
void refresh(OFFER_TYPE type);
}

View File

@@ -1,115 +0,0 @@
package ru.trader.model;
import javafx.beans.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.OFFER_TYPE;
import java.util.List;
public class ItemDescModelImpl implements ItemDescModel {
private final static Logger LOG = LoggerFactory.getLogger(ItemDescModelImpl.class);
protected final ItemModel item;
protected final ItemStatModel statSell;
protected final ItemStatModel statBuy;
public ItemDescModelImpl(ItemModel item, ItemStatModel statSell, ItemStatModel statBuy) {
this.item = item;
this.statSell = statSell;
this.statBuy = statBuy;
}
@Override
public ItemModel getItem(){
return item;
}
@Override
public ReadOnlyStringProperty nameProperty() {
return item.nameProperty();
}
@Override
public ReadOnlyDoubleProperty avgBuyProperty() {
return statBuy.avgProperty();
}
@Override
public ReadOnlyObjectProperty<OfferModel> minBuyProperty() {
return statBuy.minProperty();
}
@Override
public ReadOnlyObjectProperty<OfferModel> maxBuyProperty() {
return statBuy.maxProperty();
}
@Override
public ReadOnlyObjectProperty<OfferModel> bestBuyProperty() {
return statBuy.bestProperty();
}
@Override
public ReadOnlyDoubleProperty avgSellProperty() {
return statSell.avgProperty();
}
@Override
public ReadOnlyObjectProperty<OfferModel> minSellProperty() {
return statSell.minProperty();
}
@Override
public ReadOnlyObjectProperty<OfferModel> maxSellProperty() {
return statSell.maxProperty();
}
@Override
public ReadOnlyObjectProperty<OfferModel> bestSellProperty() {
return statSell.bestProperty();
}
@Override
public List<OfferModel> getSeller() {
return statSell.getOffers();
}
@Override
public List<OfferModel> getBuyer() {
return statBuy.getOffers();
}
@Override
public void refresh(){
LOG.trace("Refresh stats of itemDesc {}", this);
statBuy.refresh();
statSell.refresh();
}
@Override
public void refresh(OFFER_TYPE type){
LOG.trace("Refresh {} stat of itemDesc {}", type, this);
switch (type) {
case SELL: statSell.refresh();
break;
case BUY: statBuy.refresh();
break;
}
}
public boolean hasItem(ItemModel item){
return this.item.getItem().equals(item.getItem());
}
@Override
public boolean hasItem(OfferModel offer){
return this.item.getItem().equals(offer.getOffer().getItem());
}
@Override
public String toString() {
return item.toString();
}
}

View File

@@ -1,60 +1,123 @@
package ru.trader.model; package ru.trader.model;
import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.*;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.core.Item; import ru.trader.core.Item;
import ru.trader.core.OFFER_TYPE;
import ru.trader.view.support.Localization; import ru.trader.view.support.Localization;
public class ItemModel{ import java.util.List;
public class ItemModel {
private final static Logger LOG = LoggerFactory.getLogger(ItemModel.class); private final static Logger LOG = LoggerFactory.getLogger(ItemModel.class);
private final Item item; private final Item item;
private final MarketModel market;
private StringProperty name; private StringProperty name;
private final ItemStatModel statSell;
private final ItemStatModel statBuy;
ItemModel(Item item, MarketModel market) { ItemModel(Item item, MarketModel market) {
this.item = item; this.item = item;
this.market = market; this.statSell = new ItemStatModel(market.getStat(OFFER_TYPE.SELL, item), market);
this.statBuy = new ItemStatModel(market.getStat(OFFER_TYPE.BUY, item), market);
} }
public String getName() {return name != null ? name.get() : item.getName();} Item getItem(){
return item;
}
public String getId() {return item.getName();} public String getId() {return item.getName();}
public boolean isMarketItem(){ public String getName() {return name != null ? name.get() : item.getName();}
return item.getGroup() != null && item.getGroup().isMarket();
}
public void setName(String value) { public void setName(String value) {
LOG.info("Change name of item {} to {}", item, name); LOG.info("Change name of item {} to {}", item, value);
market.updateName(this, value); item.setName(value);
if (name != null) name.set(value); if (name != null) name.set(value);
} }
public ReadOnlyStringProperty nameProperty() { public ReadOnlyStringProperty nameProperty() {
if (name == null) { if (name == null) {
String lName = Localization.getString("item."+item.getName(), item.getName()); String lName = Localization.getString("item." + item.getName(), item.getName());
name = new SimpleStringProperty(lName); name = new SimpleStringProperty(lName);
} }
return name; return name;
} }
public ReadOnlyDoubleProperty avgBuyProperty() {
return statBuy.avgProperty();
}
public ReadOnlyObjectProperty<OfferModel> minBuyProperty() {
return statBuy.minProperty();
}
public ReadOnlyObjectProperty<OfferModel> maxBuyProperty() {
return statBuy.maxProperty();
}
public ReadOnlyObjectProperty<OfferModel> bestBuyProperty() {
return statBuy.bestProperty();
}
public ReadOnlyDoubleProperty avgSellProperty() {
return statSell.avgProperty();
}
public ReadOnlyObjectProperty<OfferModel> minSellProperty() {
return statSell.minProperty();
}
public ReadOnlyObjectProperty<OfferModel> maxSellProperty() {
return statSell.maxProperty();
}
public ReadOnlyObjectProperty<OfferModel> bestSellProperty() {
return statSell.bestProperty();
}
public List<OfferModel> getSeller() {
return statSell.getOffers();
}
public List<OfferModel> getBuyer() {
return statBuy.getOffers();
}
public boolean isMarketItem(){
return item.getGroup() != null && item.getGroup().isMarket();
}
public void refresh(){
LOG.trace("Refresh stats of itemDesc {}", this);
statBuy.refresh();
statSell.refresh();
}
public void refresh(OFFER_TYPE type){
LOG.trace("Refresh {} stat of itemDesc {}", type, this);
switch (type) {
case SELL: statSell.refresh();
break;
case BUY: statBuy.refresh();
break;
}
}
@Override @Override
public String toString() { public String toString() {
if (LOG.isTraceEnabled()){ if (LOG.isTraceEnabled()){
final StringBuilder sb = new StringBuilder("ItemModel{"); final StringBuilder sb = new StringBuilder("ItemModel{");
sb.append("nameProp=").append(name); sb.append("nameProp=").append(name);
sb.append(", item=").append(super.toString()); sb.append(", item=").append(item.toString());
sb.append(", statSell=").append(statSell.toString());
sb.append(", statBuy=").append(statBuy.toString());
sb.append('}'); sb.append('}');
return sb.toString(); return sb.toString();
} }
return item.toString(); return item.toString();
} }
Item getItem() {
return item;
}
} }

View File

@@ -19,6 +19,10 @@ public class ItemStatModel {
private ObjectProperty<OfferModel> min; private ObjectProperty<OfferModel> min;
private ObjectProperty<OfferModel> best; private ObjectProperty<OfferModel> best;
private OfferModel asModel(Offer offer){
return market.getModeler().get(offer);
}
ItemStatModel(ItemStat itemStat, MarketModel market) { ItemStatModel(ItemStat itemStat, MarketModel market) {
this.itemStat = itemStat; this.itemStat = itemStat;
this.market = market; this.market = market;
@@ -31,21 +35,21 @@ public class ItemStatModel {
public ReadOnlyObjectProperty<OfferModel> minProperty(){ public ReadOnlyObjectProperty<OfferModel> minProperty(){
if (min == null){ if (min == null){
min = new SimpleObjectProperty<>(market.asModel(itemStat.getMin())); min = new SimpleObjectProperty<>(asModel(itemStat.getMin()));
} }
return min; return min;
} }
public ReadOnlyObjectProperty<OfferModel> maxProperty(){ public ReadOnlyObjectProperty<OfferModel> maxProperty(){
if (max == null) { if (max == null) {
max = new SimpleObjectProperty<>(market.asModel(itemStat.getMax())); max = new SimpleObjectProperty<>(asModel(itemStat.getMax()));
} }
return max; return max;
} }
public ReadOnlyObjectProperty<OfferModel> bestProperty(){ public ReadOnlyObjectProperty<OfferModel> bestProperty(){
if (best == null){ if (best == null){
best = new SimpleObjectProperty<>(market.asModel(itemStat.getBest())); best = new SimpleObjectProperty<>(asModel(itemStat.getBest()));
} }
return best; return best;
} }
@@ -55,19 +59,19 @@ public class ItemStatModel {
} }
public OfferModel getMax() { public OfferModel getMax() {
return max != null ? max.get() : market.asModel(itemStat.getMax()); return max != null ? max.get() : asModel(itemStat.getMax());
} }
public OfferModel getMin() { public OfferModel getMin() {
return min != null ? min.get() : market.asModel(itemStat.getMin()); return min != null ? min.get() : asModel(itemStat.getMin());
} }
public OfferModel getBest() { public OfferModel getBest() {
return best != null ? best.get() : market.asModel(itemStat.getBest()); return best != null ? best.get() : asModel(itemStat.getBest());
} }
public List<OfferModel> getOffers() { public List<OfferModel> getOffers() {
return itemStat.getOffers().stream().map(market::asModel).collect(Collectors.toList()); return itemStat.getOffers().stream().map(this::asModel).collect(Collectors.toList());
} }
@Override @Override
@@ -107,8 +111,8 @@ public class ItemStatModel {
private void refreshProp(ObjectProperty<OfferModel> prop, Offer offer){ private void refreshProp(ObjectProperty<OfferModel> prop, Offer offer){
if (prop!=null ){ if (prop!=null ){
OfferModel model = prop.getValue(); OfferModel model = prop.getValue();
if (model==null || !model.isModel(offer)){ if (model==null || !model.getOffer().equals(offer)){
prop.setValue(market.asModel(offer)); prop.setValue(asModel(offer));
} }
} }
} }

View File

@@ -10,10 +10,7 @@ import ru.trader.World;
import ru.trader.core.*; import ru.trader.core.*;
import ru.trader.graph.PathRoute; import ru.trader.graph.PathRoute;
import ru.trader.model.support.BindingsHelper; import ru.trader.model.support.BindingsHelper;
import ru.trader.model.support.ChangeMarketListener; import ru.trader.model.support.Notificator;
import java.util.ArrayList;
import java.util.Collection;
public class MarketModel { public class MarketModel {
@@ -21,222 +18,98 @@ public class MarketModel {
private final Market market; private final Market market;
private final MarketAnalyzer analyzer; private final MarketAnalyzer analyzer;
private final ModelFabric modeler;
private final Notificator notificator;
private final Collection<ChangeMarketListener> listener = new ArrayList<>(); private final ListProperty<SystemModel> systems;
private final ListProperty<ItemModel> items;
private final ListProperty<VendorModel> vendors;
private final ListProperty<ItemDescModel> items;
private boolean alert = true;
public ReadOnlyListProperty<VendorModel> vendorsProperty() {
return vendors;
}
public ReadOnlyListProperty<ItemDescModel> itemsProperty() {
return items;
}
public void setAlert(boolean alert) {
this.alert = alert;
}
public MarketModel(Market market) { public MarketModel(Market market) {
this.market = market; this.market = market;
analyzer = World.buildAnalyzer(market); analyzer = World.buildAnalyzer(market);
items = new SimpleListProperty<ItemDescModel>(BindingsHelper.observableList(market.getItems(), this::getItemDesc)); modeler = new ModelFabric(this);
vendors = new SimpleListProperty<VendorModel>(BindingsHelper.observableList(market.get(), this::asModel)); notificator = new Notificator();
items = new SimpleListProperty<>(BindingsHelper.observableList(market.getItems(), modeler::get));
systems = new SimpleListProperty<>(BindingsHelper.observableList(market.get(), modeler::get));
} }
public void addListener(ChangeMarketListener listener){ public MarketAnalyzer getAnalyzer() {
synchronized (this.listener){ return analyzer;
this.listener.add(listener);
}
} }
public void removeListeners() { public ModelFabric getModeler() {
synchronized (listener){ return modeler;
listener.clear();
}
} }
public void addAllListener(Collection<? extends ChangeMarketListener> listener){ public Notificator getNotificator() {
synchronized (this.listener){ return notificator;
this.listener.addAll(listener);
}
} }
public Collection<ChangeMarketListener> getListeners() { public ReadOnlyListProperty<SystemModel> systemsProperty() {
return listener; return systems;
} }
void updatePosition(VendorModel model, double x, double y, double z) { public SystemModel add(String name, double x, double y, double z) {
Vendor vendor = model.getVendor(); SystemModel system = modeler.get(market.addPlace(name, x, y, z));
double oldX = vendor.getX(); LOG.info("Add system {} to market {}", system, this);
double oldY = vendor.getY(); notificator.sendAdd(system);
double oldZ = vendor.getZ(); systems.add(system);
market.updatePosition(vendor, x, y, z); return system;
if (alert) listener.forEach((c) -> c.positionChange(model, oldX, oldY, oldZ, x, y, z));
} }
void updateName(ItemModel model, String value) { public ReadOnlyListProperty<ItemModel> itemsProperty() {
Item item = model.getItem(); return items;
String old = item.getName();
market.updateName(item, value);
if (alert) listener.forEach((c) -> c.nameChange(model, old, value));
} }
void updateName(VendorModel model, String value) { public ItemModel add(String name, Group group) {
Vendor vendor = model.getVendor(); ItemModel item = modeler.get(market.addItem(name, group));
String old = vendor.getName();
market.updateName(vendor, value);
if (alert) listener.forEach((c) -> c.nameChange(model, old, value));
}
void updatePrice(OfferModel model, double value) {
Offer offer = model.getOffer();
double old = offer.getPrice();
market.updatePrice(offer, value);
if (alert) listener.forEach((c) -> c.priceChange(model, old, value));
}
void add(VendorModel vendor, OfferModel offer) {
market.add(vendor.getVendor(), offer.getOffer());
if (alert) listener.forEach((c) -> c.add(offer));
}
void remove(VendorModel vendor, OfferModel offer) {
market.remove(vendor.getVendor(), offer.getOffer());
if (alert) listener.forEach((c) -> c.remove(offer));
}
public void add(VendorModel vendor) {
LOG.info("Add vendor {} to market {}", vendor, this);
market.add(vendor.getVendor());
if (alert) listener.forEach((c) -> c.add(vendor));
vendors.add(vendor);
}
public void add(ItemModel item) {
LOG.info("Add item {} to market {}", item, this); LOG.info("Add item {} to market {}", item, this);
market.add(item.getItem()); notificator.sendAdd(item);
ItemDescModel model = getItemDesc(item); items.add(item);
if (alert) listener.forEach((c) -> c.add(model)); return item;
items.add(model);
}
public ItemModel newItem(String name){
return ModelFabrica.buildItemModel(name, this);
}
public VendorModel newVendor(String name){
return ModelFabrica.buildModel(name, this);
}
public OfferModel newOffer(OFFER_TYPE type, ItemModel item, double price) {
return ModelFabrica.buildModel(type, item, price, this);
}
ItemDescModel getItemDesc(Item item){
return getItemDesc(asModel(item));
}
ItemDescModel getItemDesc(ItemModel item){
return ModelFabrica.buildModel(item, market.getStatSell(item.getItem()), market.getStatBuy(item.getItem()), this);
}
public OfferDescModel asOfferDescModel(Offer offer){
return asOfferDescModel(asModel(offer));
}
public OfferDescModel asOfferDescModel(OfferModel offer){
Item item = offer.getOffer().getItem();
return ModelFabrica.buildModel(offer, market.getStatSell(item), market.getStatBuy(item), this);
} }
ItemStat getStat(OFFER_TYPE type, Item item){ ItemStat getStat(OFFER_TYPE type, Item item){
return market.getStat(type, item); return market.getStat(type, item);
} }
public OfferModel asModel(Offer offer){ public ObservableList<OrderModel> getOrders(SystemModel from, double balance) {
return ModelFabrica.getModel(offer, this); return BindingsHelper.observableList(analyzer.getOrders(from.getSystem(), balance), modeler::get);
} }
public ItemModel asModel(Item item){ public ObservableList<OrderModel> getOrders(SystemModel from, SystemModel to, double balance) {
return ModelFabrica.getModel(item, this); return BindingsHelper.observableList(analyzer.getOrders(from.getSystem(), to.getSystem(), balance), modeler::get);
} }
public VendorModel asModel(Vendor vendor) { public ObservableList<OrderModel> getOrders(StationModel from, StationModel to, double balance) {
return ModelFabrica.getModel(vendor, this); return BindingsHelper.observableList(analyzer.getOrders(from.getStation(), to.getStation(), balance), modeler::get);
}
public OrderModel asModel(Order order) {
return new OrderModel(asOfferDescModel(order.getSell()), asModel(order.getBuy()), order.getCount());
}
public PathRouteModel asModel(PathRoute path) {
return new PathRouteModel(path, this);
}
public void setLimit(int limit){
analyzer.setPathsCount(limit);
}
public void setSegmetnSize(int segmetnSize){
analyzer.setSegmentSize(segmetnSize);
}
public void setCargo(int cargo){
analyzer.setCargo(cargo);
}
public void setTank(double tank){
analyzer.setTank(tank);
}
public void setJumps(int jumps){
analyzer.setJumps(jumps);
}
public void setDistance(double distance){
analyzer.setMaxDistance(distance);
}
public ObservableList<OrderModel> getOrders(VendorModel from, double balance) {
return BindingsHelper.observableList(analyzer.getOrders(from.getVendor(), balance), this::asModel);
}
public ObservableList<OrderModel> getOrders(VendorModel from, VendorModel to, double balance) {
return BindingsHelper.observableList(analyzer.getOrders(from.getVendor(), to.getVendor(), balance), this::asModel);
} }
public ObservableList<OrderModel> getTop(double balance){ public ObservableList<OrderModel> getTop(double balance){
return BindingsHelper.observableList(analyzer.getTop(balance), this::asModel); return BindingsHelper.observableList(analyzer.getTop(balance), modeler::get);
} }
public ObservableList<PathRouteModel> getRoutes(VendorModel from, double balance){ public ObservableList<PathRouteModel> getRoutes(SystemModel from, double balance){
return BindingsHelper.observableList(analyzer.getPaths(from.getVendor(), balance), this::asModel); return BindingsHelper.observableList(analyzer.getPaths(from.getSystem(), balance), modeler::get);
} }
public ObservableList<PathRouteModel> getRoutes(VendorModel from, VendorModel to, double balance){ public ObservableList<PathRouteModel> getRoutes(SystemModel from, SystemModel to, double balance){
return BindingsHelper.observableList(analyzer.getPaths(from.getVendor(), to.getVendor(), balance), this::asModel); return BindingsHelper.observableList(analyzer.getPaths(from.getSystem(), to.getSystem(), balance), modeler::get);
} }
public ObservableList<PathRouteModel> getTopRoutes(double balance){ public ObservableList<PathRouteModel> getTopRoutes(double balance){
return BindingsHelper.observableList(analyzer.getTopPaths(balance), this::asModel); return BindingsHelper.observableList(analyzer.getTopPaths(balance), modeler::get);
} }
PathRoute getPath(VendorModel from, VendorModel to) { PathRoute getPath(SystemModel from, SystemModel to) {
return analyzer.getPath(from.getVendor(), to.getVendor()); return analyzer.getPath(from.getSystem(), to.getSystem());
} }
public PathRouteModel getPath(OrderModel order) { public PathRouteModel getPath(OrderModel order) {
PathRoute p = analyzer.getPath(order.getVendor().getVendor(), order.getBuyer().getVendor()); PathRoute p = analyzer.getPath(order.getStation().getStation().getPlace(), order.getBuyer().getStation().getPlace());
if (p == null) return null; if (p == null) return null;
p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount())); p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount()));
order.setPath(p); return modeler.get(p);
return asModel(p);
} }
} }

View File

@@ -0,0 +1,177 @@
package ru.trader.model;
import javafx.beans.property.ReadOnlyStringProperty;
import ru.trader.core.*;
import ru.trader.graph.PathRoute;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
public class ModelFabric {
private final MarketModel market;
private final HashMap<Item, WeakReference<ItemModel>> items = new HashMap<>();
private final HashMap<Place, WeakReference<SystemModel>> systems = new HashMap<>();
private final HashMap<Vendor, WeakReference<StationModel>> stations = new HashMap<>();
private final HashMap<Offer, WeakReference<OfferModel>> offers = new HashMap<>();
public ModelFabric(MarketModel market) {
this.market = market;
}
public OrderModel get(Order order) {
return new OrderModel(get(order.getSell()), get(order.getBuy()), order.getCount());
}
public PathRouteModel get(PathRoute path) {
return new PathRouteModel(path, market);
}
public SystemModel get(Place system){
if (system == null) return null;
SystemModel res=null;
WeakReference<SystemModel> ref = systems.get(system);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new SystemModel(system, market);
systems.put(system, new WeakReference<>(res));
}
return res;
}
public StationModel get(Vendor station){
if (station == null) return null;
StationModel res=null;
WeakReference<StationModel> ref = stations.get(station);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new StationModel(station, market);
stations.put(station, new WeakReference<>(res));
}
return res;
}
public ItemModel get(Item item){
if (item == null) return null;
ItemModel res=null;
WeakReference<ItemModel> ref = items.get(item);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new ItemModel(item, market);
items.put(item, new WeakReference<>(res));
}
return res;
}
public OfferModel get(Offer offer){
if (offer == null) return null;
OfferModel res = null;
WeakReference<OfferModel> ref = offers.get(offer);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new OfferModel(offer, market);
offers.put(offer, new WeakReference<>(res));
}
return res;
}
public OfferModel get(Offer offer, ItemModel item){
if (offer == null) return null;
//always create new offer model
OfferModel res = new OfferModel(offer, item, market);
offers.put(offer, new WeakReference<>(res));
return res;
}
public void clear(){
items.clear();
systems.clear();
stations.clear();
offers.clear();
}
public static SystemModel NONE_SYSTEM = new FAKE_SYSTEM_MODEL();
private static class FAKE_SYSTEM_MODEL extends SystemModel {
FAKE_SYSTEM_MODEL() {
super();
}
@Override
Place getSystem() {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public String getName() {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public void setName(String value) {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public ReadOnlyStringProperty nameProperty() {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public double getX() {
return Double.NaN;
}
@Override
public double getY() {
return Double.NaN;
}
@Override
public double getZ() {
return Double.NaN;
}
@Override
public void setPosition(double x, double y, double z) {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public double getDistance(SystemModel other) {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public List<StationModel> getStations() {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public List<StationModel> getStations(SERVICE_TYPE service) {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public StationModel add(String name) {
throw new UnsupportedOperationException("Is fake system, change unsupported");
}
@Override
public String toString() {
return "";
}
}
}

View File

@@ -1,104 +0,0 @@
package ru.trader.model;
import ru.trader.core.*;
import ru.trader.store.simple.SimpleItem;
import ru.trader.store.simple.SimpleOffer;
import ru.trader.store.simple.SimpleVendor;
import java.lang.ref.WeakReference;
import java.util.HashMap;
public class ModelFabrica {
private static final HashMap<Item, WeakReference<ItemModel>> items = new HashMap<>();
private static final HashMap<Vendor, WeakReference<VendorModel>> vendors = new HashMap<>();
private static final HashMap<Offer, WeakReference<OfferModel>> offers = new HashMap<>();
private static final HashMap<ItemStat, WeakReference<ItemStatModel>> stats = new HashMap<>();
public static ItemModel buildItemModel(String name, MarketModel market){
return getModel(new SimpleItem(name), market);
}
public static VendorModel buildModel(String name, MarketModel market){
return getModel(new SimpleVendor(name), market);
}
public static OfferModel buildModel(OFFER_TYPE type, ItemModel item, double price, MarketModel market) {
return getModel(new SimpleOffer(type, item.getItem(), price), market);
}
public static ItemDescModel buildModel(ItemModel item, ItemStat sell, ItemStat buy, MarketModel market) {
return new ItemDescModelImpl(item, getModel(sell, market), getModel(buy, market));
}
public static OfferDescModel buildModel(OfferModel offer, ItemStat sell, ItemStat buy, MarketModel market){
return new OfferDescModel(offer, getModel(sell, market), getModel(buy, market));
}
public static VendorModel getModel(Vendor vendor, MarketModel market){
if (vendor == null) return null;
VendorModel res=null;
WeakReference<VendorModel> ref = vendors.get(vendor);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new VendorModel(vendor, market);
vendors.put(vendor, new WeakReference<>(res));
}
return res;
}
public static ItemModel getModel(Item item, MarketModel market){
if (item == null) return null;
ItemModel res=null;
WeakReference<ItemModel> ref = items.get(item);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new ItemModel(item, market);
items.put(item, new WeakReference<>(res));
}
return res;
}
public static OfferModel getModel(Offer offer, MarketModel market){
if (offer == null) return null;
OfferModel res = null;
WeakReference<OfferModel> ref = offers.get(offer);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new OfferModel(offer, market);
offers.put(offer, new WeakReference<>(res));
}
return res;
}
public static ItemStatModel getModel(ItemStat itemStat, MarketModel market){
if (itemStat == null) return null;
ItemStatModel res = null;
WeakReference<ItemStatModel> ref = stats.get(itemStat);
if (ref != null){
res = ref.get();
}
if (res == null){
res = new ItemStatModel(itemStat, market);
stats.put(itemStat, new WeakReference<>(res));
}
return res;
}
public static void clear(){
items.clear();
vendors.clear();
offers.clear();
stats.clear();
}
}

View File

@@ -1,93 +0,0 @@
package ru.trader.model;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.model.support.ModelBindings;
public class OfferDescModel extends ItemDescModelImpl implements ItemDescModel{
private final static Logger LOG = LoggerFactory.getLogger(OfferDescModel.class);
protected DoubleProperty diff;
protected final OfferModel offer;
protected DoubleProperty maxProfit;
protected DoubleProperty minProfit;
protected DoubleProperty avgProfit;
public OfferDescModel(OfferModel offer, ItemStatModel statSell, ItemStatModel statBuy) {
super(offer.getItem(), statSell, statBuy);
this.offer = offer;
}
public ReadOnlyDoubleProperty priceProperty() {
return offer.priceProperty();
}
public double getPrice(){
return offer.getPrice();
}
public ReadOnlyDoubleProperty profitProperty() {
if (maxProfit == null){
maxProfit = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: maxProfit.bind(ModelBindings.diff(bestBuyProperty(), priceProperty()));
break;
case BUY: maxProfit.bind(ModelBindings.diff(priceProperty(), bestSellProperty()));
break;
}
}
return maxProfit;
}
public ReadOnlyDoubleProperty avgProfitProperty() {
if (avgProfit == null){
avgProfit = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: avgProfit.bind(avgBuyProperty().subtract(priceProperty()));
break;
case BUY: avgProfit.bind(priceProperty().subtract(avgSellProperty()));
break;
}
}
return avgProfit;
}
public ReadOnlyDoubleProperty minProfitProperty() {
if (minProfit == null){
minProfit = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: minProfit.bind(ModelBindings.diff(minBuyProperty(), priceProperty()));
break;
case BUY: minProfit.bind(ModelBindings.diff(priceProperty(), minSellProperty()));
break;
}
}
return minProfit;
}
public ReadOnlyDoubleProperty diffProperty(){
if (diff == null){
diff = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: diff.bind(Bindings.subtract(priceProperty(), avgSellProperty()));
break;
case BUY: diff.bind(Bindings.subtract(priceProperty(), avgBuyProperty()));
break;
}
}
return diff;
}
public double getDiff(){
return diffProperty().get();
}
public OfferModel getOffer(){
return offer;
}
}

View File

@@ -1,32 +1,78 @@
package ru.trader.model; package ru.trader.model;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.core.OFFER_TYPE; import ru.trader.core.OFFER_TYPE;
import ru.trader.core.Offer; import ru.trader.core.Offer;
import ru.trader.core.Place;
import ru.trader.core.Vendor;
import ru.trader.model.support.ModelBindings;
public class OfferModel{ import java.util.List;
public class OfferModel {
private final static Logger LOG = LoggerFactory.getLogger(OfferModel.class); private final static Logger LOG = LoggerFactory.getLogger(OfferModel.class);
private final MarketModel market;
private final Offer offer; private final Offer offer;
private final MarketModel market;
private final ItemModel item;
private DoubleProperty price; private DoubleProperty price;
private LongProperty count;
private DoubleProperty diff;
private DoubleProperty maxProfit;
private DoubleProperty minProfit;
private DoubleProperty avgProfit;
OfferModel(Offer offer, MarketModel market) { private SystemModel asModel(Place system){
this.market = market; return market.getModeler().get(system);
this.offer = offer; }
private StationModel asModel(Vendor station){
return market.getModeler().get(station);
} }
public OfferModel(Offer offer, MarketModel market) {
this(offer, market.getModeler().get(offer.getItem()), market);
}
public OfferModel(Offer offer, ItemModel item, MarketModel market) {
this.offer = offer;
this.market = market;
this.item = item;
}
Offer getOffer(){
return offer;
}
public ItemModel getItem(){
return item;
}
public OFFER_TYPE getType(){
return offer.getType();
}
public StationModel getStation(){
return asModel(offer.getVendor());
}
public SystemModel getSystem(){
return asModel(offer.getVendor().getPlace());
}
public double getPrice() {return price != null ? price.get() : offer.getPrice();} public double getPrice() {return price != null ? price.get() : offer.getPrice();}
public void setPrice(double value) { public void setPrice(double value) {
if (getPrice() == value) return; double old = getPrice();
if (old == value) return;
LOG.info("Change price offer {} to {}", offer, value); LOG.info("Change price offer {} to {}", offer, value);
market.updatePrice(this, value); offer.setPrice(value);
if (price != null) price.set(value); if (price != null) price.set(value);
refresh();
market.getNotificator().sendPriceChange(this, old, value);
} }
public ReadOnlyDoubleProperty priceProperty() { public ReadOnlyDoubleProperty priceProperty() {
@@ -36,37 +82,140 @@ public class OfferModel{
return price; return price;
} }
public ItemModel getItem() { public long getCount() {return count != null ? count.get() : offer.getCount();}
return market.asModel(offer.getItem());
public void setCount(long value) {
if (getCount() == value) return;
LOG.info("Change count offer {} to {}", offer, value);
offer.setCount(value);
if (count != null) count.set(value);
} }
public VendorModel getVendor() { public ReadOnlyLongProperty countProperty() {
return market.asModel(offer.getVendor()); if (count == null) {
count = new SimpleLongProperty(offer.getCount());
}
return count;
} }
public OFFER_TYPE getType(){ public ReadOnlyStringProperty nameProperty() {
return offer.getType(); return item.nameProperty();
} }
public boolean isModel(Offer offer) { public ReadOnlyDoubleProperty avgBuyProperty() {
return this.offer == offer; return item.avgBuyProperty();
} }
public boolean hasVendor(VendorModel vendor){ public ReadOnlyObjectProperty<OfferModel> minBuyProperty() {
return offer.getVendor().equals(vendor.getVendor()); return item.minBuyProperty();
} }
public boolean hasItem(ItemModel item){ public ReadOnlyObjectProperty<OfferModel> maxBuyProperty() {
return offer.getItem().equals(item.getItem()); return item.maxBuyProperty();
}
public ReadOnlyObjectProperty<OfferModel> bestBuyProperty() {
return item.bestBuyProperty();
}
public ReadOnlyDoubleProperty avgSellProperty() {
return item.avgSellProperty();
}
public ReadOnlyObjectProperty<OfferModel> minSellProperty() {
return item.minSellProperty();
}
public ReadOnlyObjectProperty<OfferModel> maxSellProperty() {
return item.maxSellProperty();
}
public ReadOnlyObjectProperty<OfferModel> bestSellProperty() {
return item.bestSellProperty();
}
public List<OfferModel> getSeller() {
return item.getSeller();
}
public List<OfferModel> getBuyer() {
return item.getBuyer();
}
public ReadOnlyDoubleProperty profitProperty() {
if (maxProfit == null){
maxProfit = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: maxProfit.bind(ModelBindings.diff(bestBuyProperty(), priceProperty()));
break;
case BUY: maxProfit.bind(ModelBindings.diff(priceProperty(), bestSellProperty()));
break;
}
}
return maxProfit;
}
public ReadOnlyDoubleProperty avgProfitProperty() {
if (avgProfit == null){
avgProfit = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: avgProfit.bind(avgBuyProperty().subtract(priceProperty()));
break;
case BUY: avgProfit.bind(priceProperty().subtract(avgSellProperty()));
break;
}
}
return avgProfit;
}
public ReadOnlyDoubleProperty minProfitProperty() {
if (minProfit == null){
minProfit = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: minProfit.bind(ModelBindings.diff(minBuyProperty(), priceProperty()));
break;
case BUY: minProfit.bind(ModelBindings.diff(priceProperty(), minSellProperty()));
break;
}
}
return minProfit;
}
public ReadOnlyDoubleProperty diffProperty(){
if (diff == null){
diff = new SimpleDoubleProperty(0);
switch (offer.getType()) {
case SELL: diff.bind(Bindings.subtract(priceProperty(), avgSellProperty()));
break;
case BUY: diff.bind(Bindings.subtract(priceProperty(), avgBuyProperty()));
break;
}
}
return diff;
}
public double getDiff(){
return diffProperty().get();
}
public String toPString(){
return offer.toPString();
}
public String toIString(){
return offer.toIString();
}
public void refresh(){
item.refresh(offer.getType());
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof OfferModel)) return false; if (!(o instanceof OfferModel)) return false;
OfferModel that = (OfferModel) o; OfferModel that = (OfferModel) o;
return offer.equals(that.offer); return offer.equals(that.offer);
} }
@@ -82,22 +231,12 @@ public class OfferModel{
final StringBuilder sb = new StringBuilder("OfferModel{"); final StringBuilder sb = new StringBuilder("OfferModel{");
sb.append("priceProp=").append(price); sb.append("priceProp=").append(price);
sb.append(", offer=").append(offer.toString()); sb.append(", offer=").append(offer.toString());
sb.append(", item=").append(item.toString());
sb.append('}'); sb.append('}');
return sb.toString(); return sb.toString();
} }
return offer.toString(); return offer.toString();
} }
Offer getOffer() {
return offer;
}
public String toVString(){
return offer.toVString();
}
public String toIString(){
return offer.toIString();
}
} }

View File

@@ -1,8 +1,8 @@
package ru.trader.model; package ru.trader.model;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import ru.trader.core.Order;
import ru.trader.graph.PathRoute; import ru.trader.graph.PathRoute;
import ru.trader.model.support.ModelBindings; import ru.trader.model.support.ModelBindings;
@@ -10,23 +10,25 @@ import java.util.List;
public class OrderModel { public class OrderModel {
private final OfferDescModel offer; private final OfferModel offer;
private final LongProperty count; private final LongProperty count;
private final ObjectProperty<OfferModel> buyer = new SimpleObjectProperty<>(); private final ObjectProperty<OfferModel> buyer = new SimpleObjectProperty<>();
private long max; private LongProperty max;
private DoubleProperty profit; private DoubleProperty profit;
private DoubleProperty distance; private DoubleProperty distance;
private DoubleProperty bestProfit; private DoubleProperty bestProfit;
private PathRoute path; private PathRoute path;
public OrderModel(OfferDescModel offer) { public OrderModel(OfferModel offer) {
this.offer = offer; this.offer = offer;
this.max = new SimpleLongProperty(0);
this.count = new SimpleLongProperty(0){ this.count = new SimpleLongProperty(0){
@Override @Override
public void setValue(Number v) { public void setValue(Number v) {
if (max > 0 && v.longValue() > max){ long limit = max.get();
super.setValue(max); if (limit > 0 && v.longValue() > limit){
super.setValue(limit);
} else { } else {
super.setValue(v); super.setValue(v);
} }
@@ -34,20 +36,67 @@ public class OrderModel {
}; };
} }
public OrderModel(OfferDescModel sellOffer, OfferModel buyOffer, long max) { public OrderModel(OfferModel sellOffer, OfferModel buyOffer, long max) {
this(sellOffer); this(sellOffer);
this.max = max; this.max.setValue(max);
setBuyOffer(buyOffer); setBuyOffer(buyOffer);
setCount(max); setCount(max);
} }
public OrderModel(OfferDescModel offer, double balance, long limit) { public OrderModel(OfferModel offer, double balance, long limit) {
this(offer); this(offer);
this.max = Math.min(limit, (long) Math.floor(balance / offer.getPrice())); this.max.setValue(Math.min(offer.getCount(), Math.min(limit, (long) Math.floor(balance / offer.getPrice()))));
} }
PathRoute getPath() {
return path;
}
void setPath(PathRoute path) {
this.path = path;
}
public OfferModel getOffer() { public OfferModel getOffer() {
return offer.getOffer(); return offer;
}
public long getCount() {
return count.get();
}
public void setCount(long count) {
this.count.set(count);
}
public LongProperty countProperty() {
return count;
}
public OfferModel getBuyOffer() {
return buyer.get();
}
public void setBuyOffer(OfferModel buyer) {
this.buyer.set(buyer);
if (distance!=null) distance.set(getStation().getDistance(buyer.getStation()));
}
public ReadOnlyObjectProperty<OfferModel> buyOfferProperty() {
return buyer;
}
public long getMax() {
return max.get();
}
public void setMax(long max) {
this.max.setValue(max);
}
public StationModel getStation() {
return offer.getStation();
} }
public ReadOnlyStringProperty nameProperty() { public ReadOnlyStringProperty nameProperty() {
@@ -58,26 +107,35 @@ public class OrderModel {
return offer.priceProperty(); return offer.priceProperty();
} }
public ReadOnlyLongProperty supplyProperty() {
return offer.countProperty();
}
public ReadOnlyObjectProperty<OfferModel> bestProperty(){ public ReadOnlyObjectProperty<OfferModel> bestProperty(){
return offer.bestBuyProperty(); return offer.bestBuyProperty();
} }
public long getCount() { public List<OfferModel> getBuyers(){
return count.get(); return offer.getBuyer();
} }
public LongProperty countProperty() { public StationModel getBuyer() {
return count; OfferModel buyOffer = getBuyOffer();
return buyOffer != null ? buyer.get().getStation() : null;
} }
public void setCount(long count) { public double getProfit() {
this.count.set(count); return profitProperty().get();
}
public ObservableValue<Double> getProfit(OfferModel buyer) {
return buyer.priceProperty().subtract(offer.priceProperty()).multiply(Bindings.min(max, buyer.countProperty())).asObject();
} }
public ReadOnlyDoubleProperty profitProperty() { public ReadOnlyDoubleProperty profitProperty() {
if (profit == null){ if (profit == null){
profit = new SimpleDoubleProperty(0); profit = new SimpleDoubleProperty(0);
profit.bind(ModelBindings.diff(buyer, offer.getOffer().priceProperty()).multiply(count)); profit.bind(ModelBindings.diff(buyer, offer.priceProperty()).multiply(count));
} }
return profit; return profit;
} }
@@ -90,66 +148,16 @@ public class OrderModel {
return bestProfit; return bestProfit;
} }
public ObservableValue<Double> getProfit(OfferModel buyer) {
return buyer.priceProperty().subtract(offer.getOffer().priceProperty()).multiply(max).asObject();
}
public double getProfit() {
return profitProperty().get();
}
public ReadOnlyObjectProperty<OfferModel> buyOfferProperty() {
return buyer;
}
public void setBuyOffer(OfferModel buyer) {
this.buyer.set(buyer);
if (distance!=null) distance.set(getVendor().getDistance(buyer.getVendor()));
}
public OfferModel getBuyOffer() {
return buyer.get();
}
public VendorModel getVendor() {
return offer.getOffer().getVendor();
}
public VendorModel getBuyer() {
OfferModel buyOffer = getBuyOffer();
return buyOffer != null ? buyer.get().getVendor() : null;
}
public long getMax() {
return max;
}
public void setMax(long max) {
this.max = max;
}
public List<OfferModel> getBuyers(){
return offer.getBuyer();
}
public ReadOnlyDoubleProperty distanceProperty() { public ReadOnlyDoubleProperty distanceProperty() {
if (distance == null){ if (distance == null){
VendorModel buyer = getBuyer(); StationModel buyer = getBuyer();
distance = new SimpleDoubleProperty(buyer!=null ? getVendor().getDistance(buyer) : Double.NaN); distance = new SimpleDoubleProperty(buyer!=null ? getStation().getDistance(buyer) : Double.NaN);
} }
return distance; return distance;
} }
void setPath(PathRoute path) {
this.path = path;
}
PathRoute getPath() {
return path;
}
public double getBalance(){ public double getBalance(){
return path != null ? path.getBalance() : max * offer.getPrice(); return path != null ? path.getRoot().getBalance() : getMax() * offer.getPrice();
} }
} }

View File

@@ -70,7 +70,7 @@ public class PathRouteModel {
p = p.getNext(); p = p.getNext();
if (cargo == null && p.getBest()!=null){ if (cargo == null && p.getBest()!=null){
cargo = p.getBest(); cargo = p.getBest();
OrderModel order = market.asModel(cargo); OrderModel order = market.getModeler().get(cargo);
order.setPath(p); order.setPath(p);
res.add(order); res.add(order);
} }
@@ -82,7 +82,7 @@ public class PathRouteModel {
} }
public void add(OrderModel order){ public void add(OrderModel order){
PathRoute p = market.getPath(order.getVendor(), order.getBuyer()); PathRoute p = market.getPath(order.getStation().getSystem(), order.getBuyer().getSystem());
if (p == null) return; if (p == null) return;
p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount())); p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount()));
PathRoute head = path.getEnd(); PathRoute head = path.getEnd();
@@ -95,6 +95,6 @@ public class PathRouteModel {
} }
public PathRouteModel remove(OrderModel order) { public PathRouteModel remove(OrderModel order) {
return new PathRouteModel(path.dropTo(order.getVendor().getVendor()), market); return new PathRouteModel(path.dropTo(order.getStation().getStation()), market);
} }
} }

View File

@@ -0,0 +1,102 @@
package ru.trader.model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.OFFER_TYPE;
import ru.trader.core.Offer;
import ru.trader.core.Vendor;
import java.util.*;
import java.util.stream.Collectors;
public class StationModel {
private final static Logger LOG = LoggerFactory.getLogger(StationModel.class);
private final Vendor station;
private final MarketModel market;
private OfferModel asModel(Offer offer){
return market.getModeler().get(offer);
}
private OfferModel asModel(Offer offer, ItemModel item){
return market.getModeler().get(offer, item);
}
StationModel(Vendor station, MarketModel market) {
this.station = station;
this.market = market;
}
Vendor getStation() {
return station;
}
public String getName() {return station.getName();}
public void setName(String value) {
if (getName().equals(value)) return;
LOG.info("Change name station {} to {}", station, value);
station.setName(value);
}
public double getDistance(){
return station.getDistance();
}
public void setDistance(double value){
if (getDistance() == value) return;
LOG.info("Change distance station {} to {}", station, value);
station.setDistance(value);
}
public SystemModel getSystem(){
return market.getModeler().get(station.getPlace());
}
public List<OfferModel> getSells() {
return station.getAllSellOffers().stream().map(this::asModel).collect(Collectors.toList());
}
public List<OfferModel> getBuys() {
return station.getAllBuyOffers().stream().map(this::asModel).collect(Collectors.toList());
}
public OfferModel add(OFFER_TYPE type, ItemModel item, double price, long count){
OfferModel offer = asModel(station.addOffer(type, item.getItem(), price, count), item);
LOG.info("Add offer {} to station {}", offer, station);
offer.refresh();
market.getNotificator().sendAdd(offer);
return offer;
}
public void remove(OfferModel offer) {
LOG.info("Remove offer {} from station {}", offer, station);
station.remove(offer.getOffer());
offer.refresh();
market.getNotificator().sendRemove(offer);
}
public boolean hasSell(ItemModel item) {
return station.hasSell(item.getItem());
}
public boolean hasBuy(ItemModel item) {
return station.hasBuy(item.getItem());
}
public double getDistance(StationModel other){
return station.getPlace().getDistance(other.station.getPlace());
}
@Override
public String toString() {
if (LOG.isTraceEnabled()){
final StringBuilder sb = new StringBuilder("StationModel{");
sb.append(station.toString());
sb.append('}');
return sb.toString();
}
return station.toString();
}
}

View File

@@ -0,0 +1,102 @@
package ru.trader.model;
import javafx.beans.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.Place;
import ru.trader.core.SERVICE_TYPE;
import ru.trader.core.Vendor;
import java.util.List;
import java.util.stream.Collectors;
public class SystemModel {
private final static Logger LOG = LoggerFactory.getLogger(SystemModel.class);
private final Place system;
private final MarketModel market;
private StringProperty name;
private StationModel asModel(Vendor station){
return market.getModeler().get(station);
}
SystemModel() {
this.system = null;
this.market = null;
}
SystemModel(Place system, MarketModel market) {
this.system = system;
this.market = market;
}
Place getSystem() {
return system;
}
public String getName() {return name != null ? name.get() : system.getName();}
public void setName(String value) {
if (getName().equals(value)) return;
LOG.info("Change name system {} to {}", system, value);
system.setName(value);
if (name != null) name.set(value);
}
public ReadOnlyStringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(system.getName());
}
return name;
}
public double getX(){
return system.getX();
}
public double getY(){
return system.getY();
}
public double getZ(){
return system.getZ();
}
public void setPosition(double x, double y, double z){
if (x == system.getX() && y == system.getY() && z == system.getZ()) return;
LOG.info("Change position of system {} to ({};{};{})", this.system, x, y, z);
system.setPosition(x, y, z);
}
public double getDistance(SystemModel other){
return system.getDistance(other.getSystem());
}
public List<StationModel> getStations() {
return system.get().stream().map(this::asModel).collect(Collectors.toList());
}
public List<StationModel> getStations(final SERVICE_TYPE service) {
return system.get().stream().filter(v -> v.has(service)).map(this::asModel).collect(Collectors.toList());
}
public StationModel add(String name){
StationModel station = market.getModeler().get(system.addVendor(name));
LOG.info("Add station {} to system {}", station, this);
market.getNotificator().sendAdd(station);
return station;
}
@Override
public String toString() {
if (LOG.isTraceEnabled()){
final StringBuilder sb = new StringBuilder("SystemModel{");
sb.append("nameProp=").append(name);
sb.append(", system=").append(system.toString());
sb.append('}');
return sb.toString();
}
return system.toString();
}
}

View File

@@ -1,132 +0,0 @@
package ru.trader.model;
import javafx.beans.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.Vendor;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class VendorModel {
private final static Logger LOG = LoggerFactory.getLogger(VendorModel.class);
private final Vendor vendor;
private final MarketModel market;
private StringProperty name;
VendorModel(Vendor vendor, MarketModel market) {
this.vendor = vendor;
this.market = market;
}
public String getName() {return name != null ? name.get() : vendor.getName();}
public void setName(String value) {
if (getName().equals(value)) return;
LOG.info("Change name vendor {} to {}", vendor, value);
market.updateName(this, value);
if (name != null) name.set(value);
}
public ReadOnlyStringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(vendor.getName());
}
return name;
}
public void setPosition(double x, double y, double z){
if (x == vendor.getX() && y == vendor.getY() && z == vendor.getZ()) return;
LOG.info("Change position of vendor {} to ({};{};{})", vendor, x, y, z);
market.updatePosition(this, x, y, z);
}
public double getX(){
return vendor.getX();
}
public double getY(){
return vendor.getY();
}
public double getZ(){
return vendor.getZ();
}
public ReadOnlyDoubleProperty xProperty(){
return new SimpleDoubleProperty(vendor.getX());
}
public ReadOnlyDoubleProperty yProperty(){
return new SimpleDoubleProperty(vendor.getY());
}
public ReadOnlyDoubleProperty zProperty(){
return new SimpleDoubleProperty(vendor.getZ());
}
public double getDistance(VendorModel other){
return vendor.getDistance(other.vendor);
}
public List<OfferModel> getSells() {
return vendor.getAllSellOffers().stream().map(market::asModel).collect(Collectors.toList());
}
public List<OfferModel> getBuys() {
return vendor.getAllBuyOffers().stream().map(market::asModel).collect(Collectors.toList());
}
public <T> List<T> getSells(Function<OfferModel, T> mapper) {
return vendor.getAllSellOffers().stream().map(market::asModel).map(mapper).collect(Collectors.toList());
}
public <T> List<T> getBuys(Function<OfferModel, T> mapper) {
return vendor.getAllBuyOffers().stream().map(market::asModel).map(mapper).collect(Collectors.toList());
}
Vendor getVendor() {
return vendor;
}
public void add(OfferModel offer){
LOG.info("Add offer {} to vendor {}", offer, vendor);
market.add(this, offer);
}
public void remove(OfferModel offer) {
LOG.info("Remove offer {} from vendor {}", offer, vendor);
market.remove(this, offer);
}
public boolean hasSell(ItemModel item) {
return vendor.hasSell(item.getItem());
}
public boolean hasBuy(ItemModel item) {
return vendor.hasBuy(item.getItem());
}
@Override
public String toString() {
if (LOG.isTraceEnabled()){
final StringBuilder sb = new StringBuilder("VendorModel{");
sb.append("nameProp=").append(name);
sb.append(", vendor=").append(vendor.toString());
sb.append('}');
return sb.toString();
}
return vendor.toString();
}
public Optional<OfferModel> getSell(ItemModel item){
return Optional.ofNullable(market.asModel(vendor.getSell(item.getItem())));
}
public Optional<OfferModel> getBuy(ItemModel item){
return Optional.ofNullable(market.asModel(vendor.getBuy(item.getItem())));
}
}

View File

@@ -6,6 +6,8 @@ import javafx.beans.binding.ListBinding;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.collections.transformation.SortedList;
import javafx.scene.control.TableView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -68,4 +70,17 @@ public class BindingsHelper {
}; };
} }
public static <T> SortedList<T> sortedObservableList(List<T> list){
return (list instanceof ObservableList) ? new SortedList<>((ObservableList<? extends T>) list) : new SortedList<>(FXCollections.observableList(list));
}
public static <T> void setTableViewItems(TableView<T> table, List<T> items){
ObservableList<T> list = table.getItems();
SortedList<T> sList = sortedObservableList(items);
if (list instanceof SortedList){
((SortedList)list).comparatorProperty().unbind();
}
table.setItems(sList);
sList.comparatorProperty().bind(table.comparatorProperty());
}
} }

View File

@@ -1,37 +1,34 @@
package ru.trader.model.support; package ru.trader.model.support;
import ru.trader.model.ItemDescModel; import ru.trader.model.*;
import ru.trader.model.ItemModel;
import ru.trader.model.OfferModel;
import ru.trader.model.VendorModel;
public class ChangeMarketListener { public class ChangeMarketListener {
public void nameChange(ItemModel item, String oldName, String newName){ public void add(ItemModel item) {
} }
public void nameChange(VendorModel vendor, String oldName, String newName) { public void remove(ItemModel item) {
} }
public void add(ItemDescModel item) { public void add(SystemModel system) {
} }
public void priceChange(OfferModel offer, double oldPrice, double newPrice) { public void remove(SystemModel system) {
}
public void add(StationModel station) {
}
public void remove(StationModel station) {
} }
public void add(OfferModel offer) { public void add(OfferModel offer) {
}
public void add(VendorModel vendor) {
} }
public void remove(OfferModel offer) { public void remove(OfferModel offer) {
} }
public void positionChange(VendorModel vendor, double oldX, double oldY, double oldZ, double x, double y, double z) { public void priceChange(OfferModel offer, double oldPrice, double newPrice) {
} }
} }

View File

@@ -9,7 +9,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.model.ItemModel; import ru.trader.model.ItemModel;
import ru.trader.model.OfferModel; import ru.trader.model.OfferModel;
import ru.trader.model.VendorModel; import ru.trader.model.SystemModel;
public class ModelBindings { public class ModelBindings {
@@ -17,11 +17,11 @@ public class ModelBindings {
public static StringBinding asString(final OfferModel offer){ public static StringBinding asString(final OfferModel offer){
return Bindings.createStringBinding(offer::toVString, offer.priceProperty(), offer.getVendor().nameProperty()); return Bindings.createStringBinding(offer::toPString, offer.priceProperty(), offer.getSystem().nameProperty());
} }
public static StringBinding asItemString(final OfferModel offer){ public static StringBinding asItemString(final OfferModel offer){
return Bindings.createStringBinding(offer::toIString, offer.priceProperty(), offer.getItem().nameProperty()); return Bindings.createStringBinding(offer::toIString, offer.priceProperty(), offer.nameProperty());
} }
public static DoubleBinding price(final ObservableValue<OfferModel> offer){ public static DoubleBinding price(final ObservableValue<OfferModel> offer){
@@ -64,7 +64,7 @@ public class ModelBindings {
private static StringBinding asString(final ObservableValue<OfferModel> offer, final Observable... dependencies){ private static StringBinding asString(final ObservableValue<OfferModel> offer, final Observable... dependencies){
return Bindings.createStringBinding(() -> { return Bindings.createStringBinding(() -> {
OfferModel o = offer.getValue(); OfferModel o = offer.getValue();
return o != null ? o.toVString() : ""; return o != null ? o.toPString() : "";
}, dependencies); }, dependencies);
} }
@@ -110,7 +110,7 @@ public class ModelBindings {
public javafx.collections.ObservableList<?> getDependencies() { public javafx.collections.ObservableList<?> getDependencies() {
if (deep){ if (deep){
OfferModel model = offer.getValue(); OfferModel model = offer.getValue();
return new ImmutableObservableList<Observable>(offer, model.priceProperty(), model.getVendor().nameProperty(), model.getItem().nameProperty()); return new ImmutableObservableList<Observable>(offer, model.priceProperty(), model.getSystem().nameProperty(), model.getItem().nameProperty());
} }
else else
return new ImmutableObservableList<Observable>(offer, offer.getValue().priceProperty()); return new ImmutableObservableList<Observable>(offer, offer.getValue().priceProperty());
@@ -120,7 +120,7 @@ public class ModelBindings {
if (model == null) return; if (model == null) return;
super.bind(model.priceProperty()); super.bind(model.priceProperty());
if (deep){ if (deep){
super.bind(model.getVendor().nameProperty()); super.bind(model.getSystem().nameProperty());
super.bind(model.getItem().nameProperty()); super.bind(model.getItem().nameProperty());
} }
} }
@@ -129,7 +129,7 @@ public class ModelBindings {
if (model == null) return; if (model == null) return;
super.unbind(model.priceProperty()); super.unbind(model.priceProperty());
if (deep){ if (deep){
super.unbind(model.getVendor().nameProperty()); super.unbind(model.getSystem().nameProperty());
super.unbind(model.getItem().nameProperty()); super.unbind(model.getItem().nameProperty());
} }
} }
@@ -170,16 +170,16 @@ public class ModelBindings {
} }
public static ObservableValue<VendorModel> vendorName(final ObservableValue<VendorModel> vendor){ public static ObservableValue<SystemModel> systemName(final ObservableValue<SystemModel> system){
if ((vendor == null)) { if ((system == null)) {
throw new NullPointerException("Operands cannot be null."); throw new NullPointerException("Operands cannot be null.");
} }
return new ObjectBinding<VendorModel>() { return new ObjectBinding<SystemModel>() {
{ {
super.bind(vendor); super.bind(system);
super.bind(vendor.getValue().nameProperty()); super.bind(system.getValue().nameProperty());
vendor.addListener((observable, oldValue, newValue) -> { system.addListener((observable, oldValue, newValue) -> {
super.unbind(oldValue.nameProperty()); super.unbind(oldValue.nameProperty());
super.bind(newValue.nameProperty()); super.bind(newValue.nameProperty());
}); });
@@ -187,18 +187,18 @@ public class ModelBindings {
@Override @Override
public void dispose() { public void dispose() {
super.unbind(vendor.getValue().nameProperty()); super.unbind(system.getValue().nameProperty());
super.unbind(vendor); super.unbind(system);
} }
@Override @Override
protected VendorModel computeValue() { protected SystemModel computeValue() {
return vendor.getValue(); return system.getValue();
} }
@Override @Override
public javafx.collections.ObservableList<?> getDependencies() { public javafx.collections.ObservableList<?> getDependencies() {
return new ImmutableObservableList<Observable>(vendor, vendor.getValue().nameProperty()); return new ImmutableObservableList<Observable>(system, system.getValue().nameProperty());
} }
}; };
} }

View File

@@ -0,0 +1,75 @@
package ru.trader.model.support;
import ru.trader.model.ItemModel;
import ru.trader.model.OfferModel;
import ru.trader.model.StationModel;
import ru.trader.model.SystemModel;
import java.util.ArrayList;
import java.util.Collection;
public class Notificator {
private final Collection<ChangeMarketListener> listener = new ArrayList<>();
private boolean alert = true;
public void setAlert(boolean alert) {
this.alert = alert;
}
public void add(ChangeMarketListener listener){
synchronized (this.listener){
this.listener.add(listener);
}
}
public void addAll(Collection<? extends ChangeMarketListener> listener){
synchronized (this.listener){
this.listener.addAll(listener);
}
}
public void clear() {
synchronized (listener){
listener.clear();
}
}
public void sendAdd(ItemModel item) {
if (alert) listener.forEach((c) -> c.add(item));
}
public void sendRemove(ItemModel item) {
if (alert) listener.forEach((c) -> c.remove(item));
}
public void sendAdd(SystemModel system) {
if (alert) listener.forEach((c) -> c.add(system));
}
public void sendRemove(SystemModel system) {
if (alert) listener.forEach((c) -> c.remove(system));
}
public void sendAdd(StationModel station) {
if (alert) listener.forEach((c) -> c.add(station));
}
public void sendRemove(StationModel station) {
if (alert) listener.forEach((c) -> c.remove(station));
}
public void sendAdd(OfferModel offer) {
if (alert) listener.forEach((c) -> c.add(offer));
}
public void sendRemove(OfferModel offer) {
if (alert) listener.forEach((c) -> c.remove(offer));
}
public void sendPriceChange(OfferModel offer, double oldPrice, double newPrice) {
if (alert) listener.forEach((c) -> c.priceChange(offer, oldPrice, newPrice));
}
}

View File

@@ -6,26 +6,24 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ru.trader.controllers.MainController; import ru.trader.controllers.MainController;
import ru.trader.core.OFFER_TYPE; import ru.trader.core.OFFER_TYPE;
import ru.trader.model.ItemModel; import ru.trader.model.*;
import ru.trader.model.MarketModel;
import ru.trader.model.OfferModel;
import ru.trader.model.VendorModel;
public class VendorUpdater { public class StationUpdater {
private final static Logger LOG = LoggerFactory.getLogger(VendorUpdater.class); private final static Logger LOG = LoggerFactory.getLogger(StationUpdater.class);
private final ObservableList<FakeOffer> offers; private final ObservableList<FakeOffer> offers;
private final StringProperty name; private final StringProperty name;
private final DoubleProperty x; private final DoubleProperty x;
private final DoubleProperty y; private final DoubleProperty y;
private final DoubleProperty z; private final DoubleProperty z;
private final MarketModel market; private final MarketModel market;
private VendorModel vendor; private SystemModel system;
private StationModel station;
private boolean updateOnly; private boolean updateOnly;
public VendorUpdater(MarketModel market) { public StationUpdater(MarketModel market) {
this.market = market; this.market = market;
this.offers = BindingsHelper.observableList(MainController.getMarket().itemsProperty(), (item) -> new FakeOffer(item.getItem())); this.offers = BindingsHelper.observableList(MainController.getMarket().itemsProperty(), FakeOffer::new);
this.name = new SimpleStringProperty(); this.name = new SimpleStringProperty();
this.x = new SimpleDoubleProperty(0); this.x = new SimpleDoubleProperty(0);
this.y = new SimpleDoubleProperty(0); this.y = new SimpleDoubleProperty(0);
@@ -33,16 +31,17 @@ public class VendorUpdater {
this.updateOnly = false; this.updateOnly = false;
} }
public void init(VendorModel vendor){ public void init(SystemModel system, StationModel station){
LOG.debug("Init update of {}", vendor); LOG.debug("Init update of {}", station);
this.vendor = vendor; this.station = station;
if (vendor != null){ this.system = system;
name.setValue(vendor.getName()); if (station != null){
x.setValue(vendor.getX()); name.setValue(station.getName());
y.setValue(vendor.getY()); x.setValue(system.getX());
z.setValue(vendor.getZ()); y.setValue(system.getY());
vendor.getSells().forEach(this::fillOffer); z.setValue(system.getZ());
vendor.getBuys().forEach(this::fillOffer); station.getSells().forEach(this::fillOffer);
station.getBuys().forEach(this::fillOffer);
} else { } else {
name.setValue(""); name.setValue("");
x.setValue(0); x.setValue(0);
@@ -53,7 +52,7 @@ public class VendorUpdater {
private void fillOffer(OfferModel offer) { private void fillOffer(OfferModel offer) {
for (FakeOffer o : offers) { for (FakeOffer o : offers) {
if (offer.hasItem(o.item)) { if (offer.getItem().equals(o.item)) {
switch (offer.getType()) { switch (offer.getType()) {
case SELL: case SELL:
o.setSell(offer); o.setSell(offer);
@@ -71,8 +70,8 @@ public class VendorUpdater {
return offers; return offers;
} }
public VendorModel getVendor() { public StationModel getStation() {
return vendor; return station;
} }
public String getName() { public String getName() {
@@ -112,28 +111,29 @@ public class VendorUpdater {
} }
public void commit(){ public void commit(){
LOG.debug("Save changes of {}", vendor); LOG.debug("Save changes of {}", station);
system.setPosition(x.get(), y.get(), z.get());
if (isNew()) { if (isNew()) {
market.setAlert(false); Notificator notificator = market.getNotificator();
vendor = market.newVendor(name.get()); notificator.setAlert(false);
vendor.setPosition(x.get(), y.get(), z.get()); station = system.add(name.get());
offers.forEach(FakeOffer::commit); offers.forEach(FakeOffer::commit);
market.setAlert(true); notificator.setAlert(true);
market.add(vendor); notificator.sendAdd(station);
} else { } else {
vendor.setName(name.get()); station.setName(name.get());
vendor.setPosition(x.get(), y.get(), z.get());
offers.forEach(FakeOffer::commit); offers.forEach(FakeOffer::commit);
} }
} }
public void reset(){ public void reset(){
offers.forEach(FakeOffer::reset); offers.forEach(FakeOffer::reset);
vendor = null; station = null;
system = null;
} }
public boolean isNew() { public boolean isNew() {
return vendor == null; return station == null;
} }
public void setUpdateOnly(boolean updateOnly) { public void setUpdateOnly(boolean updateOnly) {
@@ -146,15 +146,19 @@ public class VendorUpdater {
public class FakeOffer { public class FakeOffer {
private final ItemModel item; private final ItemModel item;
private DoubleProperty sprice; private final DoubleProperty sprice;
private DoubleProperty bprice; private final LongProperty supply;
private final DoubleProperty bprice;
private final LongProperty demand;
private OfferModel sell; private OfferModel sell;
private OfferModel buy; private OfferModel buy;
public FakeOffer(ItemModel item){ public FakeOffer(ItemModel item){
this.item = item; this.item = item;
this.sprice = new SimpleDoubleProperty(0); this.sprice = new SimpleDoubleProperty(0);
this.supply = new SimpleLongProperty(0);
this.bprice = new SimpleDoubleProperty(0); this.bprice = new SimpleDoubleProperty(0);
this.demand = new SimpleLongProperty(0);
} }
public ReadOnlyStringProperty nameProperty(){ public ReadOnlyStringProperty nameProperty(){
@@ -169,6 +173,22 @@ public class VendorUpdater {
this.sprice.set(sprice); this.sprice.set(sprice);
} }
public DoubleProperty spriceProperty() {
return sprice;
}
public long getSupply() {
return supply.get();
}
public LongProperty supplyProperty() {
return supply;
}
public void setSupply(long supply) {
this.supply.set(supply);
}
public double getBprice() { public double getBprice() {
return bprice.get(); return bprice.get();
} }
@@ -181,19 +201,26 @@ public class VendorUpdater {
return bprice; return bprice;
} }
public DoubleProperty spriceProperty() { public long getDemand() {
return sprice; return demand.get();
}
public LongProperty demandProperty() {
return demand;
}
public void setDemand(long demand) {
this.demand.set(demand);
} }
public boolean isChangeSell() { public boolean isChangeSell() {
return sell!=null && getSprice() != sell.getPrice(); return sell!=null && (getSprice() != sell.getPrice() || getSupply() != sell.getCount());
} }
public boolean isChangeBuy() { public boolean isChangeBuy() {
return buy!=null && getBprice() != buy.getPrice(); return buy!=null && (getBprice() != buy.getPrice() || getDemand() != buy.getCount());
} }
public boolean isNewSell() { public boolean isNewSell() {
return sell == null && getSprice() != 0; return sell == null && getSprice() != 0;
} }
@@ -226,10 +253,18 @@ public class VendorUpdater {
return sell != null ? sell.getPrice() : 0; return sell != null ? sell.getPrice() : 0;
} }
public double getOldSupply(){
return sell != null ? sell.getCount() : 0;
}
public double getOldBprice() { public double getOldBprice() {
return buy != null ? buy.getPrice() : 0; return buy != null ? buy.getPrice() : 0;
} }
public double getOldDemand(){
return buy != null ? buy.getCount() : 0;
}
public void setSell(OfferModel sell) { public void setSell(OfferModel sell) {
this.sell = sell; this.sell = sell;
sprice.set(sell.getPrice()); sprice.set(sell.getPrice());
@@ -244,13 +279,18 @@ public class VendorUpdater {
if (sell != null){ if (sell != null){
sell = null; sell = null;
sprice.setValue(Double.NaN); sprice.setValue(Double.NaN);
supply.setValue(Double.NaN);
} }
if (buy != null){ if (buy != null){
buy = null; buy = null;
bprice.setValue(Double.NaN); bprice.setValue(Double.NaN);
demand.setValue(Double.NaN);
} }
//for fire change event
sprice.setValue(0); sprice.setValue(0);
supply.setValue(0);
bprice.setValue(0); bprice.setValue(0);
demand.setValue(0);
} }
private void commit(){ private void commit(){
@@ -265,18 +305,19 @@ public class VendorUpdater {
if (updateOnly) { if (updateOnly) {
LOG.trace("Is update only, skip"); LOG.trace("Is update only, skip");
} else { } else {
vendor.add(market.newOffer(OFFER_TYPE.BUY, item, getBprice())); station.add(OFFER_TYPE.BUY, item, getBprice(), getDemand());
} }
} else if (isRemoveBuy()) { } else if (isRemoveBuy()) {
LOG.trace("Is remove buy offer"); LOG.trace("Is remove buy offer");
if (updateOnly) { if (updateOnly) {
LOG.trace("Is update only, skip"); LOG.trace("Is update only, skip");
} else { } else {
vendor.remove(buy); station.remove(buy);
} }
} else if (isChangeBuy()){ } else if (isChangeBuy()){
LOG.trace("Is change buy price to {}", getBprice()); LOG.trace("Is change buy offer to {} ({})", getBprice(), getDemand());
buy.setPrice(getBprice()); buy.setPrice(getBprice());
buy.setCount(getDemand());
} else { } else {
LOG.trace("No change buy offer"); LOG.trace("No change buy offer");
} }
@@ -286,18 +327,19 @@ public class VendorUpdater {
if (updateOnly) { if (updateOnly) {
LOG.trace("Is update only, skip"); LOG.trace("Is update only, skip");
} else { } else {
vendor.add(market.newOffer(OFFER_TYPE.SELL, item, getSprice())); station.add(OFFER_TYPE.SELL, item, getSprice(), getSupply());
} }
} else if (isRemoveSell()) { } else if (isRemoveSell()) {
LOG.trace("Is remove sell offer"); LOG.trace("Is remove sell offer");
if (updateOnly) { if (updateOnly) {
LOG.trace("Is update only, skip"); LOG.trace("Is update only, skip");
} else { } else {
vendor.remove(sell); station.remove(sell);
} }
} else if (isChangeSell()){ } else if (isChangeSell()){
LOG.trace("Is change sell price to {}", getSprice()); LOG.trace("Is change sell offer to {}({})", getSprice(), getSupply());
sell.setPrice(getSprice()); sell.setPrice(getSprice());
sell.setCount(getSupply());
} else { } else {
LOG.trace("No change sell offer"); LOG.trace("No change sell offer");
} }
@@ -309,7 +351,9 @@ public class VendorUpdater {
return "FakeOffer{" + return "FakeOffer{" +
"item=" + item + "item=" + item +
", sprice=" + sprice.get() + ", sprice=" + sprice.get() +
", supply=" + supply.get() +
", bprice=" + bprice.get() + ", bprice=" + bprice.get() +
", demand=" + demand.get() +
", sell=" + sell + ", sell=" + sell +
", buy=" + buy + ", buy=" + buy +
'}'; '}';

View File

@@ -19,6 +19,6 @@ public class GlyphBuilder implements Builder<Glyph> {
@Override @Override
public Glyph build() { public Glyph build() {
return (Glyph) GlyphFontRegistry.glyph(text); return Glyph.create(text);
} }
} }

View File

@@ -5,7 +5,7 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import org.controlsfx.glyphfont.GlyphFontRegistry; import org.controlsfx.glyphfont.Glyph;
import ru.trader.core.Order; import ru.trader.core.Order;
import ru.trader.graph.PathRoute; import ru.trader.graph.PathRoute;
import ru.trader.model.PathRouteModel; import ru.trader.model.PathRouteModel;
@@ -15,7 +15,7 @@ public class RouteNode {
private final static String CSS_ICONS = "path-icons"; private final static String CSS_ICONS = "path-icons";
private final static String CSS_TRACK = "path-track"; private final static String CSS_TRACK = "path-track";
private final static String CSS_TRACK_TEXT = "path-track-text"; private final static String CSS_TRACK_TEXT = "path-track-text";
private final static String CSS_VENDOR = "path-vendor"; private final static String CSS_SYSTEM = "path-system";
private final PathRoute path; private final PathRoute path;
private final HBox node = new HBox(); private final HBox node = new HBox();
@@ -33,7 +33,7 @@ public class RouteNode {
VBox.setVgrow(track, Priority.ALWAYS); VBox.setVgrow(track, Priority.ALWAYS);
VBox.setVgrow(icons, Priority.ALWAYS); VBox.setVgrow(icons, Priority.ALWAYS);
v.getStyleClass().add(CSS_VENDOR); v.getStyleClass().add(CSS_SYSTEM);
icons.getStyleClass().add(CSS_ICONS); icons.getStyleClass().add(CSS_ICONS);
track.getStyleClass().add(CSS_TRACK); track.getStyleClass().add(CSS_TRACK);
@@ -42,12 +42,13 @@ public class RouteNode {
v.getChildren().add(new Text(p.get().getName())); v.getChildren().add(new Text(p.get().getName()));
Order cargo = null; Order cargo = null;
while (p.hasNext()){ while (p.hasNext()){
//TODO: fix icons
p = p.getNext(); p = p.getNext();
if (cargo == null && p.getBest() != null){ if (cargo == null && p.getBest() != null){
cargo = p.getBest(); cargo = p.getBest();
icons.getChildren().add(GlyphFontRegistry.glyph("FontAwesome|UPLOAD_ALT")); icons.getChildren().add(Glyph.create("FontAwesome|UPLOAD_ALT"));
} }
if (p.isRefill()) icons.getChildren().add(GlyphFontRegistry.glyph("FontAwesome|REFRESH")); if (p.isRefill()) icons.getChildren().add(Glyph.create("FontAwesome|REFRESH"));
node.getChildren().addAll(v, icons); node.getChildren().addAll(v, icons);
@@ -55,7 +56,7 @@ public class RouteNode {
t.getStyleClass().add(CSS_TRACK_TEXT); t.getStyleClass().add(CSS_TRACK_TEXT);
track.getChildren().addAll(t, GlyphFontRegistry.glyph("FontAwesome|LONG_ARROW_RIGHT")); track.getChildren().addAll(t, Glyph.create("FontAwesome|LONG_ARROW_RIGHT"));
node.getChildren().addAll(track); node.getChildren().addAll(track);
@@ -65,7 +66,7 @@ public class RouteNode {
VBox.setVgrow(track, Priority.ALWAYS); VBox.setVgrow(track, Priority.ALWAYS);
VBox.setVgrow(icons, Priority.ALWAYS); VBox.setVgrow(icons, Priority.ALWAYS);
v.getStyleClass().add(CSS_VENDOR); v.getStyleClass().add(CSS_SYSTEM);
icons.getStyleClass().add(CSS_ICONS); icons.getStyleClass().add(CSS_ICONS);
track.getStyleClass().add(CSS_TRACK); track.getStyleClass().add(CSS_TRACK);
@@ -74,7 +75,7 @@ public class RouteNode {
if (cargo != null && cargo.isBuyer(p.get())){ if (cargo != null && cargo.isBuyer(p.get())){
v.getChildren().add(new Text(String.format(" (%+.0f) ", cargo.getProfit()))); v.getChildren().add(new Text(String.format(" (%+.0f) ", cargo.getProfit())));
cargo = null; cargo = null;
icons.getChildren().add(GlyphFontRegistry.glyph("FontAwesome|DOWNLOAD_ALT")); icons.getChildren().add(Glyph.create("FontAwesome|DOWNLOAD_ALT"));
} }
} }
node.getChildren().addAll(v, icons); node.getChildren().addAll(v, icons);

View File

@@ -10,10 +10,9 @@ import javafx.scene.text.Text;
import javafx.util.Callback; import javafx.util.Callback;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.controlsfx.glyphfont.Glyph; import org.controlsfx.glyphfont.Glyph;
import org.controlsfx.glyphfont.GlyphFontRegistry; import ru.trader.model.support.StationUpdater;
import ru.trader.model.support.VendorUpdater;
public class EditOfferCell extends TextFieldCell<VendorUpdater.FakeOffer, Double> { public class EditOfferCell extends TextFieldCell<StationUpdater.FakeOffer, Double> {
private final static String CSS_CHANGE = "change"; private final static String CSS_CHANGE = "change";
private final static String CSS_ADD = "add"; private final static String CSS_ADD = "add";
private final static String CSS_REMOVE = "remove"; private final static String CSS_REMOVE = "remove";
@@ -25,13 +24,13 @@ public class EditOfferCell extends TextFieldCell<VendorUpdater.FakeOffer, Double
this.isSell = isSell; this.isSell = isSell;
} }
public static Callback<TableColumn<VendorUpdater.FakeOffer,Double>, TableCell<VendorUpdater.FakeOffer,Double>> forTable(final StringConverter<Double> converter, boolean isSell) { public static Callback<TableColumn<StationUpdater.FakeOffer,Double>, TableCell<StationUpdater.FakeOffer,Double>> forTable(final StringConverter<Double> converter, boolean isSell) {
return list -> new EditOfferCell(converter, isSell); return list -> new EditOfferCell(converter, isSell);
} }
@Override @Override
protected void outItem() { protected void outItem() {
VendorUpdater.FakeOffer offer = (VendorUpdater.FakeOffer) getTableRow().getItem(); StationUpdater.FakeOffer offer = (StationUpdater.FakeOffer) getTableRow().getItem();
double d = isSell? offer.getSprice() - offer.getOldSprice() : offer.getBprice() - offer.getOldBprice(); double d = isSell? offer.getSprice() - offer.getOldSprice() : offer.getBprice() - offer.getOldBprice();
getStyleClass().removeAll(CSS_ADD, CSS_CHANGE, CSS_REMOVE); getStyleClass().removeAll(CSS_ADD, CSS_CHANGE, CSS_REMOVE);
if (d !=0 ){ if (d !=0 ){
@@ -48,7 +47,7 @@ public class EditOfferCell extends TextFieldCell<VendorUpdater.FakeOffer, Double
Text diff = new Text(String.format(" (%+.0f)", d)); Text diff = new Text(String.format(" (%+.0f)", d));
hBox.getChildren().add(diff); hBox.getChildren().add(diff);
} }
Glyph glyph = (Glyph) GlyphFontRegistry.glyph("FontAwesome|REMOVE"); Glyph glyph = Glyph.create("FontAwesome|REMOVE");
glyph.addEventFilter(MouseEvent.MOUSE_CLICKED, (e) -> { glyph.addEventFilter(MouseEvent.MOUSE_CLICKED, (e) -> {
Platform.runLater(() -> { Platform.runLater(() -> {
if (isSell) { if (isSell) {

View File

@@ -4,39 +4,38 @@ import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.util.Callback; import javafx.util.Callback;
import javafx.util.converter.DoubleStringConverter; import javafx.util.converter.DoubleStringConverter;
import ru.trader.model.OfferDescModel; import ru.trader.model.OfferModel;
public class PriceCellImpl implements Callback<TableColumn<OfferDescModel, Double>, TableCell<OfferDescModel, Double>> { public class PriceCellImpl implements Callback<TableColumn<OfferModel, Double>, TableCell<OfferModel, Double>> {
private final static String CSS_BAD = "bad"; private final static String CSS_BAD = "bad";
private final static String CSS_GOOD = "good"; private final static String CSS_GOOD = "good";
private final static String CSS_DIFF = "diff"; private final static String CSS_DIFF = "diff";
@Override @Override
public TableCell<OfferDescModel, Double> call(TableColumn<OfferDescModel, Double> param) { public TableCell<OfferModel, Double> call(TableColumn<OfferModel, Double> param) {
return new PriceCell(); return new PriceCell();
} }
private class PriceCell extends EditingCell<OfferDescModel, Double> { private class PriceCell extends EditingCell<OfferModel, Double> {
protected PriceCell() { protected PriceCell() {
super(new DoubleStringConverter()); super(new DoubleStringConverter());
} }
@Override @Override
protected void outText() { protected void outText() {
OfferDescModel offerDesc = (OfferDescModel) getTableRow().getItem(); OfferModel offer = (OfferModel) getTableRow().getItem();
if (offerDesc!=null){ if (offer!=null){
double d = offerDesc.getDiff(); double d = offer.getDiff();
HBox txt = new HBox(); HBox txt = new HBox();
Text price = new Text(String.format("%.0f", offerDesc.getPrice())); Text price = new Text(String.format("%.0f", offer.getPrice()));
Text diff = new Text(String.format(" (%+.0f)", d)); Text diff = new Text(String.format(" (%+.0f)", d));
diff.getStyleClass().add(CSS_DIFF); diff.getStyleClass().add(CSS_DIFF);
txt.getChildren().addAll(price, diff); txt.getChildren().addAll(price, diff);
this.getStyleClass().removeAll(CSS_BAD, CSS_GOOD); this.getStyleClass().removeAll(CSS_BAD, CSS_GOOD);
String cssClass = (d == 0 || Double.isNaN(d) ? "" : d * offerDesc.getOffer().getType().getOrder() > 0 ? CSS_BAD : CSS_GOOD ); String cssClass = (d == 0 || Double.isNaN(d) ? "" : d * offer.getType().getOrder() > 0 ? CSS_BAD : CSS_GOOD );
this.getStyleClass().add(cssClass); this.getStyleClass().add(cssClass);
this.setText(null); this.setText(null);
this.setGraphic(txt); this.setGraphic(txt);

View File

@@ -1,14 +1,17 @@
# Market # Market
market.vendors=Stations market.systems=Systems
market.stations=Stations
market.items=Commods market.items=Commods
market.offers=Offers market.offers=Offers
market.item.name=Commodity market.item.name=Commodity
market.vendor.name=Station market.station.name=Station
# Offer # Offer
market.offer.buy=Buy market.offer.buy=Buy
market.offer.sell=Sell market.offer.sell=Sell
market.offer.price=Price market.offer.price=Price
market.offer.supply=Supply
market.offer.demand=Demand
market.offer.min=Min market.offer.min=Min
market.offer.avg=Avg market.offer.avg=Avg
market.offer.max=Max market.offer.max=Max
@@ -42,9 +45,13 @@ main.menu.file=File
main.menu.file.save=Save main.menu.file.save=Save
main.menu.file.import=Import... main.menu.file.import=Import...
main.menu.edit=Edit main.menu.edit=Edit
main.menu.edit.addSystem=Add System
main.menu.edit.editSystem=Edit System
main.menu.edit.removeSystem=Delete System
main.menu.edit.addStation=Add Station main.menu.edit.addStation=Add Station
main.menu.edit.addItem=Add Commodity
main.menu.edit.editStation=Edit Station main.menu.edit.editStation=Edit Station
main.menu.edit.removeStation=Delete Station
main.menu.edit.addItem=Add Commodity
main.menu.settings=Settings main.menu.settings=Settings
main.menu.settings.language=Language main.menu.settings.language=Language
main.menu.settings.language.item=English main.menu.settings.language.item=English

View File

@@ -1,14 +1,17 @@
# Market # Market
market.vendors=\u0421\u0442\u0430\u043D\u0446\u0438\u0438 market.systems=\u0421\u0438\u0441\u0442\u0435\u043C\u044B
market.stations=\u0421\u0442\u0430\u043D\u0446\u0438\u0438
market.items=\u0422\u043E\u0432\u0430\u0440\u044B market.items=\u0422\u043E\u0432\u0430\u0440\u044B
market.offers=\u0417\u0430\u043A\u0430\u0437\u044B market.offers=\u0417\u0430\u043A\u0430\u0437\u044B
market.item.name=\u0422\u043E\u0432\u0430\u0440 market.item.name=\u0422\u043E\u0432\u0430\u0440
market.vendor.name=\u0421\u0442\u0430\u043D\u0446\u0438\u044F market.station.name=\u0421\u0442\u0430\u043D\u0446\u0438\u044F
# Offer # Offer
market.offer.buy=\u041F\u043E\u043A\u0443\u043F\u043A\u0430 market.offer.buy=\u041F\u043E\u043A\u0443\u043F\u043A\u0430
market.offer.sell=\u041F\u0440\u043E\u0434\u0430\u0436\u0430 market.offer.sell=\u041F\u0440\u043E\u0434\u0430\u0436\u0430
market.offer.price=\u0426\u0435\u043D\u0430 market.offer.price=\u0426\u0435\u043D\u0430
market.offer.supply=\u0417\u0430\u043F\u0430\u0441
market.offer.demand=\u0421\u043F\u0440\u043E\u0441
market.offer.min=\u041C\u0438\u043D. market.offer.min=\u041C\u0438\u043D.
market.offer.avg=\u0421\u0440. market.offer.avg=\u0421\u0440.
market.offer.max=\u041C\u0430\u043A\u0441. market.offer.max=\u041C\u0430\u043A\u0441.
@@ -43,9 +46,13 @@ main.menu.file=\u0424\u0430\u0439\u043B
main.menu.file.save=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C main.menu.file.save=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
main.menu.file.import=\u0418\u043C\u043F\u043E\u0440\u0442... main.menu.file.import=\u0418\u043C\u043F\u043E\u0440\u0442...
main.menu.edit=\u041F\u0440\u0430\u0432\u043A\u0430 main.menu.edit=\u041F\u0440\u0430\u0432\u043A\u0430
main.menu.edit.addSystem=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0438\u0441\u0442\u0435\u043C\u0443
main.menu.edit.editSystem=\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0438\u0441\u0442\u0435\u043C\u0443
main.menu.edit.removeSystem=\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0438\u0441\u0442\u0435\u043C\u0443
main.menu.edit.addStation=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0442\u0430\u043D\u0446\u0438\u044E main.menu.edit.addStation=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0442\u0430\u043D\u0446\u0438\u044E
main.menu.edit.addItem=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u043E\u0432\u0430\u0440
main.menu.edit.editStation=\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0430\u043D\u0446\u0438\u044E main.menu.edit.editStation=\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0430\u043D\u0446\u0438\u044E
main.menu.edit.removeStation=\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0442\u0430\u043D\u0446\u0438\u044E
main.menu.edit.addItem=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u043E\u0432\u0430\u0440
main.menu.settings=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 main.menu.settings=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
main.menu.settings.language=\u042F\u0437\u044B\u043A main.menu.settings.language=\u042F\u0437\u044B\u043A
main.menu.settings.language.item=\u0420\u0443\u0441\u0441\u043A\u0438\u0439 main.menu.settings.language.item=\u0420\u0443\u0441\u0441\u043A\u0438\u0439

View File

@@ -14,8 +14,12 @@
<MenuItem text="%main.menu.file.import" onAction="#importWorld"/> <MenuItem text="%main.menu.file.import" onAction="#importWorld"/>
</Menu> </Menu>
<Menu text="%main.menu.edit"> <Menu text="%main.menu.edit">
<MenuItem text="%main.menu.edit.addStation" onAction="#addVendor"/> <MenuItem text="%main.menu.edit.addSystem" onAction="#addSystem"/>
<MenuItem text="%main.menu.edit.editStation" onAction="#editVendor"/> <MenuItem text="%main.menu.edit.editSystem" onAction="#editSystem"/>
<MenuItem text="%main.menu.edit.removeSystem" onAction="#removeSystem"/>
<MenuItem text="%main.menu.edit.addStation" onAction="#addStation"/>
<MenuItem text="%main.menu.edit.editStation" onAction="#editStation"/>
<MenuItem text="%main.menu.edit.removeStation" onAction="#removeStation"/>
</Menu> </Menu>
<Menu text="%main.menu.settings"> <Menu text="%main.menu.settings">
<MenuItem text="%main.menu.settings.parameters" onAction="#editSettings"/> <MenuItem text="%main.menu.settings.parameters" onAction="#editSettings"/>
@@ -28,7 +32,7 @@
<Tab text="%market.items"> <Tab text="%market.items">
<fx:include fx:id="items" source="items.fxml"/> <fx:include fx:id="items" source="items.fxml"/>
</Tab> </Tab>
<Tab text="%market.vendors"> <Tab text="%market.systems">
<fx:include fx:id="offers" source="offers.fxml"/> <fx:include fx:id="offers" source="offers.fxml"/>
</Tab> </Tab>
<Tab text="%routes"> <Tab text="%routes">

View File

@@ -9,24 +9,38 @@
<?import ru.trader.view.support.cells.OfferCellValueImpl?> <?import ru.trader.view.support.cells.OfferCellValueImpl?>
<?import ru.trader.view.support.cells.DoubleCell?> <?import ru.trader.view.support.cells.DoubleCell?>
<HBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" <?import org.controlsfx.glyphfont.Glyph?>
<?import org.controlsfx.control.SegmentedButton?>
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="ru.trader.controllers.OffersController"> fx:controller="ru.trader.controllers.OffersController">
<TitledPane text="%market.vendors" minWidth="250" prefHeight="510" collapsible="false">
<ListView fx:id="vendors"> <fx:define><Insets fx:id="stationsMargin" left="5" right="5" /></fx:define>
<fx:define><Insets fx:id="stationsPadding" left="12" right="10" /></fx:define>
<columnConstraints>
<ColumnConstraints minWidth="250" maxWidth="250"/>
<ColumnConstraints fillWidth="true"/>
</columnConstraints>
<TitledPane GridPane.rowSpan="2" text="%market.systems" minWidth="250" prefHeight="510" collapsible="false">
<ListView fx:id="systems">
<contextMenu> <contextMenu>
<ContextMenu> <ContextMenu>
<items> <items>
<MenuItem text="%main.menu.edit.addStation" onAction="#addVendor" /> <MenuItem text="%main.menu.edit.addStation" onAction="#addStation" />
<MenuItem text="%main.menu.edit.editStation" onAction="#editVendor" /> <MenuItem text="%main.menu.edit.editStation" onAction="#editStation" />
</items> </items>
</ContextMenu> </ContextMenu>
</contextMenu> </contextMenu>
</ListView> </ListView>
</TitledPane> </TitledPane>
<Accordion HBox.hgrow="ALWAYS"> <TitledPane GridPane.columnIndex="1" text="%market.stations" maxHeight="60" collapsible="false">
<SegmentedButton fx:id="stationsBar" />
</TitledPane>
<Accordion GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS">
<panes> <panes>
<TitledPane fx:id="sells" animated="false" text="%offers.pane.sell"> <TitledPane fx:id="paneSells" animated="false" text="%offers.pane.sell">
<TableView fx:id="tblSell" editable="true"> <TableView fx:id="tblSell" editable="true">
<columns> <columns>
<TableColumn minWidth="230.0" text="%market.item.name"> <TableColumn minWidth="230.0" text="%market.item.name">
@@ -36,6 +50,9 @@
<cellFactory><PriceCellImpl/></cellFactory> <cellFactory><PriceCellImpl/></cellFactory>
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="80.0" text="%market.offer.supply">
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
</TableColumn>
<TableColumn fx:id="sortSell" minWidth="90.0" text="%market.order.profit" sortType="DESCENDING"> <TableColumn fx:id="sortSell" minWidth="90.0" text="%market.order.profit" sortType="DESCENDING">
<cellFactory><DoubleCell/></cellFactory> <cellFactory><DoubleCell/></cellFactory>
<cellValueFactory><PropertyValueFactory property="profit"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="profit"/></cellValueFactory>
@@ -81,6 +98,9 @@
<cellFactory><PriceCellImpl/></cellFactory> <cellFactory><PriceCellImpl/></cellFactory>
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="80.0" text="%market.offer.demand">
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
</TableColumn>
<TableColumn fx:id="sortBuy" minWidth="90.0" text="%market.order.profit" sortType="DESCENDING"> <TableColumn fx:id="sortBuy" minWidth="90.0" text="%market.order.profit" sortType="DESCENDING">
<cellFactory><DoubleCell/></cellFactory> <cellFactory><DoubleCell/></cellFactory>
<cellValueFactory><PropertyValueFactory property="profit"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="profit"/></cellValueFactory>
@@ -118,7 +138,7 @@
</TitledPane> </TitledPane>
</panes> </panes>
<expandedPane> <expandedPane>
<fx:reference source="sells"/> <fx:reference source="paneSells"/>
</expandedPane> </expandedPane>
</Accordion> </Accordion>
</HBox> </GridPane>

View File

@@ -80,7 +80,7 @@
<TableView fx:id="tblOrders" VBox.vgrow="ALWAYS"> <TableView fx:id="tblOrders" VBox.vgrow="ALWAYS">
<columns> <columns>
<TableColumn minWidth="210.0" text="%market.order.seller"> <TableColumn minWidth="210.0" text="%market.order.seller">
<cellValueFactory><PropertyValueFactory property="vendor"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="station"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="180.0" text="%market.item.name"> <TableColumn minWidth="180.0" text="%market.item.name">
<cellValueFactory><PropertyValueFactory property="name"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="name"/></cellValueFactory>

View File

@@ -15,7 +15,7 @@
</columnConstraints> </columnConstraints>
<Label text="%settings.emdn" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2"/> <Label text="%settings.emdn" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2"/>
<Label text="%settings.emdn.on" GridPane.rowIndex="1"/> <Label text="%settings.emdn.on" GridPane.rowIndex="1"/>
<CheckBox fx:id="emdnOn" GridPane.columnIndex="1" GridPane.rowIndex="1"/> <CheckBox fx:id="emdnOn" GridPane.columnIndex="1" GridPane.rowIndex="1" disable="true"/>
<Label text="%settings.emdn.sub" GridPane.rowIndex="2" /> <Label text="%settings.emdn.sub" GridPane.rowIndex="2" />
<TextField fx:id="emdnSubServ" GridPane.columnIndex="1" GridPane.rowIndex="2" /> <TextField fx:id="emdnSubServ" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="%settings.emdn.updateOnly" GridPane.rowIndex="3" /> <Label text="%settings.emdn.updateOnly" GridPane.rowIndex="3" />

View File

@@ -61,7 +61,7 @@ HBox.fields-group hbox-margin{
-fx-fill-height: true; -fx-fill-height: true;
} }
.path-vendor { .path-system {
-fx-alignment: center-left; -fx-alignment: center-left;
-fx-text-alignment: left; -fx-text-alignment: left;
} }

View File

@@ -10,7 +10,7 @@
<?import ru.trader.view.support.NumberField?> <?import ru.trader.view.support.NumberField?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<GridPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" <GridPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8"
fx:controller="ru.trader.controllers.VendorEditorController" styleClass="dialog" fx:controller="ru.trader.controllers.StationEditorController" styleClass="dialog"
vgap="10" hgap="4"> vgap="10" hgap="4">
<fx:define><Insets fx:id="hbox_margin" left="10" /></fx:define> <fx:define><Insets fx:id="hbox_margin" left="10" /></fx:define>
<TextField fx:id="name" GridPane.columnSpan="2" alignment="CENTER" /> <TextField fx:id="name" GridPane.columnSpan="2" alignment="CENTER" />

View File

@@ -72,7 +72,7 @@
<dependency> <dependency>
<groupId>org.controlsfx</groupId> <groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId> <artifactId>controlsfx</artifactId>
<version>8.0.6</version> <version>8.20.8</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sleepycat</groupId> <groupId>com.sleepycat</groupId>