add paths layout
This commit is contained in:
@@ -67,6 +67,7 @@ public class Main extends Application {
|
||||
Screeners.loadAddOfferStage(getUrl(("oEditor.fxml")));
|
||||
Screeners.loadOrdersStage(getUrl(("orders.fxml")));
|
||||
Screeners.loadTopOrdersStage(getUrl(("topOrders.fxml")));
|
||||
Screeners.loadPathsStage(getUrl(("paths.fxml")));
|
||||
}
|
||||
|
||||
private static URL getUrl(String filename) throws MalformedURLException {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
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;
|
||||
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.graph.PathRoute;
|
||||
import ru.trader.model.OrderModel;
|
||||
import ru.trader.model.PathRouteModel;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
@FXML
|
||||
private TableView<PathRouteModel> tblPaths;
|
||||
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void showDialog(Parent parent, Parent content, Collection<PathRouteModel> paths) {
|
||||
|
||||
init(paths);
|
||||
|
||||
Dialog dlg = new Dialog(parent, String.format("Доступные маршруты"));
|
||||
dlg.setContent(content);
|
||||
dlg.getActions().addAll(OK, Dialog.Actions.CANCEL);
|
||||
dlg.setResizable(false);
|
||||
dlg.show();
|
||||
}
|
||||
|
||||
|
||||
private void init(Collection<PathRouteModel> paths) {
|
||||
tblPaths.getSelectionModel().clearSelection();
|
||||
tblPaths.setItems(FXCollections.observableArrayList(paths));
|
||||
if (tblPaths.getSortOrder().size()>0)
|
||||
tblPaths.sort();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,15 +21,22 @@ public class RoutersController {
|
||||
|
||||
@FXML
|
||||
private NumberField balance;
|
||||
|
||||
@FXML
|
||||
private NumberField cargo;
|
||||
@FXML
|
||||
private NumberField distance;
|
||||
@FXML
|
||||
private NumberField tank;
|
||||
@FXML
|
||||
private NumberField jumps;
|
||||
|
||||
@FXML
|
||||
private Button add;
|
||||
|
||||
@FXML
|
||||
private ComboBox<VendorModel> vendors;
|
||||
private ComboBox<VendorModel> source;
|
||||
@FXML
|
||||
private ComboBox<VendorModel> target;
|
||||
|
||||
@FXML
|
||||
private TableView<OrderModel> tblOrders;
|
||||
@@ -40,10 +47,23 @@ public class RoutersController {
|
||||
@FXML
|
||||
private NumberField totalBalance;
|
||||
|
||||
private MarketModel market;
|
||||
|
||||
@FXML
|
||||
private void initialize(){
|
||||
init();
|
||||
balance.numberProperty().addListener((ov, o, n) -> totalBalance.setValue(n));
|
||||
cargo.numberProperty().addListener((ov, o, n) -> market.setCargo(n.longValue()));
|
||||
tank.numberProperty().addListener((ov, o, n) -> market.setTank(n.doubleValue()));
|
||||
distance.numberProperty().addListener((ov, o, n) -> market.setDistance(n.doubleValue()));
|
||||
jumps.numberProperty().addListener((ov, o, n) -> market.setJumps(n.intValue()));
|
||||
|
||||
balance.setValue(1000);
|
||||
cargo.setValue(4);
|
||||
tank.setValue(30);
|
||||
distance.setValue(7);
|
||||
jumps.setValue(4);
|
||||
|
||||
add.disableProperty().bind(this.balance.wrongProperty().or(this.cargo.wrongProperty()));
|
||||
tblOrders.setItems(FXCollections.observableArrayList());
|
||||
tblOrders.getItems().addListener((ListChangeListener<OrderModel>) c -> {
|
||||
@@ -64,30 +84,30 @@ public class RoutersController {
|
||||
|
||||
|
||||
void init(){
|
||||
MarketModel market = MainController.getMarket();
|
||||
vendors.setItems(market.vendorsProperty());
|
||||
vendors.getSelectionModel().selectFirst();
|
||||
market = MainController.getMarket();
|
||||
source.setItems(market.vendorsProperty());
|
||||
source.getSelectionModel().selectFirst();
|
||||
target.setItems(market.vendorsProperty());
|
||||
tblOrders.getItems().clear();
|
||||
totalBalance.setValue(balance.getValue());
|
||||
totalProfit.setValue(0);
|
||||
}
|
||||
|
||||
private Collection<OfferDescModel> getOffers(){
|
||||
MarketModel market = MainController.getMarket();
|
||||
VendorModel vendor = vendors.getSelectionModel().getSelectedItem();
|
||||
VendorModel vendor = source.getSelectionModel().getSelectedItem();
|
||||
return vendor.getSells(market::asOfferDescModel);
|
||||
}
|
||||
|
||||
private void onAdd(OrderModel order){
|
||||
totalProfit.add(order.getProfit());
|
||||
totalBalance.add(order.getProfit());
|
||||
vendors.getSelectionModel().select(order.getBuyer().getVendor());
|
||||
source.getSelectionModel().select(order.getBuyer().getVendor());
|
||||
}
|
||||
|
||||
private void onRemove(OrderModel order) {
|
||||
totalProfit.sub(order.getProfit());
|
||||
totalBalance.sub(order.getProfit());
|
||||
vendors.getSelectionModel().select(order.getVendor());
|
||||
source.getSelectionModel().select(order.getVendor());
|
||||
}
|
||||
|
||||
public void addOrders(){
|
||||
@@ -113,11 +133,20 @@ public class RoutersController {
|
||||
|
||||
|
||||
public void showTopOrders(){
|
||||
MarketModel market = MainController.getMarket();
|
||||
OrderModel order = Screeners.showTopOrders(market.getTop(100, totalBalance.getValue().doubleValue(), cargo.getValue().longValue()));
|
||||
OrderModel order = Screeners.showTopOrders(market.getTop(100, totalBalance.getValue().doubleValue()));
|
||||
if (order!=null){
|
||||
tblOrders.getItems().add(order);
|
||||
}
|
||||
}
|
||||
|
||||
public void showRoutes(){
|
||||
VendorModel s = source.getSelectionModel().getSelectedItem();
|
||||
VendorModel t = target.getSelectionModel().getSelectedItem();
|
||||
if (t==null) return;
|
||||
|
||||
MarketModel market = MainController.getMarket();
|
||||
Screeners.showRouters(market.getRouters(s, t, totalBalance.getValue().doubleValue()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public class Screeners {
|
||||
private static Parent editOffersScreen;
|
||||
private static Parent ordersScreen;
|
||||
private static Parent topOrdersScreen;
|
||||
private static Parent pathsScreen;
|
||||
|
||||
private static MainController mainController;
|
||||
private static ItemDescController itemDescController;
|
||||
@@ -31,6 +32,7 @@ public class Screeners {
|
||||
private static OffersEditorController oEditorController;
|
||||
private static OrdersController ordersController;
|
||||
private static TopOrdersController topOrdersController;
|
||||
private static PathsController pathsController;
|
||||
|
||||
private static FXMLLoader initLoader(URL url){
|
||||
FXMLLoader loader = new FXMLLoader(url);
|
||||
@@ -94,6 +96,15 @@ public class Screeners {
|
||||
stage.setScene(new Scene(topOrdersScreen));
|
||||
}
|
||||
|
||||
public static void loadPathsStage(URL fxml) throws IOException {
|
||||
FXMLLoader loader = initLoader(fxml);
|
||||
pathsScreen = loader.load();
|
||||
addStylesheet(pathsScreen);
|
||||
pathsController = loader.getController();
|
||||
Stage stage = new Stage();
|
||||
stage.setScene(new Scene(pathsScreen));
|
||||
}
|
||||
|
||||
public static void show(Node node){
|
||||
mainController.getMainPane().setCenter(node);
|
||||
}
|
||||
@@ -148,4 +159,8 @@ public class Screeners {
|
||||
public static OrderModel showTopOrders(ObservableList<OrderModel> top) {
|
||||
return topOrdersController.showDialog(mainScreen, topOrdersScreen, top);
|
||||
}
|
||||
|
||||
public static void showRouters(ObservableList<PathRouteModel> routers) {
|
||||
pathsController.showDialog(mainScreen, pathsScreen, routers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,13 +169,32 @@ public class MarketModel {
|
||||
return ModelFabrica.getModel(vendor, this);
|
||||
}
|
||||
|
||||
public ObservableList<OrderModel> getTop(int limit, double balance, long max){
|
||||
return BindingsHelper.observableList(analyzer.getTop(limit, balance, max), (o) -> {
|
||||
OrderModel model = new OrderModel(asOfferDescModel(o.getSell()), balance, max);
|
||||
public ObservableList<OrderModel> getTop(int limit, double balance){
|
||||
return BindingsHelper.observableList(analyzer.getTop(limit, balance), (o) -> {
|
||||
OrderModel model = new OrderModel(asOfferDescModel(o.getSell()), balance, analyzer.getCargo());
|
||||
model.setBuyer(asModel(o.getBuy()));
|
||||
model.setCount(model.getMax());
|
||||
return model;
|
||||
});
|
||||
}
|
||||
|
||||
public void setCargo(long 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<PathRouteModel> getRouters(VendorModel from, VendorModel to, double balance){
|
||||
return BindingsHelper.observableList(analyzer.getPaths(from.getVendor(), to.getVendor(), balance), PathRouteModel::new);
|
||||
}
|
||||
}
|
||||
|
||||
50
client/src/main/java/ru/trader/model/PathRouteModel.java
Normal file
50
client/src/main/java/ru/trader/model/PathRouteModel.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package ru.trader.model;
|
||||
|
||||
import ru.trader.core.Vendor;
|
||||
import ru.trader.graph.PathRoute;
|
||||
|
||||
public class PathRouteModel {
|
||||
private final double distance;
|
||||
private final double totalProfit;
|
||||
private final int jumps;
|
||||
private final int refuels;
|
||||
|
||||
private final PathRoute path;
|
||||
|
||||
public PathRouteModel(PathRoute path) {
|
||||
this.path = path;
|
||||
PathRoute p = path.getRoot();
|
||||
double pr =0, d = 0; int j = 0, r = 0;
|
||||
while (p.hasNext()){
|
||||
p = p.getNext();
|
||||
d += path.getDistance();
|
||||
pr += p.getMaxProfit();
|
||||
j++;
|
||||
if (p.isRefill()) r++;
|
||||
}
|
||||
totalProfit = pr;
|
||||
distance = d;
|
||||
jumps = j;
|
||||
refuels = r;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public double getTotalProfit() {
|
||||
return totalProfit;
|
||||
}
|
||||
|
||||
public int getJumps() {
|
||||
return jumps;
|
||||
}
|
||||
|
||||
public int getRefuels() {
|
||||
return refuels;
|
||||
}
|
||||
|
||||
public PathRoute getPath() {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package ru.trader.view.support.cells;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Callback;
|
||||
import org.controlsfx.glyphfont.GlyphFontRegistry;
|
||||
import ru.trader.core.Order;
|
||||
import ru.trader.graph.PathRoute;
|
||||
import ru.trader.model.PathRouteModel;
|
||||
|
||||
public class PathRouteCell<T> implements Callback<TableColumn<PathRouteModel, T>, TableCell<PathRouteModel, T>> {
|
||||
@Override
|
||||
public TableCell<PathRouteModel, T> call(TableColumn<PathRouteModel, T> param) {
|
||||
return new TableCell<PathRouteModel, T>(){
|
||||
@Override
|
||||
public void updateItem(T value, boolean empty) {
|
||||
super.updateItem(value, empty);
|
||||
if (!empty){
|
||||
PathRoute p = ((PathRouteModel) getTableRow().getItem()).getPath().getRoot();
|
||||
HBox hBox = new HBox();
|
||||
|
||||
HBox v = new HBox();
|
||||
v.setAlignment(Pos.BOTTOM_CENTER);
|
||||
v.getChildren().add(new Text(p.get().getName()));
|
||||
while (p.hasNext()){
|
||||
p = p.getNext();
|
||||
if (p.isRefill()) v.getChildren().add(GlyphFontRegistry.glyph("FontAwesome|REFRESH"));
|
||||
hBox.getChildren().add(v);
|
||||
|
||||
VBox dist = new VBox(new Text(String.format("(%+.0f LY)", p.getDistance())));
|
||||
dist.setAlignment(Pos.BASELINE_CENTER);
|
||||
dist.getChildren().add(GlyphFontRegistry.glyph("FontAwesome|LONG_ARROW_RIGHT"));
|
||||
hBox.getChildren().addAll(dist);
|
||||
|
||||
v = new HBox();
|
||||
v.setAlignment(Pos.BOTTOM_CENTER);
|
||||
v.getChildren().add(new Text(p.get().getName()));
|
||||
v.getChildren().add(new Text(String.format(" (%+.0f) ", p.getMaxProfit())));
|
||||
}
|
||||
hBox.getChildren().add(v);
|
||||
setText(null);
|
||||
setGraphic(hBox);
|
||||
} else {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
<cellFactory><DoubleCell/></cellFactory>
|
||||
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="count" minWidth="60.0" text="Кол-во">
|
||||
<TableColumn fx:id="count" minWidth="60.0" prefWidth="60.0" text="Кол-во">
|
||||
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="160.0" text="Покупатель">
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<TableColumn resizable="false" text="Максимум">
|
||||
<columns>
|
||||
<TableColumn fx:id="maxCount" minWidth="60.0" text="Кол-во">
|
||||
<TableColumn fx:id="maxCount" minWidth="60.0" prefWidth="60.0" text="Кол-во">
|
||||
<cellValueFactory><PropertyValueFactory property="max"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="bestProfit" minWidth="80.0" text="Прибыль" sortType="DESCENDING">
|
||||
|
||||
45
client/src/main/resources/view/paths.fxml
Normal file
45
client/src/main/resources/view/paths.fxml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.cell.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
|
||||
|
||||
<?import ru.trader.view.support.cells.DoubleCell?>
|
||||
|
||||
<?import ru.trader.view.support.cells.OfferCellValueImpl?>
|
||||
<?import ru.trader.view.support.cells.OfferTableCell?>
|
||||
<?import ru.trader.view.support.cells.PathRouteCell?>
|
||||
<HBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="ru.trader.controllers.PathsController" styleClass="dialog"
|
||||
prefWidth="900">
|
||||
<TableView fx:id="tblPaths" editable="true">
|
||||
<columns>
|
||||
<TableColumn minWidth="640.0" text="Путь">
|
||||
<cellFactory><PathRouteCell /></cellFactory>
|
||||
</TableColumn>
|
||||
|
||||
<TableColumn minWidth="60.0" text="Заправок">
|
||||
<cellValueFactory><PropertyValueFactory property="refuels"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
|
||||
<TableColumn minWidth="60.0" text="Прыжков">
|
||||
<cellValueFactory><PropertyValueFactory property="jumps"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
|
||||
<TableColumn minWidth="60.0" text="Дистанция">
|
||||
<cellFactory><DoubleCell format="\%.2f LY"/></cellFactory>
|
||||
<cellValueFactory><PropertyValueFactory property="distance"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="profit" minWidth="80.0" text="Прибыль" sortType="DESCENDING">
|
||||
<cellValueFactory><PropertyValueFactory property="totalProfit"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="UNCONSTRAINED_RESIZE_POLICY"/>
|
||||
</columnResizePolicy>
|
||||
<sortOrder>
|
||||
<fx:reference source="profit"/>
|
||||
</sortOrder>
|
||||
</TableView>
|
||||
</HBox>
|
||||
@@ -12,21 +12,38 @@
|
||||
<HBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="ru.trader.controllers.RoutersController">
|
||||
<fx:define><Insets fx:id="fields_group_margin" left="2" right="10"/></fx:define>
|
||||
<fx:define><Insets fx:id="separator_margin" top="20" bottom="20"/></fx:define>
|
||||
<fx:define><Insets fx:id="separator_margin" top="10" bottom="10"/></fx:define>
|
||||
|
||||
<VBox minWidth="260">
|
||||
<TitledPane text="Параметры" minHeight="400" collapsible="false">
|
||||
<VBox minWidth="250">
|
||||
<TitledPane text="Параметры корабля" minHeight="160" collapsible="false">
|
||||
<GridPane vgap="4">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints minWidth="140" />
|
||||
<ColumnConstraints minWidth="90" maxWidth="90"/>
|
||||
</columnConstraints>
|
||||
<Label text="Баланс:"/>
|
||||
<NumberField fx:id="balance" value="1000" GridPane.columnIndex="1" />
|
||||
<Label text="Трюм:" GridPane.rowIndex="1" />
|
||||
<NumberField fx:id="cargo" value="4" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<Label text="Запас топлива(LY):" GridPane.rowIndex="2" />
|
||||
<NumberField fx:id="tank" value="30" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
<Label text="Дистанция прыжка(LY):" GridPane.rowIndex="3" />
|
||||
<NumberField fx:id="distance" value="7" GridPane.columnIndex="1" GridPane.rowIndex="3" />
|
||||
</GridPane>
|
||||
</TitledPane>
|
||||
<TitledPane text="Параметры маршрута" minHeight="250" collapsible="false">
|
||||
<GridPane vgap="4">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints minWidth="70"/>
|
||||
<ColumnConstraints minWidth="160"/>
|
||||
<ColumnConstraints minWidth="160" maxWidth="160"/>
|
||||
</columnConstraints>
|
||||
<Label text="Баланс:"/>
|
||||
<NumberField fx:id="balance" prefWidth="100" value="1000" GridPane.columnIndex="1" />
|
||||
<Label text="Трюм:" GridPane.rowIndex="1" />
|
||||
<NumberField fx:id="cargo" prefWidth="50" value="4" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<Label text="Станция:" GridPane.rowIndex="2"/>
|
||||
<ComboBox fx:id="vendors" prefWidth="160" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
|
||||
<Label text="От:" />
|
||||
<ComboBox fx:id="source" prefWidth="160" GridPane.columnIndex="1" />
|
||||
<Label text="До:" GridPane.rowIndex="1"/>
|
||||
<ComboBox fx:id="target" prefWidth="160" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||
<Label text="Прыжков:" GridPane.rowIndex="2" />
|
||||
<NumberField fx:id="jumps" value="4" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
|
||||
<Separator GridPane.columnSpan="2" GridPane.rowIndex="3" GridPane.margin="$separator_margin"/>
|
||||
<VBox GridPane.columnSpan="2" GridPane.rowIndex="4" spacing="20">
|
||||
<HBox alignment="CENTER" spacing="5">
|
||||
@@ -36,6 +53,7 @@
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" spacing="5">
|
||||
<Button text="TOP 100" onAction="#showTopOrders" />
|
||||
<Button text="Маршруты" onAction="#showRoutes" />
|
||||
</HBox>
|
||||
</VBox>
|
||||
</GridPane>
|
||||
@@ -56,7 +74,7 @@
|
||||
</VBox>
|
||||
<TableView fx:id="tblOrders" HBox.hgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn minWidth="200.0" text="Продавец">
|
||||
<TableColumn minWidth="210.0" text="Продавец">
|
||||
<cellValueFactory><PropertyValueFactory property="vendor"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="180.0" text="Товар">
|
||||
|
||||
Reference in New Issue
Block a user