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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,7 @@ package ru.trader.controllers;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
@@ -10,6 +11,7 @@ import javafx.scene.input.MouseButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.model.*;
import ru.trader.model.support.BindingsHelper;
import ru.trader.model.support.ChangeMarketListener;
import ru.trader.model.support.ModelBindings;
@@ -18,14 +20,16 @@ public class ItemsController {
private final static Logger LOG = LoggerFactory.getLogger(ItemsController.class);
@FXML
private TableView<ItemDescModel> tblItems;
private TableView<ItemModel> tblItems;
@FXML
private TableColumn<ItemDescModel, Number> minProfit;
private TableColumn<ItemModel, Number> minProfit;
@FXML
private TableColumn<ItemDescModel, Number> avgProfit;
private TableColumn<ItemModel, Number> avgProfit;
@FXML
private TableColumn<ItemDescModel, Number> maxProfit;
private TableColumn<ItemModel, Number> maxProfit;
private final ObservableList<ItemModel> items = FXCollections.observableArrayList();
@FXML
private void initialize() {
@@ -38,24 +42,26 @@ public class ItemsController {
}
});
minProfit.setCellValueFactory((data) -> {
ItemDescModel iDesc = data.getValue();
ItemModel iDesc = data.getValue();
return ModelBindings.diff(iDesc.minBuyProperty(),iDesc.maxSellProperty());
});
avgProfit.setCellValueFactory((data) -> {
ItemDescModel iDesc = data.getValue();
ItemModel iDesc = data.getValue();
return iDesc.avgBuyProperty().subtract(iDesc.avgSellProperty());
});
maxProfit.setCellValueFactory((data) -> {
ItemDescModel iDesc = data.getValue();
ItemModel iDesc = data.getValue();
return ModelBindings.diff(iDesc.maxBuyProperty(), iDesc.minSellProperty());
});
BindingsHelper.setTableViewItems(tblItems, items);
init();
}
void init(){
MarketModel market = MainController.getMarket();
market.addListener(new ItemsStatChangeListener());
tblItems.setItems(FXCollections.observableArrayList(market.itemsProperty()));
market.getNotificator().add(new ItemsStatChangeListener());
items.clear();
items.addAll(market.itemsProperty());
sort();
}
@@ -64,53 +70,41 @@ public class ItemsController {
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(){
LOG.info("Refresh all stats");
tblItems.getItems().forEach(ItemDescModel::refresh);
tblItems.getItems().forEach(ItemModel::refresh);
sort();
}
private void addItem(ItemDescModel item){
tblItems.getItems().add(item);
sort();
private void addItem(ItemModel item){
items.add(item);
}
private class ItemsStatChangeListener extends ChangeMarketListener {
@Override
public void add(ItemDescModel item) {
public void add(ItemModel item) {
addItem(item);
}
@Override
public void add(OfferModel offer) {
refresh(offer);
}
@Override
public void add(VendorModel vendor) {
public void add(StationModel station) {
refresh();
}
@Override
public void add(OfferModel offer) {
sort();
}
@Override
public void remove(OfferModel offer) {
refresh(offer);
sort();
}
@Override
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) {
MarketModel old = MainController.market;
MainController.market = market;
MainController.market.addAllListener(old.getListeners());
Screeners.reinitAll();
}
@@ -134,19 +132,35 @@ public class MainController {
.showTextInput();
ItemModel item = null;
if (res.isPresent()){
item = market.newItem(res.get());
market.add(item);
//TODO: implement groups
// item = market.add(res.get());
}
return Optional.ofNullable(item);
}
public void addVendor(ActionEvent actionEvent) {
Screeners.showAddVendor();
public void addSystem(ActionEvent actionEvent){
//TODO: implement
}
public void editVendor(ActionEvent actionEvent) {
Screeners.showEditVendor(offersController.getVendor());
public void editSystem(ActionEvent actionEvent){
//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(){

View File

@@ -3,81 +3,125 @@ package ru.trader.controllers;
import javafx.application.Platform;
import javafx.collections.FXCollections;
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.layout.Background;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import org.controlsfx.control.SegmentedButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import ru.trader.model.*;
import ru.trader.model.support.BindingsHelper;
import ru.trader.model.support.ChangeMarketListener;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class OffersController {
private final static Logger LOG = LoggerFactory.getLogger(OffersController.class);
private VendorModel vendor;
private StationModel station;
private SystemModel system;
@FXML
private ListView<VendorModel> vendors;
private Insets stationsMargin;
@FXML
private TableView<OfferDescModel> tblSell;
private ListView<SystemModel> systems;
@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
private void initialize() {
vendors.getSelectionModel().selectedItemProperty().addListener((ob, oldValue, newValue) ->{
systems.getSelectionModel().selectedItemProperty().addListener((ob, oldValue, newValue) ->{
if (newValue != null){
LOG.info("Change vendor to {}", newValue);
this.vendor = newValue;
fillTables(vendor);
LOG.info("Change system to {}", newValue);
fillDetails(newValue);
} 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) -> {
if (n!=null) Screeners.changeItemDesc(n);
if (n != null) Screeners.changeItemDesc(n.getItem());
});
tblBuy.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> {
if (n!=null) Screeners.changeItemDesc(n);
if (n != null) Screeners.changeItemDesc(n.getItem());
});
tblSell.setOnMouseClicked((e) -> {
if (e.getButton() == MouseButton.SECONDARY){
if (e.getButton() == MouseButton.SECONDARY) {
Screeners.showItemDesc(tblSell);
}
});
tblBuy.setOnMouseClicked((e) -> {
if (e.getButton() == MouseButton.SECONDARY){
if (e.getButton() == MouseButton.SECONDARY) {
Screeners.showItemDesc(tblBuy);
}
});
BindingsHelper.setTableViewItems(tblSell, sells);
BindingsHelper.setTableViewItems(tblBuy, buys);
init();
}
void init(){
MarketModel market = MainController.getMarket();
market.addListener(new OffersChangeListener());
vendors.setItems(market.vendorsProperty());
vendors.getSelectionModel().selectFirst();
market.getNotificator().add(new OffersChangeListener());
systems.setItems(market.systemsProperty());
systems.getSelectionModel().selectFirst();
}
private void fillTables(VendorModel vendor){
if (vendor != null){
tblSell.setItems(FXCollections.observableList(vendor.getSells(this::asOfferDescModel)));
tblBuy.setItems(FXCollections.observableList(vendor.getBuys(this::asOfferDescModel)));
sort();
} else {
tblSell.getItems().clear();
tblBuy.getItems().clear();
private void fillDetails(SystemModel system){
this.system = system;
List<StationModel> stations = system.getStations();
stationsBar.getButtons().clear();
stations.forEach(s -> stationsBar.getButtons().add(buildStationNode(s)));
if (!stations.isEmpty()){
stationsBar.getButtons().get(0).setSelected(true);
}
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
public void editPrice(TableColumn.CellEditEvent<OfferDescModel, Double> event){
OfferModel offer = event.getRowValue().getOffer();
public void editPrice(TableColumn.CellEditEvent<OfferModel, Double> event){
OfferModel offer = event.getRowValue();
offer.setPrice(event.getNewValue());
}
public VendorModel getVendor() {
return vendor;
public SystemModel getSystem() {
return system;
}
public void addVendor(ActionEvent actionEvent) {
Screeners.showAddVendor();
public StationModel getStation() {
return station;
}
public void editVendor(ActionEvent actionEvent) {
Screeners.showEditVendor(vendor);
public void addStation(ActionEvent actionEvent) {
Screeners.showAddStation(system);
}
private OfferDescModel asOfferDescModel(OfferModel offer){
return MainController.getMarket().asOfferDescModel(offer);
public void editStation(ActionEvent actionEvent) {
Screeners.showEditStation(station);
}
private void addOffer(OfferModel offer){
switch (offer.getType()){
case SELL: tblSell.getItems().add(asOfferDescModel(offer));
case SELL: sells.add(offer);
break;
case BUY: tblBuy.getItems().add(asOfferDescModel(offer));
case BUY: buys.add(offer);
break;
}
}
private void removeOffer(OfferModel offer){
switch (offer.getType()){
case SELL: remove(offer, tblSell.getItems());
case SELL: sells.remove(offer);
break;
case BUY: remove(offer, tblBuy.getItems());
case BUY: buys.remove(offer);
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(){
LOG.info("Refresh lists");
tblSell.getItems().forEach(OfferDescModel::refresh);
tblBuy.getItems().forEach(OfferDescModel::refresh);
sort();
tblSell.getItems().forEach(OfferModel::refresh);
tblBuy.getItems().forEach(OfferModel::refresh);
}
private class OffersChangeListener extends ChangeMarketListener {
@Override
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();
}
}
@Override
public void add(OfferModel offer) {
refresh(offer);
if (offer.hasVendor(vendor)){
if (offer.getStation().equals(station)){
addOffer(offer);
}
}
@Override
public void add(VendorModel vendor) {
public void add(StationModel station) {
refresh();
sort();
}
@Override
public void remove(OfferModel offer) {
refresh(offer);
if (offer.hasVendor(vendor)) {
if (offer.getStation().equals(station)){
removeOffer(offer);
}
}

View File

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

View File

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

View File

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

View File

@@ -31,7 +31,7 @@ public class Screeners {
private static MainController mainController;
private static ItemDescController itemDescController;
private static VendorEditorController vEditorController;
private static StationEditorController vEditorController;
private static OffersEditorController oEditorController;
private static OrdersController ordersController;
private static TopOrdersController topOrdersController;
@@ -131,12 +131,12 @@ public class Screeners {
return Dialogs.create().owner(mainScreen).message(text).showConfirm();
}
public static void showAddVendor(){
vEditorController.showDialog(mainScreen, vEditorScreen, null);
public static void showAddStation(SystemModel system){
vEditorController.showDialog(mainScreen, vEditorScreen, system, null);
}
public static void showEditVendor(VendorModel vendor){
vEditorController.showDialog(mainScreen, vEditorScreen, vendor);
public static void showEditStation(StationModel station){
vEditorController.showDialog(mainScreen, vEditorScreen, station);
}
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);
}
public static void changeItemDesc(ItemDescModel item){
public static void changeItemDesc(ItemModel item){
itemDescController.setItemDesc(item);
}

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
package ru.trader.controllers;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.TableColumn;
@@ -9,27 +8,18 @@ import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.LongStringConverter;
import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogAction;
import ru.trader.model.OrderModel;
import ru.trader.model.support.BindingsHelper;
import ru.trader.view.support.Localization;
import java.util.Collection;
import java.util.List;
public class TopOrdersController {
private final Action OK = new AbstractAction("OK") {
{
ButtonBar.setType(this, ButtonBar.ButtonType.OK_DONE);
}
@Override
public void handle(ActionEvent event) {
Dialog dlg = (Dialog) event.getSource();
dlg.hide();
}
};
private final Action OK = new DialogAction("OK", ButtonBar.ButtonType.OK_DONE, false, true, false);
@FXML
private TableView<OrderModel> tblOrders;
@@ -39,10 +29,13 @@ public class TopOrdersController {
private OrderModel order;
private final List<OrderModel> orders = FXCollections.observableArrayList();
@FXML
private void initialize() {
count.setCellFactory(TextFieldTableCell.forTableColumn(new LongStringConverter()));
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"));
dlg.setContent(content);
dlg.getActions().addAll(OK, Dialog.Actions.CANCEL);
dlg.getActions().addAll(OK, Dialog.ACTION_CANCEL);
dlg.setResizable(false);
OrderModel res = dlg.show() == OK ? order : null;
tblOrders.getItems().clear();
this.orders.clear();
return res;
}
private void init(Collection<OrderModel> orders) {
tblOrders.getSelectionModel().clearSelection();
tblOrders.setItems(FXCollections.observableArrayList(orders));
if (tblOrders.getSortOrder().size()>0)
tblOrders.sort();
this.orders.addAll(orders);
}
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;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.Item;
import ru.trader.core.OFFER_TYPE;
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 Item item;
private final MarketModel market;
private StringProperty name;
private final ItemStatModel statSell;
private final ItemStatModel statBuy;
ItemModel(Item item, MarketModel market) {
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 boolean isMarketItem(){
return item.getGroup() != null && item.getGroup().isMarket();
}
public String getName() {return name != null ? name.get() : item.getName();}
public void setName(String value) {
LOG.info("Change name of item {} to {}", item, name);
market.updateName(this, value);
LOG.info("Change name of item {} to {}", item, value);
item.setName(value);
if (name != null) name.set(value);
}
public ReadOnlyStringProperty nameProperty() {
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);
}
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
public String toString() {
if (LOG.isTraceEnabled()){
final StringBuilder sb = new StringBuilder("ItemModel{");
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('}');
return sb.toString();
}
return item.toString();
}
Item getItem() {
return item;
}
}

View File

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

View File

@@ -10,10 +10,7 @@ import ru.trader.World;
import ru.trader.core.*;
import ru.trader.graph.PathRoute;
import ru.trader.model.support.BindingsHelper;
import ru.trader.model.support.ChangeMarketListener;
import java.util.ArrayList;
import java.util.Collection;
import ru.trader.model.support.Notificator;
public class MarketModel {
@@ -21,222 +18,98 @@ public class MarketModel {
private final Market market;
private final MarketAnalyzer analyzer;
private final ModelFabric modeler;
private final Notificator notificator;
private final Collection<ChangeMarketListener> listener = new ArrayList<>();
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;
}
private final ListProperty<SystemModel> systems;
private final ListProperty<ItemModel> items;
public MarketModel(Market market) {
this.market = market;
analyzer = World.buildAnalyzer(market);
items = new SimpleListProperty<ItemDescModel>(BindingsHelper.observableList(market.getItems(), this::getItemDesc));
vendors = new SimpleListProperty<VendorModel>(BindingsHelper.observableList(market.get(), this::asModel));
modeler = new ModelFabric(this);
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){
synchronized (this.listener){
this.listener.add(listener);
}
public MarketAnalyzer getAnalyzer() {
return analyzer;
}
public void removeListeners() {
synchronized (listener){
listener.clear();
}
public ModelFabric getModeler() {
return modeler;
}
public void addAllListener(Collection<? extends ChangeMarketListener> listener){
synchronized (this.listener){
this.listener.addAll(listener);
}
public Notificator getNotificator() {
return notificator;
}
public Collection<ChangeMarketListener> getListeners() {
return listener;
public ReadOnlyListProperty<SystemModel> systemsProperty() {
return systems;
}
void updatePosition(VendorModel model, double x, double y, double z) {
Vendor vendor = model.getVendor();
double oldX = vendor.getX();
double oldY = vendor.getY();
double oldZ = vendor.getZ();
market.updatePosition(vendor, x, y, z);
if (alert) listener.forEach((c) -> c.positionChange(model, oldX, oldY, oldZ, x, y, z));
public SystemModel add(String name, double x, double y, double z) {
SystemModel system = modeler.get(market.addPlace(name, x, y, z));
LOG.info("Add system {} to market {}", system, this);
notificator.sendAdd(system);
systems.add(system);
return system;
}
void updateName(ItemModel model, String value) {
Item item = model.getItem();
String old = item.getName();
market.updateName(item, value);
if (alert) listener.forEach((c) -> c.nameChange(model, old, value));
public ReadOnlyListProperty<ItemModel> itemsProperty() {
return items;
}
void updateName(VendorModel model, String value) {
Vendor vendor = model.getVendor();
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) {
public ItemModel add(String name, Group group) {
ItemModel item = modeler.get(market.addItem(name, group));
LOG.info("Add item {} to market {}", item, this);
market.add(item.getItem());
ItemDescModel model = getItemDesc(item);
if (alert) listener.forEach((c) -> c.add(model));
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);
notificator.sendAdd(item);
items.add(item);
return item;
}
ItemStat getStat(OFFER_TYPE type, Item item){
return market.getStat(type, item);
}
public OfferModel asModel(Offer offer){
return ModelFabrica.getModel(offer, this);
public ObservableList<OrderModel> getOrders(SystemModel from, double balance) {
return BindingsHelper.observableList(analyzer.getOrders(from.getSystem(), balance), modeler::get);
}
public ItemModel asModel(Item item){
return ModelFabrica.getModel(item, this);
public ObservableList<OrderModel> getOrders(SystemModel from, SystemModel to, double balance) {
return BindingsHelper.observableList(analyzer.getOrders(from.getSystem(), to.getSystem(), balance), modeler::get);
}
public VendorModel asModel(Vendor vendor) {
return ModelFabrica.getModel(vendor, this);
}
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> getOrders(StationModel from, StationModel to, double balance) {
return BindingsHelper.observableList(analyzer.getOrders(from.getStation(), to.getStation(), balance), modeler::get);
}
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){
return BindingsHelper.observableList(analyzer.getPaths(from.getVendor(), balance), this::asModel);
public ObservableList<PathRouteModel> getRoutes(SystemModel from, double balance){
return BindingsHelper.observableList(analyzer.getPaths(from.getSystem(), balance), modeler::get);
}
public ObservableList<PathRouteModel> getRoutes(VendorModel from, VendorModel to, double balance){
return BindingsHelper.observableList(analyzer.getPaths(from.getVendor(), to.getVendor(), balance), this::asModel);
public ObservableList<PathRouteModel> getRoutes(SystemModel from, SystemModel to, double balance){
return BindingsHelper.observableList(analyzer.getPaths(from.getSystem(), to.getSystem(), balance), modeler::get);
}
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) {
return analyzer.getPath(from.getVendor(), to.getVendor());
PathRoute getPath(SystemModel from, SystemModel to) {
return analyzer.getPath(from.getSystem(), to.getSystem());
}
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;
p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount()));
order.setPath(p);
return asModel(p);
return modeler.get(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;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.trader.core.OFFER_TYPE;
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 MarketModel market;
private final Offer offer;
private final MarketModel market;
private final ItemModel item;
private DoubleProperty price;
private LongProperty count;
private DoubleProperty diff;
private DoubleProperty maxProfit;
private DoubleProperty minProfit;
private DoubleProperty avgProfit;
OfferModel(Offer offer, MarketModel market) {
this.market = market;
this.offer = offer;
private SystemModel asModel(Place system){
return market.getModeler().get(system);
}
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 void setPrice(double value) {
if (getPrice() == value) return;
double old = getPrice();
if (old == value) return;
LOG.info("Change price offer {} to {}", offer, value);
market.updatePrice(this, value);
offer.setPrice(value);
if (price != null) price.set(value);
refresh();
market.getNotificator().sendPriceChange(this, old, value);
}
public ReadOnlyDoubleProperty priceProperty() {
@@ -36,37 +82,140 @@ public class OfferModel{
return price;
}
public ItemModel getItem() {
return market.asModel(offer.getItem());
public long getCount() {return count != null ? count.get() : offer.getCount();}
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() {
return market.asModel(offer.getVendor());
public ReadOnlyLongProperty countProperty() {
if (count == null) {
count = new SimpleLongProperty(offer.getCount());
}
return count;
}
public OFFER_TYPE getType(){
return offer.getType();
public ReadOnlyStringProperty nameProperty() {
return item.nameProperty();
}
public boolean isModel(Offer offer) {
return this.offer == offer;
public ReadOnlyDoubleProperty avgBuyProperty() {
return item.avgBuyProperty();
}
public boolean hasVendor(VendorModel vendor){
return offer.getVendor().equals(vendor.getVendor());
public ReadOnlyObjectProperty<OfferModel> minBuyProperty() {
return item.minBuyProperty();
}
public boolean hasItem(ItemModel item){
return offer.getItem().equals(item.getItem());
public ReadOnlyObjectProperty<OfferModel> maxBuyProperty() {
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
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OfferModel)) return false;
OfferModel that = (OfferModel) o;
return offer.equals(that.offer);
}
@@ -82,22 +231,12 @@ public class OfferModel{
final StringBuilder sb = new StringBuilder("OfferModel{");
sb.append("priceProp=").append(price);
sb.append(", offer=").append(offer.toString());
sb.append(", item=").append(item.toString());
sb.append('}');
return sb.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;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import ru.trader.core.Order;
import ru.trader.graph.PathRoute;
import ru.trader.model.support.ModelBindings;
@@ -10,23 +10,25 @@ import java.util.List;
public class OrderModel {
private final OfferDescModel offer;
private final OfferModel offer;
private final LongProperty count;
private final ObjectProperty<OfferModel> buyer = new SimpleObjectProperty<>();
private long max;
private LongProperty max;
private DoubleProperty profit;
private DoubleProperty distance;
private DoubleProperty bestProfit;
private PathRoute path;
public OrderModel(OfferDescModel offer) {
public OrderModel(OfferModel offer) {
this.offer = offer;
this.max = new SimpleLongProperty(0);
this.count = new SimpleLongProperty(0){
@Override
public void setValue(Number v) {
if (max > 0 && v.longValue() > max){
super.setValue(max);
long limit = max.get();
if (limit > 0 && v.longValue() > limit){
super.setValue(limit);
} else {
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.max = max;
this.max.setValue(max);
setBuyOffer(buyOffer);
setCount(max);
}
public OrderModel(OfferDescModel offer, double balance, long limit) {
public OrderModel(OfferModel offer, double balance, long limit) {
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() {
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() {
@@ -58,26 +107,35 @@ public class OrderModel {
return offer.priceProperty();
}
public ReadOnlyLongProperty supplyProperty() {
return offer.countProperty();
}
public ReadOnlyObjectProperty<OfferModel> bestProperty(){
return offer.bestBuyProperty();
}
public long getCount() {
return count.get();
public List<OfferModel> getBuyers(){
return offer.getBuyer();
}
public LongProperty countProperty() {
return count;
public StationModel getBuyer() {
OfferModel buyOffer = getBuyOffer();
return buyOffer != null ? buyer.get().getStation() : null;
}
public void setCount(long count) {
this.count.set(count);
public double getProfit() {
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() {
if (profit == null){
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;
}
@@ -90,66 +148,16 @@ public class OrderModel {
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() {
if (distance == null){
VendorModel buyer = getBuyer();
distance = new SimpleDoubleProperty(buyer!=null ? getVendor().getDistance(buyer) : Double.NaN);
StationModel buyer = getBuyer();
distance = new SimpleDoubleProperty(buyer!=null ? getStation().getDistance(buyer) : Double.NaN);
}
return distance;
}
void setPath(PathRoute path) {
this.path = path;
}
PathRoute getPath() {
return path;
}
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();
if (cargo == null && p.getBest()!=null){
cargo = p.getBest();
OrderModel order = market.asModel(cargo);
OrderModel order = market.getModeler().get(cargo);
order.setPath(p);
res.add(order);
}
@@ -82,7 +82,7 @@ public class PathRouteModel {
}
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;
p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount()));
PathRoute head = path.getEnd();
@@ -95,6 +95,6 @@ public class PathRouteModel {
}
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.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.SortedList;
import javafx.scene.control.TableView;
import java.util.ArrayList;
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;
import ru.trader.model.ItemDescModel;
import ru.trader.model.ItemModel;
import ru.trader.model.OfferModel;
import ru.trader.model.VendorModel;
import ru.trader.model.*;
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(VendorModel vendor) {
}
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 ru.trader.model.ItemModel;
import ru.trader.model.OfferModel;
import ru.trader.model.VendorModel;
import ru.trader.model.SystemModel;
public class ModelBindings {
@@ -17,11 +17,11 @@ public class ModelBindings {
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){
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){
@@ -64,7 +64,7 @@ public class ModelBindings {
private static StringBinding asString(final ObservableValue<OfferModel> offer, final Observable... dependencies){
return Bindings.createStringBinding(() -> {
OfferModel o = offer.getValue();
return o != null ? o.toVString() : "";
return o != null ? o.toPString() : "";
}, dependencies);
}
@@ -110,7 +110,7 @@ public class ModelBindings {
public javafx.collections.ObservableList<?> getDependencies() {
if (deep){
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
return new ImmutableObservableList<Observable>(offer, offer.getValue().priceProperty());
@@ -120,7 +120,7 @@ public class ModelBindings {
if (model == null) return;
super.bind(model.priceProperty());
if (deep){
super.bind(model.getVendor().nameProperty());
super.bind(model.getSystem().nameProperty());
super.bind(model.getItem().nameProperty());
}
}
@@ -129,7 +129,7 @@ public class ModelBindings {
if (model == null) return;
super.unbind(model.priceProperty());
if (deep){
super.unbind(model.getVendor().nameProperty());
super.unbind(model.getSystem().nameProperty());
super.unbind(model.getItem().nameProperty());
}
}
@@ -170,16 +170,16 @@ public class ModelBindings {
}
public static ObservableValue<VendorModel> vendorName(final ObservableValue<VendorModel> vendor){
if ((vendor == null)) {
public static ObservableValue<SystemModel> systemName(final ObservableValue<SystemModel> system){
if ((system == null)) {
throw new NullPointerException("Operands cannot be null.");
}
return new ObjectBinding<VendorModel>() {
return new ObjectBinding<SystemModel>() {
{
super.bind(vendor);
super.bind(vendor.getValue().nameProperty());
vendor.addListener((observable, oldValue, newValue) -> {
super.bind(system);
super.bind(system.getValue().nameProperty());
system.addListener((observable, oldValue, newValue) -> {
super.unbind(oldValue.nameProperty());
super.bind(newValue.nameProperty());
});
@@ -187,18 +187,18 @@ public class ModelBindings {
@Override
public void dispose() {
super.unbind(vendor.getValue().nameProperty());
super.unbind(vendor);
super.unbind(system.getValue().nameProperty());
super.unbind(system);
}
@Override
protected VendorModel computeValue() {
return vendor.getValue();
protected SystemModel computeValue() {
return system.getValue();
}
@Override
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 ru.trader.controllers.MainController;
import ru.trader.core.OFFER_TYPE;
import ru.trader.model.ItemModel;
import ru.trader.model.MarketModel;
import ru.trader.model.OfferModel;
import ru.trader.model.VendorModel;
import ru.trader.model.*;
public class VendorUpdater {
private final static Logger LOG = LoggerFactory.getLogger(VendorUpdater.class);
public class StationUpdater {
private final static Logger LOG = LoggerFactory.getLogger(StationUpdater.class);
private final ObservableList<FakeOffer> offers;
private final StringProperty name;
private final DoubleProperty x;
private final DoubleProperty y;
private final DoubleProperty z;
private final MarketModel market;
private VendorModel vendor;
private SystemModel system;
private StationModel station;
private boolean updateOnly;
public VendorUpdater(MarketModel market) {
public StationUpdater(MarketModel 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.x = new SimpleDoubleProperty(0);
this.y = new SimpleDoubleProperty(0);
@@ -33,16 +31,17 @@ public class VendorUpdater {
this.updateOnly = false;
}
public void init(VendorModel vendor){
LOG.debug("Init update of {}", vendor);
this.vendor = vendor;
if (vendor != null){
name.setValue(vendor.getName());
x.setValue(vendor.getX());
y.setValue(vendor.getY());
z.setValue(vendor.getZ());
vendor.getSells().forEach(this::fillOffer);
vendor.getBuys().forEach(this::fillOffer);
public void init(SystemModel system, StationModel station){
LOG.debug("Init update of {}", station);
this.station = station;
this.system = system;
if (station != null){
name.setValue(station.getName());
x.setValue(system.getX());
y.setValue(system.getY());
z.setValue(system.getZ());
station.getSells().forEach(this::fillOffer);
station.getBuys().forEach(this::fillOffer);
} else {
name.setValue("");
x.setValue(0);
@@ -53,7 +52,7 @@ public class VendorUpdater {
private void fillOffer(OfferModel offer) {
for (FakeOffer o : offers) {
if (offer.hasItem(o.item)) {
if (offer.getItem().equals(o.item)) {
switch (offer.getType()) {
case SELL:
o.setSell(offer);
@@ -71,8 +70,8 @@ public class VendorUpdater {
return offers;
}
public VendorModel getVendor() {
return vendor;
public StationModel getStation() {
return station;
}
public String getName() {
@@ -112,28 +111,29 @@ public class VendorUpdater {
}
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()) {
market.setAlert(false);
vendor = market.newVendor(name.get());
vendor.setPosition(x.get(), y.get(), z.get());
Notificator notificator = market.getNotificator();
notificator.setAlert(false);
station = system.add(name.get());
offers.forEach(FakeOffer::commit);
market.setAlert(true);
market.add(vendor);
notificator.setAlert(true);
notificator.sendAdd(station);
} else {
vendor.setName(name.get());
vendor.setPosition(x.get(), y.get(), z.get());
station.setName(name.get());
offers.forEach(FakeOffer::commit);
}
}
public void reset(){
offers.forEach(FakeOffer::reset);
vendor = null;
station = null;
system = null;
}
public boolean isNew() {
return vendor == null;
return station == null;
}
public void setUpdateOnly(boolean updateOnly) {
@@ -146,15 +146,19 @@ public class VendorUpdater {
public class FakeOffer {
private final ItemModel item;
private DoubleProperty sprice;
private DoubleProperty bprice;
private final DoubleProperty sprice;
private final LongProperty supply;
private final DoubleProperty bprice;
private final LongProperty demand;
private OfferModel sell;
private OfferModel buy;
public FakeOffer(ItemModel item){
this.item = item;
this.sprice = new SimpleDoubleProperty(0);
this.supply = new SimpleLongProperty(0);
this.bprice = new SimpleDoubleProperty(0);
this.demand = new SimpleLongProperty(0);
}
public ReadOnlyStringProperty nameProperty(){
@@ -169,6 +173,22 @@ public class VendorUpdater {
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() {
return bprice.get();
}
@@ -181,19 +201,26 @@ public class VendorUpdater {
return bprice;
}
public DoubleProperty spriceProperty() {
return sprice;
public long getDemand() {
return demand.get();
}
public LongProperty demandProperty() {
return demand;
}
public void setDemand(long demand) {
this.demand.set(demand);
}
public boolean isChangeSell() {
return sell!=null && getSprice() != sell.getPrice();
return sell!=null && (getSprice() != sell.getPrice() || getSupply() != sell.getCount());
}
public boolean isChangeBuy() {
return buy!=null && getBprice() != buy.getPrice();
return buy!=null && (getBprice() != buy.getPrice() || getDemand() != buy.getCount());
}
public boolean isNewSell() {
return sell == null && getSprice() != 0;
}
@@ -226,10 +253,18 @@ public class VendorUpdater {
return sell != null ? sell.getPrice() : 0;
}
public double getOldSupply(){
return sell != null ? sell.getCount() : 0;
}
public double getOldBprice() {
return buy != null ? buy.getPrice() : 0;
}
public double getOldDemand(){
return buy != null ? buy.getCount() : 0;
}
public void setSell(OfferModel sell) {
this.sell = sell;
sprice.set(sell.getPrice());
@@ -244,13 +279,18 @@ public class VendorUpdater {
if (sell != null){
sell = null;
sprice.setValue(Double.NaN);
supply.setValue(Double.NaN);
}
if (buy != null){
buy = null;
bprice.setValue(Double.NaN);
demand.setValue(Double.NaN);
}
//for fire change event
sprice.setValue(0);
supply.setValue(0);
bprice.setValue(0);
demand.setValue(0);
}
private void commit(){
@@ -265,18 +305,19 @@ public class VendorUpdater {
if (updateOnly) {
LOG.trace("Is update only, skip");
} else {
vendor.add(market.newOffer(OFFER_TYPE.BUY, item, getBprice()));
station.add(OFFER_TYPE.BUY, item, getBprice(), getDemand());
}
} else if (isRemoveBuy()) {
LOG.trace("Is remove buy offer");
if (updateOnly) {
LOG.trace("Is update only, skip");
} else {
vendor.remove(buy);
station.remove(buy);
}
} else if (isChangeBuy()){
LOG.trace("Is change buy price to {}", getBprice());
LOG.trace("Is change buy offer to {} ({})", getBprice(), getDemand());
buy.setPrice(getBprice());
buy.setCount(getDemand());
} else {
LOG.trace("No change buy offer");
}
@@ -286,18 +327,19 @@ public class VendorUpdater {
if (updateOnly) {
LOG.trace("Is update only, skip");
} else {
vendor.add(market.newOffer(OFFER_TYPE.SELL, item, getSprice()));
station.add(OFFER_TYPE.SELL, item, getSprice(), getSupply());
}
} else if (isRemoveSell()) {
LOG.trace("Is remove sell offer");
if (updateOnly) {
LOG.trace("Is update only, skip");
} else {
vendor.remove(sell);
station.remove(sell);
}
} else if (isChangeSell()){
LOG.trace("Is change sell price to {}", getSprice());
LOG.trace("Is change sell offer to {}({})", getSprice(), getSupply());
sell.setPrice(getSprice());
sell.setCount(getSupply());
} else {
LOG.trace("No change sell offer");
}
@@ -309,7 +351,9 @@ public class VendorUpdater {
return "FakeOffer{" +
"item=" + item +
", sprice=" + sprice.get() +
", supply=" + supply.get() +
", bprice=" + bprice.get() +
", demand=" + demand.get() +
", sell=" + sell +
", buy=" + buy +
'}';

View File

@@ -19,6 +19,6 @@ public class GlyphBuilder implements Builder<Glyph> {
@Override
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.VBox;
import javafx.scene.text.Text;
import org.controlsfx.glyphfont.GlyphFontRegistry;
import org.controlsfx.glyphfont.Glyph;
import ru.trader.core.Order;
import ru.trader.graph.PathRoute;
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_TRACK = "path-track";
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 HBox node = new HBox();
@@ -33,7 +33,7 @@ public class RouteNode {
VBox.setVgrow(track, Priority.ALWAYS);
VBox.setVgrow(icons, Priority.ALWAYS);
v.getStyleClass().add(CSS_VENDOR);
v.getStyleClass().add(CSS_SYSTEM);
icons.getStyleClass().add(CSS_ICONS);
track.getStyleClass().add(CSS_TRACK);
@@ -42,12 +42,13 @@ public class RouteNode {
v.getChildren().add(new Text(p.get().getName()));
Order cargo = null;
while (p.hasNext()){
//TODO: fix icons
p = p.getNext();
if (cargo == null && p.getBest() != null){
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);
@@ -55,7 +56,7 @@ public class RouteNode {
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);
@@ -65,7 +66,7 @@ public class RouteNode {
VBox.setVgrow(track, Priority.ALWAYS);
VBox.setVgrow(icons, Priority.ALWAYS);
v.getStyleClass().add(CSS_VENDOR);
v.getStyleClass().add(CSS_SYSTEM);
icons.getStyleClass().add(CSS_ICONS);
track.getStyleClass().add(CSS_TRACK);
@@ -74,7 +75,7 @@ public class RouteNode {
if (cargo != null && cargo.isBuyer(p.get())){
v.getChildren().add(new Text(String.format(" (%+.0f) ", cargo.getProfit())));
cargo = null;
icons.getChildren().add(GlyphFontRegistry.glyph("FontAwesome|DOWNLOAD_ALT"));
icons.getChildren().add(Glyph.create("FontAwesome|DOWNLOAD_ALT"));
}
}
node.getChildren().addAll(v, icons);

View File

@@ -10,10 +10,9 @@ import javafx.scene.text.Text;
import javafx.util.Callback;
import javafx.util.StringConverter;
import org.controlsfx.glyphfont.Glyph;
import org.controlsfx.glyphfont.GlyphFontRegistry;
import ru.trader.model.support.VendorUpdater;
import ru.trader.model.support.StationUpdater;
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_ADD = "add";
private final static String CSS_REMOVE = "remove";
@@ -25,13 +24,13 @@ public class EditOfferCell extends TextFieldCell<VendorUpdater.FakeOffer, Double
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);
}
@Override
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();
getStyleClass().removeAll(CSS_ADD, CSS_CHANGE, CSS_REMOVE);
if (d !=0 ){
@@ -48,7 +47,7 @@ public class EditOfferCell extends TextFieldCell<VendorUpdater.FakeOffer, Double
Text diff = new Text(String.format(" (%+.0f)", d));
hBox.getChildren().add(diff);
}
Glyph glyph = (Glyph) GlyphFontRegistry.glyph("FontAwesome|REMOVE");
Glyph glyph = Glyph.create("FontAwesome|REMOVE");
glyph.addEventFilter(MouseEvent.MOUSE_CLICKED, (e) -> {
Platform.runLater(() -> {
if (isSell) {

View File

@@ -4,39 +4,38 @@ import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.util.Callback;
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_GOOD = "good";
private final static String CSS_DIFF = "diff";
@Override
public TableCell<OfferDescModel, Double> call(TableColumn<OfferDescModel, Double> param) {
public TableCell<OfferModel, Double> call(TableColumn<OfferModel, Double> param) {
return new PriceCell();
}
private class PriceCell extends EditingCell<OfferDescModel, Double> {
private class PriceCell extends EditingCell<OfferModel, Double> {
protected PriceCell() {
super(new DoubleStringConverter());
}
@Override
protected void outText() {
OfferDescModel offerDesc = (OfferDescModel) getTableRow().getItem();
if (offerDesc!=null){
double d = offerDesc.getDiff();
OfferModel offer = (OfferModel) getTableRow().getItem();
if (offer!=null){
double d = offer.getDiff();
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));
diff.getStyleClass().add(CSS_DIFF);
txt.getChildren().addAll(price, diff);
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.setText(null);
this.setGraphic(txt);

View File

@@ -1,14 +1,17 @@
# Market
market.vendors=Stations
market.systems=Systems
market.stations=Stations
market.items=Commods
market.offers=Offers
market.item.name=Commodity
market.vendor.name=Station
market.station.name=Station
# Offer
market.offer.buy=Buy
market.offer.sell=Sell
market.offer.price=Price
market.offer.supply=Supply
market.offer.demand=Demand
market.offer.min=Min
market.offer.avg=Avg
market.offer.max=Max
@@ -42,9 +45,13 @@ main.menu.file=File
main.menu.file.save=Save
main.menu.file.import=Import...
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.addItem=Add Commodity
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.language=Language
main.menu.settings.language.item=English

View File

@@ -1,14 +1,17 @@
# 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.offers=\u0417\u0430\u043A\u0430\u0437\u044B
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
market.offer.buy=\u041F\u043E\u043A\u0443\u043F\u043A\u0430
market.offer.sell=\u041F\u0440\u043E\u0434\u0430\u0436\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.avg=\u0421\u0440.
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.import=\u0418\u043C\u043F\u043E\u0440\u0442...
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.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.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.language=\u042F\u0437\u044B\u043A
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"/>
</Menu>
<Menu text="%main.menu.edit">
<MenuItem text="%main.menu.edit.addStation" onAction="#addVendor"/>
<MenuItem text="%main.menu.edit.editStation" onAction="#editVendor"/>
<MenuItem text="%main.menu.edit.addSystem" onAction="#addSystem"/>
<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 text="%main.menu.settings">
<MenuItem text="%main.menu.settings.parameters" onAction="#editSettings"/>
@@ -28,7 +32,7 @@
<Tab text="%market.items">
<fx:include fx:id="items" source="items.fxml"/>
</Tab>
<Tab text="%market.vendors">
<Tab text="%market.systems">
<fx:include fx:id="offers" source="offers.fxml"/>
</Tab>
<Tab text="%routes">

View File

@@ -9,24 +9,38 @@
<?import ru.trader.view.support.cells.OfferCellValueImpl?>
<?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">
<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>
<items>
<MenuItem text="%main.menu.edit.addStation" onAction="#addVendor" />
<MenuItem text="%main.menu.edit.editStation" onAction="#editVendor" />
<MenuItem text="%main.menu.edit.addStation" onAction="#addStation" />
<MenuItem text="%main.menu.edit.editStation" onAction="#editStation" />
</items>
</ContextMenu>
</contextMenu>
</ListView>
</TitledPane>
<Accordion HBox.hgrow="ALWAYS">
<panes>
<TitledPane fx:id="sells" animated="false" text="%offers.pane.sell">
<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>
<TitledPane fx:id="paneSells" animated="false" text="%offers.pane.sell">
<TableView fx:id="tblSell" editable="true">
<columns>
<TableColumn minWidth="230.0" text="%market.item.name">
@@ -36,6 +50,9 @@
<cellFactory><PriceCellImpl/></cellFactory>
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
</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">
<cellFactory><DoubleCell/></cellFactory>
<cellValueFactory><PropertyValueFactory property="profit"/></cellValueFactory>
@@ -70,8 +87,8 @@
<fx:reference source="sortSell"/>
</sortOrder>
</TableView>
</TitledPane>
<TitledPane animated="false" text="%offers.pane.buy">
</TitledPane>
<TitledPane animated="false" text="%offers.pane.buy">
<TableView fx:id="tblBuy" editable="true">
<columns>
<TableColumn minWidth="230.0" text="%market.item.name">
@@ -81,6 +98,9 @@
<cellFactory><PriceCellImpl/></cellFactory>
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
</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">
<cellFactory><DoubleCell/></cellFactory>
<cellValueFactory><PropertyValueFactory property="profit"/></cellValueFactory>
@@ -115,10 +135,10 @@
<fx:reference source="sortBuy"/>
</sortOrder>
</TableView>
</TitledPane>
</panes>
<expandedPane>
<fx:reference source="sells"/>
</expandedPane>
</TitledPane>
</panes>
<expandedPane>
<fx:reference source="paneSells"/>
</expandedPane>
</Accordion>
</HBox>
</GridPane>

View File

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

View File

@@ -15,7 +15,7 @@
</columnConstraints>
<Label text="%settings.emdn" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2"/>
<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" />
<TextField fx:id="emdnSubServ" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="%settings.emdn.updateOnly" GridPane.rowIndex="3" />

View File

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

View File

@@ -10,7 +10,7 @@
<?import ru.trader.view.support.NumberField?>
<?import javafx.geometry.Insets?>
<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">
<fx:define><Insets fx:id="hbox_margin" left="10" /></fx:define>
<TextField fx:id="name" GridPane.columnSpan="2" alignment="CENTER" />