mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-20 13:54:32 +01:00
Orderbook, Mainview, refactorings
This commit is contained in:
parent
870cd062f5
commit
c30646a11c
72 changed files with 1995 additions and 1088 deletions
|
@ -27,7 +27,7 @@ import io.bitsquare.msg.MessageFacade;
|
|||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
|
@ -105,16 +105,16 @@ public class BitSquare extends Application {
|
|||
|
||||
User persistedUser = (User) persistence.read(user);
|
||||
user.applyPersistedUser(persistedUser);
|
||||
persistence.write(user);
|
||||
//persistence.write(user);
|
||||
|
||||
settings.applyPersistedSettings((Settings) persistence.read(settings.getClass().getName()));
|
||||
|
||||
primaryStage.setTitle("BitSquare (" + APP_NAME + ")");
|
||||
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
final BSFXMLLoader loader =
|
||||
new BSFXMLLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()), false);
|
||||
final ViewLoader loader =
|
||||
new ViewLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()), false);
|
||||
try {
|
||||
final Parent view = loader.load();
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@ public class BitSquareModule extends AbstractModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(User.class).asEagerSingleton();
|
||||
bind(OrderBook.class).asEagerSingleton();
|
||||
bind(Persistence.class).asEagerSingleton();
|
||||
bind(Settings.class).asEagerSingleton();
|
||||
|
||||
|
@ -71,6 +70,7 @@ public class BitSquareModule extends AbstractModule {
|
|||
bind(BootstrappedPeerFactory.class).asEagerSingleton();
|
||||
|
||||
bind(TradeManager.class).asEagerSingleton();
|
||||
bind(OrderBook.class).asEagerSingleton();
|
||||
bind(NavigationController.class).asEagerSingleton();
|
||||
bind(OverlayController.class).asEagerSingleton();
|
||||
bind(BSFormatter.class).asEagerSingleton();
|
||||
|
@ -81,7 +81,6 @@ public class BitSquareModule extends AbstractModule {
|
|||
bind(InputValidator.class).asEagerSingleton();
|
||||
bind(PasswordValidator.class).asEagerSingleton();
|
||||
|
||||
|
||||
//bind(String.class).annotatedWith(Names.named("networkType")).toInstance(WalletFacade.MAIN_NET);
|
||||
// how to use reg test see description in the readme file
|
||||
bind(String.class).annotatedWith(Names.named("networkType")).toInstance(WalletFacade.REG_TEST_NET);
|
||||
|
|
|
@ -19,6 +19,10 @@ public class CachedViewCB<T extends PresentationModel> extends ViewCB<T> {
|
|||
super(presentationModel);
|
||||
}
|
||||
|
||||
public CachedViewCB() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get called form GUI framework when the UI is ready.
|
||||
* In caching controllers the initialize is only used for static UI setup.
|
||||
|
@ -36,8 +40,11 @@ public class CachedViewCB<T extends PresentationModel> extends ViewCB<T> {
|
|||
// lets terminate
|
||||
log.trace("Lifecycle: sceneProperty changed: " + this.getClass().getSimpleName() + " / oldValue=" +
|
||||
oldValue + " / newValue=" + newValue);
|
||||
if (oldValue == null && newValue != null) activate();
|
||||
else if (oldValue != null && newValue == null) deactivate();
|
||||
|
||||
if (oldValue == null && newValue != null)
|
||||
activate();
|
||||
else if (oldValue != null && newValue == null)
|
||||
deactivate();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -50,7 +57,8 @@ public class CachedViewCB<T extends PresentationModel> extends ViewCB<T> {
|
|||
*/
|
||||
public void activate() {
|
||||
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
|
||||
if (childController instanceof CachedViewCB) ((CachedViewCB) childController).activate();
|
||||
if (childController instanceof CachedViewCB)
|
||||
((CachedViewCB) childController).activate();
|
||||
|
||||
if (presentationModel != null)
|
||||
presentationModel.activate();
|
||||
|
@ -61,7 +69,8 @@ public class CachedViewCB<T extends PresentationModel> extends ViewCB<T> {
|
|||
*/
|
||||
public void deactivate() {
|
||||
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
|
||||
if (childController instanceof CachedViewCB) ((CachedViewCB) childController).deactivate();
|
||||
if (childController instanceof CachedViewCB)
|
||||
((CachedViewCB) childController).deactivate();
|
||||
|
||||
if (presentationModel != null)
|
||||
presentationModel.deactivate();
|
||||
|
|
22
src/main/java/io/bitsquare/gui/CloseListener.java
Normal file
22
src/main/java/io/bitsquare/gui/CloseListener.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui;
|
||||
|
||||
public interface CloseListener {
|
||||
void onClosed();
|
||||
}
|
22
src/main/java/io/bitsquare/gui/NavigationListener.java
Normal file
22
src/main/java/io/bitsquare/gui/NavigationListener.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui;
|
||||
|
||||
public interface NavigationListener {
|
||||
public void navigate(NavigationItem navigationItem);
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package io.bitsquare.gui;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PresentationModel<T extends UIModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(PresentationModel.class);
|
||||
|
||||
protected T model;
|
||||
|
||||
|
@ -13,26 +17,26 @@ public class PresentationModel<T extends UIModel> {
|
|||
}
|
||||
|
||||
public void initialize() {
|
||||
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
|
||||
if (model != null)
|
||||
model.initialize();
|
||||
|
||||
activate();
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
|
||||
if (model != null)
|
||||
model.activate();
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
|
||||
if (model != null)
|
||||
model.deactivate();
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
|
||||
if (model != null)
|
||||
model.terminate();
|
||||
|
||||
deactivate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,18 @@ public class UIModel {
|
|||
private static final Logger log = LoggerFactory.getLogger(UIModel.class);
|
||||
|
||||
public void initialize() {
|
||||
activate();
|
||||
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
deactivate();
|
||||
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ public class ViewCB<T extends PresentationModel> implements Initializable {
|
|||
this.presentationModel = presentationModel;
|
||||
}
|
||||
|
||||
// TODO Still open question if we enforce a presentationModel or not? For small UIs it might be too much overhead.
|
||||
public ViewCB() {
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,12 @@ upper gradient color on tab: d3d3d3
|
|||
lower gradient color on tab: dddddd
|
||||
*/
|
||||
|
||||
.root {
|
||||
-bs-theme-color: #0096c9;
|
||||
-bs-dark-grey: #333333;
|
||||
-bs-bg-grey: #dddddd;
|
||||
}
|
||||
|
||||
|
||||
/* Splash */
|
||||
#splash {
|
||||
|
@ -27,7 +33,7 @@ lower gradient color on tab: dddddd
|
|||
}
|
||||
|
||||
#base-content-container {
|
||||
-fx-background-color: #dddddd;
|
||||
-fx-background-color: -bs-bg-grey;
|
||||
}
|
||||
|
||||
#content-pane {
|
||||
|
@ -63,7 +69,7 @@ lower gradient color on tab: dddddd
|
|||
}
|
||||
|
||||
#nav-button:selected .text {
|
||||
-fx-font-size: 11;
|
||||
-fx-font-size: 11;
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
|
@ -103,7 +109,7 @@ lower gradient color on tab: dddddd
|
|||
}
|
||||
|
||||
.copy-icon {
|
||||
-fx-text-fill: #0096c9;
|
||||
-fx-text-fill: -bs-theme-color;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
|
@ -111,6 +117,12 @@ lower gradient color on tab: dddddd
|
|||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
-fx-background-color: white;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
|
||||
/* Same style like non editable textfield. But textfield spans a whole column in a grid, so we use generally
|
||||
textfield */
|
||||
#label-with-background {
|
||||
|
@ -121,7 +133,7 @@ textfield */
|
|||
|
||||
#address-text-field {
|
||||
-fx-cursor: hand;
|
||||
-fx-text-fill: #0096c9;
|
||||
-fx-text-fill: -bs-theme-color;
|
||||
}
|
||||
#address-text-field:hover {
|
||||
-fx-text-fill: black;
|
||||
|
@ -157,7 +169,7 @@ textfield */
|
|||
}
|
||||
|
||||
.table-view .table-row-cell .copy-icon .text {
|
||||
-fx-fill: #0096c9;
|
||||
-fx-fill: -bs-theme-color;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell .copy-icon .text:hover {
|
||||
|
@ -173,7 +185,7 @@ textfield */
|
|||
}
|
||||
|
||||
.table-view .table-row-cell .hyperlink .text {
|
||||
-fx-fill: #0096c9;
|
||||
-fx-fill: -bs-theme-color;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell .hyperlink .text:hover {
|
||||
|
@ -194,12 +206,12 @@ textfield */
|
|||
}
|
||||
|
||||
#clickable-icon {
|
||||
-fx-text-fill: #0096c9;
|
||||
-fx-text-fill: -bs-theme-color;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
#clickable-icon:hover {
|
||||
-fx-text-fill: #666;
|
||||
-fx-text-fill: #666666;
|
||||
}
|
||||
|
||||
#form-title {
|
||||
|
@ -255,13 +267,13 @@ textfield */
|
|||
-fx-background-color:
|
||||
#cfcfcf,
|
||||
linear-gradient(#cfcfcf 0%, #b5b5b5 100%),
|
||||
linear-gradient(#d3d3d3 0%, #dddddd 100%);
|
||||
linear-gradient(#d3d3d3 0%, -bs-bg-grey 100%);
|
||||
-fx-background-insets: 0 0 0 0,0,1;
|
||||
}
|
||||
|
||||
#content-pane-label {
|
||||
-fx-font-size: 14;
|
||||
-fx-text-fill: #000;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
#info-icon-label {
|
||||
-fx-font-size:16;
|
||||
|
@ -272,7 +284,7 @@ textfield */
|
|||
#direction-icon-label {
|
||||
-fx-font-weight:bold;
|
||||
-fx-font-size:16;
|
||||
-fx-text-fill: #333;
|
||||
-fx-text-fill: -bs-dark-grey;
|
||||
}
|
||||
|
||||
#input-description-label {
|
||||
|
@ -289,14 +301,14 @@ textfield */
|
|||
#currency-info-label {
|
||||
-fx-border-radius: 0 4 4 0;
|
||||
-fx-padding: 4 4 4 4;
|
||||
-fx-background-color: linear-gradient(to bottom, #eee, #ddd);
|
||||
-fx-background-color: #f6f6f6;
|
||||
-fx-border-color: #aaa;
|
||||
-fx-border-style: solid solid solid none;
|
||||
-fx-border-insets: 0 0 0 -2;
|
||||
}
|
||||
|
||||
#totals-separator {
|
||||
-fx-background: #aaa;
|
||||
-fx-background: #AAAAAA;
|
||||
}
|
||||
|
||||
#payment-info {
|
||||
|
@ -308,32 +320,32 @@ textfield */
|
|||
#wizard-title-deactivated {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 16;
|
||||
-fx-text-fill: #ccc;
|
||||
-fx-text-fill: #CCCCCC;
|
||||
}
|
||||
#wizard-title-active {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 16;
|
||||
-fx-text-fill: #000;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
#wizard-title-completed {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 16;
|
||||
-fx-text-fill: #000;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
#wizard-sub-title-deactivated {
|
||||
-fx-text-fill: #ccc;
|
||||
-fx-text-fill: #CCCCCC;
|
||||
}
|
||||
#wizard-sub-title-active {
|
||||
-fx-text-fill: #000;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
#wizard-sub-title-completed {
|
||||
-fx-text-fill: #000;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
#wizard-item-background-deactivated {
|
||||
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
|
||||
-fx-outer-border: linear-gradient(to bottom, #ddd, #ccc);
|
||||
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
|
||||
-fx-background-color: -fx-shadow-highlight-color,
|
||||
-fx-outer-border,
|
||||
-fx-inner-border,
|
||||
|
@ -369,22 +381,22 @@ textfield */
|
|||
#wizard-title-disabled {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 16;
|
||||
-fx-text-fill: #ccc;
|
||||
-fx-text-fill: #CCCCCC;
|
||||
}
|
||||
#wizard-title-active {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 16;
|
||||
-fx-text-fill: #000;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
#wizard-title-selected {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 16;
|
||||
-fx-text-fill: #0096c9;
|
||||
-fx-text-fill: -bs-theme-color;
|
||||
}
|
||||
|
||||
#account-settings-item-background-disabled {
|
||||
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
|
||||
-fx-outer-border: linear-gradient(to bottom, #ddd, #ccc);
|
||||
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
|
||||
-fx-background-color: -fx-shadow-highlight-color,
|
||||
-fx-outer-border,
|
||||
-fx-inner-border,
|
||||
|
@ -395,7 +407,7 @@ textfield */
|
|||
|
||||
#account-settings-item-background-active {
|
||||
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
|
||||
-fx-outer-border: linear-gradient(to bottom, #ddd, #ccc);
|
||||
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
|
||||
-fx-background-color: -fx-shadow-highlight-color,
|
||||
-fx-outer-border,
|
||||
-fx-inner-border,
|
||||
|
@ -420,18 +432,18 @@ textfield */
|
|||
#titled-group-bg-label {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 14;
|
||||
-fx-text-fill: #333;
|
||||
-fx-text-fill: -bs-dark-grey;
|
||||
-fx-background-color: #f4f4f4;
|
||||
}
|
||||
#titled-group-bg-label-active {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 14;
|
||||
-fx-text-fill: #0096c9;
|
||||
-fx-text-fill: -bs-theme-color;
|
||||
-fx-background-color: #f4f4f4;
|
||||
}
|
||||
#titled-group-bg {
|
||||
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
|
||||
-fx-outer-border: linear-gradient(to bottom, #ddd, #ccc);
|
||||
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
|
||||
-fx-background-color: -fx-shadow-highlight-color,
|
||||
-fx-outer-border,
|
||||
-fx-inner-border,
|
||||
|
@ -449,3 +461,26 @@ textfield */
|
|||
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
|
||||
-fx-background-radius: 3px, 3px, 2px, 1px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* TitledSeparator */
|
||||
#titled-separator-label {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 14;
|
||||
-fx-text-fill: -bs-dark-grey;
|
||||
-fx-background-color: #f4f4f4;
|
||||
}
|
||||
#titled-separator-label-active {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 14;
|
||||
-fx-text-fill: -bs-theme-color;
|
||||
-fx-background-color: #f4f4f4;
|
||||
}
|
||||
#titled-separator:horizontal .line {
|
||||
-fx-border-color: #cccccc transparent #999999 transparent;
|
||||
}
|
||||
|
||||
#titled-separator-active:horizontal .line {
|
||||
-fx-border-color: #dddddd transparent derive(-bs-theme-color, 50%) transparent;
|
||||
}
|
|
@ -19,7 +19,7 @@ package io.bitsquare.gui.components;
|
|||
|
||||
import io.bitsquare.gui.ViewController;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -96,7 +96,7 @@ public class CachingTabPane extends TabPane {
|
|||
selectedTabIndex = getSelectionModel().getSelectedIndex();
|
||||
TabInfo selectedTabInfo = tabInfoList.get(selectedTabIndex);
|
||||
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(selectedTabInfo.url));
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(selectedTabInfo.url));
|
||||
try {
|
||||
Node view = loader.load();
|
||||
selectedTabInfo.controller = loader.getController();
|
||||
|
|
|
@ -21,8 +21,10 @@ import io.bitsquare.gui.util.ImageUtil;
|
|||
import io.bitsquare.locale.BSResources;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -35,6 +37,7 @@ import javafx.scene.*;
|
|||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.text.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -51,12 +54,14 @@ public class InfoDisplay extends Parent {
|
|||
private final StringProperty text = new SimpleStringProperty();
|
||||
private final IntegerProperty rowIndex = new SimpleIntegerProperty(0);
|
||||
private final IntegerProperty columnIndex = new SimpleIntegerProperty(0);
|
||||
private final DoubleProperty prefWidth = new SimpleDoubleProperty(740);
|
||||
private final ObjectProperty<EventHandler<ActionEvent>> onAction = new SimpleObjectProperty<>();
|
||||
|
||||
private final ObjectProperty<GridPane> gridPane = new SimpleObjectProperty<>();
|
||||
|
||||
private boolean useReadMore;
|
||||
|
||||
private final ImageView icon;
|
||||
private final VBox vBox;
|
||||
private final TextFlow textFlow;
|
||||
private final Label label;
|
||||
private final Hyperlink link;
|
||||
|
||||
|
@ -70,34 +75,58 @@ public class InfoDisplay extends Parent {
|
|||
icon = ImageUtil.getIconImageView(ImageUtil.INFO);
|
||||
icon.setPickOnBounds(true);
|
||||
icon.setPreserveRatio(true);
|
||||
|
||||
icon.visibleProperty().bind(visibleProperty());
|
||||
|
||||
GridPane.setValignment(icon, VPos.TOP);
|
||||
GridPane.setMargin(icon, new Insets(4, 2, 0, 0));
|
||||
GridPane.setRowSpan(icon, 2);
|
||||
|
||||
label = new Label();
|
||||
label.textProperty().bindBidirectional(text);
|
||||
label.setWrapText(true);
|
||||
label.textProperty().bind(text);
|
||||
label.prefWidthProperty().bind(prefWidth);
|
||||
label.setTextOverrun(OverrunStyle.WORD_ELLIPSIS);
|
||||
|
||||
link = new Hyperlink(BSResources.get("shared.readMore"));
|
||||
link.setPadding(new Insets(0, 0, 0, -2));
|
||||
|
||||
vBox = new VBox();
|
||||
vBox.setSpacing(0);
|
||||
vBox.getChildren().addAll(label, link);
|
||||
// We need that to know if we have a wrapping or not.
|
||||
// Did not find a way to get that from the API.
|
||||
Label testLabel = new Label();
|
||||
testLabel.textProperty().bind(text);
|
||||
|
||||
visibleProperty().addListener((ov, oldValue, newValue) -> {
|
||||
icon.setVisible(newValue);
|
||||
vBox.setVisible(newValue);
|
||||
textFlow = new TextFlow();
|
||||
textFlow.visibleProperty().bind(visibleProperty());
|
||||
textFlow.getChildren().addAll(testLabel);
|
||||
|
||||
testLabel.widthProperty().addListener((ov, o, n) -> {
|
||||
if ((double) n > textFlow.getWidth()) {
|
||||
link.setText(BSResources.get("shared.readMore"));
|
||||
useReadMore = true;
|
||||
}
|
||||
else {
|
||||
link.setText(BSResources.get("shared.openHelp"));
|
||||
}
|
||||
Platform.runLater(() -> textFlow.getChildren().setAll(label, link));
|
||||
});
|
||||
|
||||
// The text in the label does not get correctly displayed if there is not enough available overall height.
|
||||
// Did not find a better way yet to solve the issue...
|
||||
label.heightProperty().addListener((ov, o, n) -> {
|
||||
vBox.setMinHeight((double) n + 100);
|
||||
label.setMinHeight((double) n);
|
||||
Platform.runLater(() -> vBox.setMinHeight(label.getHeight() + 15));
|
||||
// when clicking "Read more..." we expand and change the link to the Help
|
||||
link.setOnAction(new EventHandler<ActionEvent>() {
|
||||
@Override
|
||||
public void handle(ActionEvent actionEvent) {
|
||||
if (useReadMore) {
|
||||
|
||||
label.setWrapText(true);
|
||||
link.setText(BSResources.get("shared.openHelp"));
|
||||
label.prefWidthProperty().bind(textFlow.widthProperty());
|
||||
link.setVisited(false);
|
||||
// focus border is a bit confusing here so we remove it
|
||||
link.setStyle("-fx-focus-color: transparent;");
|
||||
link.setOnAction(onAction.get());
|
||||
}
|
||||
else {
|
||||
onAction.get().handle(actionEvent);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -108,41 +137,42 @@ public class InfoDisplay extends Parent {
|
|||
|
||||
public void setText(String text) {
|
||||
this.text.set(text);
|
||||
}
|
||||
|
||||
label.setText(text);
|
||||
public void setPrefWidth(double prefWidth) {
|
||||
this.prefWidth.set(prefWidth);
|
||||
// label.setPrefWidth(getPrefWidth());
|
||||
}
|
||||
|
||||
public void setGridPane(GridPane gridPane) {
|
||||
this.gridPane.set(gridPane);
|
||||
|
||||
gridPane.getChildren().addAll(icon, vBox);
|
||||
gridPane.getChildren().addAll(icon, textFlow);
|
||||
|
||||
GridPane.setColumnIndex(icon, columnIndex.get());
|
||||
GridPane.setColumnIndex(vBox, columnIndex.get() + 1);
|
||||
GridPane.setColumnIndex(textFlow, columnIndex.get() + 1);
|
||||
|
||||
GridPane.setRowIndex(icon, rowIndex.get());
|
||||
GridPane.setRowIndex(vBox, rowIndex.get());
|
||||
GridPane.setRowIndex(textFlow, rowIndex.get());
|
||||
}
|
||||
|
||||
public void setRowIndex(int rowIndex) {
|
||||
this.rowIndex.set(rowIndex);
|
||||
|
||||
GridPane.setRowIndex(icon, rowIndex);
|
||||
GridPane.setRowIndex(vBox, rowIndex);
|
||||
GridPane.setRowIndex(textFlow, rowIndex);
|
||||
}
|
||||
|
||||
public void setColumnIndex(int columnIndex) {
|
||||
this.columnIndex.set(columnIndex);
|
||||
|
||||
GridPane.setColumnIndex(icon, columnIndex);
|
||||
GridPane.setColumnIndex(vBox, columnIndex + 1);
|
||||
GridPane.setColumnIndex(textFlow, columnIndex + 1);
|
||||
|
||||
}
|
||||
|
||||
public final void setOnAction(javafx.event.EventHandler<javafx.event.ActionEvent> eventHandler) {
|
||||
public final void setOnAction(EventHandler<ActionEvent> eventHandler) {
|
||||
onAction.set(eventHandler);
|
||||
|
||||
link.setOnAction(eventHandler);
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,6 +188,14 @@ public class InfoDisplay extends Parent {
|
|||
return text;
|
||||
}
|
||||
|
||||
public double getPrefWidth() {
|
||||
return prefWidth.get();
|
||||
}
|
||||
|
||||
public DoubleProperty prefWidthProperty() {
|
||||
return prefWidth;
|
||||
}
|
||||
|
||||
public int getColumnIndex() {
|
||||
return columnIndex.get();
|
||||
}
|
||||
|
@ -189,4 +227,5 @@ public class InfoDisplay extends Parent {
|
|||
public ObjectProperty<GridPane> gridPaneProperty() {
|
||||
return gridPane;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.components;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TitledSeparator extends Pane {
|
||||
private static final Logger log = LoggerFactory.getLogger(TitledSeparator.class);
|
||||
|
||||
private final Label label;
|
||||
private final Separator separator;
|
||||
private StringProperty text = new SimpleStringProperty();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public TitledSeparator() {
|
||||
GridPane.setMargin(this, new Insets(-10, -10, -10, -10));
|
||||
GridPane.setColumnSpan(this, 2);
|
||||
|
||||
separator = new Separator();
|
||||
separator.prefWidthProperty().bind(widthProperty());
|
||||
|
||||
label = new Label();
|
||||
label.textProperty().bind(text);
|
||||
label.setLayoutX(8);
|
||||
label.setLayoutY(-8);
|
||||
label.setPadding(new Insets(0, 7, 0, 5));
|
||||
setActive();
|
||||
getChildren().addAll(separator, label);
|
||||
}
|
||||
|
||||
public void setInactive() {
|
||||
separator.setId("titled-separator");
|
||||
label.setId("titled-separator-label");
|
||||
}
|
||||
|
||||
public void setActive() {
|
||||
separator.setId("titled-separator-active");
|
||||
label.setId("titled-separator-label-active");
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text.get();
|
||||
}
|
||||
|
||||
public StringProperty textProperty() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text.set(text);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -44,7 +44,7 @@ import javafx.collections.ObservableList;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MainModel extends UIModel {
|
||||
class MainModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(MainModel.class);
|
||||
|
||||
private final User user;
|
||||
|
@ -56,11 +56,11 @@ public class MainModel extends UIModel {
|
|||
private boolean messageFacadeInited;
|
||||
private boolean walletFacadeInited;
|
||||
|
||||
public final BooleanProperty backendInited = new SimpleBooleanProperty();
|
||||
public final DoubleProperty networkSyncProgress = new SimpleDoubleProperty();
|
||||
public final BooleanProperty networkSyncComplete = new SimpleBooleanProperty();
|
||||
public final BooleanProperty takeOfferRequested = new SimpleBooleanProperty();
|
||||
public final ObjectProperty<Coin> balance = new SimpleObjectProperty<>();
|
||||
final BooleanProperty backendInited = new SimpleBooleanProperty();
|
||||
final DoubleProperty networkSyncProgress = new SimpleDoubleProperty();
|
||||
final BooleanProperty networkSyncComplete = new SimpleBooleanProperty();
|
||||
final BooleanProperty takeOfferRequested = new SimpleBooleanProperty();
|
||||
final ObjectProperty<Coin> balance = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -99,7 +99,7 @@ public class MainModel extends UIModel {
|
|||
// Public
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void initBackend() {
|
||||
void initBackend() {
|
||||
Profiler.printMsgWithTime("MainModel.initFacades");
|
||||
messageFacade.init(new BootstrapListener() {
|
||||
@Override
|
||||
|
@ -135,27 +135,29 @@ public class MainModel extends UIModel {
|
|||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setSelectedNavigationItem(NavigationItem navigationItem) {
|
||||
void setSelectedNavigationItem(NavigationItem navigationItem) {
|
||||
persistence.write(this, "selectedNavigationItem", navigationItem);
|
||||
}
|
||||
|
||||
public void setCurrentBankAccount(BankAccount bankAccount) {
|
||||
void setCurrentBankAccount(BankAccount bankAccount) {
|
||||
user.setCurrentBankAccount(bankAccount);
|
||||
persistence.write(user);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public ObservableList<BankAccount> getBankAccounts() {
|
||||
ObservableList<BankAccount> getBankAccounts() {
|
||||
return user.getBankAccounts();
|
||||
}
|
||||
|
||||
public ObjectProperty<BankAccount> currentBankAccountProperty() {
|
||||
ObjectProperty<BankAccount> currentBankAccountProperty() {
|
||||
return user.currentBankAccountProperty();
|
||||
}
|
||||
|
||||
public NavigationItem[] getSelectedNavigationItems() {
|
||||
NavigationItem[] getSelectedNavigationItems() {
|
||||
NavigationItem[] selectedNavigationItems = (NavigationItem[]) persistence.read(this, "selectedNavigationItems");
|
||||
if (selectedNavigationItems == null || selectedNavigationItems.length == 0)
|
||||
selectedNavigationItems = new NavigationItem[]{NavigationItem.BUY};
|
||||
|
@ -187,7 +189,6 @@ public class MainModel extends UIModel {
|
|||
backendInited.set(true);
|
||||
}
|
||||
|
||||
|
||||
private void updateBalance(Coin balance) {
|
||||
this.balance.set(balance);
|
||||
}
|
||||
|
|
|
@ -36,16 +36,16 @@ import javafx.util.StringConverter;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MainPM extends PresentationModel<MainModel> {
|
||||
class MainPM extends PresentationModel<MainModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(MainPM.class);
|
||||
|
||||
public final BooleanProperty backendInited = new SimpleBooleanProperty();
|
||||
public final StringProperty balance = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountsComboBoxPrompt = new SimpleStringProperty();
|
||||
public final BooleanProperty bankAccountsComboBoxDisable = new SimpleBooleanProperty();
|
||||
public final StringProperty splashScreenInfoText = new SimpleStringProperty();
|
||||
public final BooleanProperty networkSyncComplete = new SimpleBooleanProperty();
|
||||
public final BooleanProperty takeOfferRequested = new SimpleBooleanProperty();
|
||||
final BooleanProperty backendInited = new SimpleBooleanProperty();
|
||||
final StringProperty balance = new SimpleStringProperty();
|
||||
final StringProperty bankAccountsComboBoxPrompt = new SimpleStringProperty();
|
||||
final BooleanProperty bankAccountsComboBoxDisable = new SimpleBooleanProperty();
|
||||
final StringProperty splashScreenInfoText = new SimpleStringProperty();
|
||||
final BooleanProperty networkSyncComplete = new SimpleBooleanProperty();
|
||||
final BooleanProperty takeOfferRequested = new SimpleBooleanProperty();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -103,7 +103,7 @@ public class MainPM extends PresentationModel<MainModel> {
|
|||
// Public
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void initBackend() {
|
||||
void initBackend() {
|
||||
model.initBackend();
|
||||
}
|
||||
|
||||
|
@ -112,11 +112,11 @@ public class MainPM extends PresentationModel<MainModel> {
|
|||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setSelectedNavigationItem(NavigationItem navigationItem) {
|
||||
void setSelectedNavigationItem(NavigationItem navigationItem) {
|
||||
model.setSelectedNavigationItem(navigationItem);
|
||||
}
|
||||
|
||||
public void setCurrentBankAccount(BankAccount bankAccount) {
|
||||
void setCurrentBankAccount(BankAccount bankAccount) {
|
||||
model.setCurrentBankAccount(bankAccount);
|
||||
}
|
||||
|
||||
|
@ -125,19 +125,19 @@ public class MainPM extends PresentationModel<MainModel> {
|
|||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public NavigationItem[] getSelectedNavigationItems() {
|
||||
NavigationItem[] getSelectedNavigationItems() {
|
||||
return model.getSelectedNavigationItems();
|
||||
}
|
||||
|
||||
public ObservableList<BankAccount> getBankAccounts() {
|
||||
ObservableList<BankAccount> getBankAccounts() {
|
||||
return model.getBankAccounts();
|
||||
}
|
||||
|
||||
public ObjectProperty<BankAccount> currentBankAccountProperty() {
|
||||
ObjectProperty<BankAccount> currentBankAccountProperty() {
|
||||
return model.currentBankAccountProperty();
|
||||
}
|
||||
|
||||
public StringConverter<BankAccount> getBankAccountsConverter() {
|
||||
StringConverter<BankAccount> getBankAccountsConverter() {
|
||||
return new StringConverter<BankAccount>() {
|
||||
@Override
|
||||
public String toString(BankAccount bankAccount) {
|
||||
|
|
|
@ -28,7 +28,7 @@ import io.bitsquare.gui.components.Popups;
|
|||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.gui.util.Profiler;
|
||||
import io.bitsquare.gui.util.Transitions;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -53,20 +53,17 @@ import org.slf4j.LoggerFactory;
|
|||
public class MainViewCB extends ViewCB<MainPM> {
|
||||
private static final Logger log = LoggerFactory.getLogger(MainViewCB.class);
|
||||
|
||||
private NavigationController navigationController;
|
||||
private OverlayController overlayController;
|
||||
private final NavigationController navigationController;
|
||||
private final OverlayController overlayController;
|
||||
|
||||
private final ToggleGroup navButtonsGroup = new ToggleGroup();
|
||||
private NavigationItem mainNavigationItem;
|
||||
|
||||
private BorderPane baseApplicationContainer;
|
||||
private VBox baseOverlayContainer;
|
||||
private AnchorPane applicationContainer;
|
||||
private AnchorPane contentContainer;
|
||||
private HBox leftNavPane, rightNavPane;
|
||||
private NetworkSyncPane networkSyncPane;
|
||||
private MenuBar menuBar;
|
||||
private Label loadingLabel;
|
||||
private ToggleButton buyButton, sellButton, homeButton, msgButton, ordersButton, fundsButton, settingsButton,
|
||||
accountButton;
|
||||
private Pane ordersButtonButtonPane;
|
||||
|
@ -83,15 +80,27 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
|
||||
this.navigationController = navigationController;
|
||||
this.overlayController = overlayController;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
Profiler.printMsgWithTime("MainController.initialize");
|
||||
|
||||
// just temp. ugly hack... Popups will be removed
|
||||
Popups.setOverlayController(overlayController);
|
||||
|
||||
navigationController.addListener(navigationItems -> {
|
||||
if (navigationItems != null) {
|
||||
for (int i = 0; i < navigationItems.length; i++) {
|
||||
if (navigationItems[i].getLevel() == 1) {
|
||||
mainNavigationItem = navigationItems[i];
|
||||
for (NavigationItem navigationItem : navigationItems) {
|
||||
if (navigationItem.getLevel() == 1) {
|
||||
mainNavigationItem = navigationItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -115,19 +124,7 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
Transitions.removeBlur(baseApplicationContainer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
|
||||
Profiler.printMsgWithTime("MainController.initialize");
|
||||
startup();
|
||||
}
|
||||
|
||||
|
@ -142,43 +139,11 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
// Navigation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void selectMainMenuButton(NavigationItem navigationItem) {
|
||||
switch (navigationItem) {
|
||||
case HOME:
|
||||
homeButton.setSelected(true);
|
||||
break;
|
||||
case FUNDS:
|
||||
fundsButton.setSelected(true);
|
||||
break;
|
||||
case MSG:
|
||||
msgButton.setSelected(true);
|
||||
break;
|
||||
case ORDERS:
|
||||
ordersButton.setSelected(true);
|
||||
break;
|
||||
case SETTINGS:
|
||||
settingsButton.setSelected(true);
|
||||
break;
|
||||
case SELL:
|
||||
sellButton.setSelected(true);
|
||||
break;
|
||||
case BUY:
|
||||
buyButton.setSelected(true);
|
||||
break;
|
||||
case ACCOUNT:
|
||||
accountButton.setSelected(true);
|
||||
break;
|
||||
default:
|
||||
log.error(navigationItem.getFxmlUrl() + " is no main navigation item");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Initializable loadView(NavigationItem navigationItem) {
|
||||
super.loadView((navigationItem));
|
||||
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try {
|
||||
final Node view = loader.load();
|
||||
contentContainer.getChildren().setAll(view);
|
||||
|
@ -212,8 +177,8 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
private void onBaseContainersCreated() {
|
||||
Profiler.printMsgWithTime("MainController.onBaseContainersCreated");
|
||||
|
||||
menuBar = getMenuBar();
|
||||
applicationContainer = getApplicationContainer();
|
||||
MenuBar menuBar = getMenuBar();
|
||||
AnchorPane applicationContainer = getApplicationContainer();
|
||||
|
||||
baseApplicationContainer.setTop(menuBar);
|
||||
baseApplicationContainer.setCenter(applicationContainer);
|
||||
|
@ -260,6 +225,38 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void selectMainMenuButton(NavigationItem navigationItem) {
|
||||
switch (navigationItem) {
|
||||
case HOME:
|
||||
homeButton.setSelected(true);
|
||||
break;
|
||||
case FUNDS:
|
||||
fundsButton.setSelected(true);
|
||||
break;
|
||||
case MSG:
|
||||
msgButton.setSelected(true);
|
||||
break;
|
||||
case ORDERS:
|
||||
ordersButton.setSelected(true);
|
||||
break;
|
||||
case SETTINGS:
|
||||
settingsButton.setSelected(true);
|
||||
break;
|
||||
case SELL:
|
||||
sellButton.setSelected(true);
|
||||
break;
|
||||
case BUY:
|
||||
buyButton.setSelected(true);
|
||||
break;
|
||||
case ACCOUNT:
|
||||
accountButton.setSelected(true);
|
||||
break;
|
||||
default:
|
||||
log.error(navigationItem.getFxmlUrl() + " is no main navigation item");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private BorderPane getBaseApplicationContainer() {
|
||||
BorderPane borderPane = new BorderPane();
|
||||
borderPane.setId("base-content-container");
|
||||
|
@ -280,7 +277,7 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
subTitle.setAlignment(Pos.CENTER);
|
||||
subTitle.setId("logo-sub-title-label");
|
||||
|
||||
loadingLabel = new Label();
|
||||
Label loadingLabel = new Label();
|
||||
loadingLabel.setAlignment(Pos.CENTER);
|
||||
loadingLabel.setPadding(new Insets(80, 0, 0, 0));
|
||||
loadingLabel.textProperty().bind(presentationModel.splashScreenInfoText);
|
||||
|
@ -460,6 +457,4 @@ public class MainViewCB extends ViewCB<MainPM> {
|
|||
vBox.getChildren().setAll(comboBox, titleLabel);
|
||||
parent.getChildren().add(vBox);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import io.bitsquare.gui.NavigationController;
|
|||
import io.bitsquare.gui.NavigationItem;
|
||||
import io.bitsquare.gui.ViewCB;
|
||||
import io.bitsquare.gui.main.account.setup.AccountSetupViewCB;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -105,7 +105,7 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
|
|||
public Initializable loadView(NavigationItem navigationItem) {
|
||||
super.loadView(navigationItem);
|
||||
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try {
|
||||
Pane view = loader.load();
|
||||
tab.setContent(view);
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
</GridPane.margin>
|
||||
</HBox>
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="4"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="4" prefWidth="570"
|
||||
text="Protect your wallet with a strong password. You need to enter the password any time you withdraw Bitcoin from your trading wallets. You can change the password later in the settings. Open the help menu for more information."/>
|
||||
|
||||
<columnConstraints>
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
visible="false" prefWidth="150.0"/>
|
||||
</HBox>
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenSetupHelp" rowIndex="7"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenSetupHelp" rowIndex="7" prefWidth="510"
|
||||
text="The payments account data will be saved in a encrypted form to the Bitcoin block chain and will be used in the trade process for account verification."/>
|
||||
|
||||
<HBox fx:id="buttonsHBox" GridPane.columnIndex="1" GridPane.rowIndex="8" spacing="10">
|
||||
|
@ -111,7 +111,7 @@
|
|||
<Button fx:id="removeBankAccountButton" text="Remove selected payments account" onAction="#onRemoveAccount"
|
||||
GridPane.columnIndex="1" GridPane.rowIndex="10" disable="true"/>
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenManageAccountsHelp" rowIndex="11"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenManageAccountsHelp" rowIndex="11" prefWidth="510"
|
||||
text="When you change your payments accounts later you need to do the renew the registration and pay the small registration fee."/>
|
||||
|
||||
<columnConstraints>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
</GridPane.margin>
|
||||
</HBox>
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="3"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="3" prefWidth="570"
|
||||
text="Protect your wallet with a strong password. You need to enter the password any time you withdraw Bitcoin from your trading wallets. You can change the password later in the settings. Open the help menu for more information."/>
|
||||
|
||||
<columnConstraints>
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
</GridPane.margin>
|
||||
</BalanceTextField>
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="3"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="3" prefWidth="570"
|
||||
text="You need to pay a tiny registration fee which is needed for storing your encrypted account data in the blockchain. That will be used in the trade process for account verification."/>
|
||||
|
||||
<Button fx:id="payButton" text="Pay registration fee" onAction="#onPayFee" GridPane.columnIndex="1"
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
prefWidth="150.0"/>
|
||||
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenLanguagesHelp" rowIndex="2"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenLanguagesHelp" rowIndex="2" prefWidth="570"
|
||||
text="Trade with users who have at least 1 shared language."/>
|
||||
|
||||
<!--
|
||||
|
@ -79,8 +79,7 @@
|
|||
prefWidth="150.0" visible="false"/>
|
||||
</HBox>
|
||||
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenCountriesHelp" rowIndex="5"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenCountriesHelp" rowIndex="5" prefWidth="570"
|
||||
text="Restrict trades with these payments account countries."/>
|
||||
|
||||
|
||||
|
@ -108,8 +107,7 @@
|
|||
<Button text="Add arbitrator" onAction="#onOpenArbitratorScreen" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="7"/>
|
||||
|
||||
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenArbitratorsHelp" rowIndex="8"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenArbitratorsHelp" rowIndex="8" prefWidth="570"
|
||||
text="You need to choose at least 3 arbitrators."/>
|
||||
|
||||
<Button fx:id="completedButton" text="Completed" onAction="#onCompleted" disable="true" GridPane.columnIndex="1"
|
||||
|
|
|
@ -28,7 +28,7 @@ import io.bitsquare.gui.main.help.HelpId;
|
|||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.locale.Region;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -187,7 +187,7 @@ public class RestrictionsViewCB extends CachedViewCB<RestrictionsPM> implements
|
|||
@Override
|
||||
public Initializable loadView(NavigationItem navigationItem) {
|
||||
// TODO caching causes exception
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
try {
|
||||
final Node view = loader.load();
|
||||
//TODO Resolve type problem...
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<Insets bottom="5"/>
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="3"
|
||||
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="3" prefWidth="570"
|
||||
text="You can recreate your wallet our of these words when you lose your wallet. Backup it on paper to have better protection against online theft. Open the help menu for more information."/>
|
||||
|
||||
<columnConstraints>
|
||||
|
|
|
@ -23,7 +23,7 @@ import io.bitsquare.gui.NavigationItem;
|
|||
import io.bitsquare.gui.PresentationModel;
|
||||
import io.bitsquare.gui.ViewCB;
|
||||
import io.bitsquare.gui.main.account.content.ContextAware;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -155,7 +155,7 @@ public class AccountSettingsViewCB extends CachedViewCB<AccountSettingsPM> {
|
|||
|
||||
@Override
|
||||
public Initializable loadView(NavigationItem navigationItem) {
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try {
|
||||
final Pane view = loader.load();
|
||||
content.getChildren().setAll(view);
|
||||
|
|
|
@ -29,7 +29,7 @@ import io.bitsquare.gui.main.account.content.registration.RegistrationViewCB;
|
|||
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsViewCB;
|
||||
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsViewCB;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -165,7 +165,7 @@ public class AccountSetupViewCB extends CachedViewCB<AccountSetupPM> implements
|
|||
|
||||
@Override
|
||||
public Initializable loadView(NavigationItem navigationItem) {
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try {
|
||||
final Pane view = loader.load();
|
||||
content.getChildren().setAll(view);
|
||||
|
|
|
@ -26,7 +26,7 @@ import io.bitsquare.msg.MessageFacade;
|
|||
import io.bitsquare.msg.listeners.ArbitratorListener;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -122,7 +122,7 @@ public class ArbitratorBrowserController extends CachedViewController implements
|
|||
|
||||
@Override
|
||||
public Initializable loadViewAndGetChildController(NavigationItem navigationItem) {
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try {
|
||||
final Node view = loader.load();
|
||||
arbitratorProfileController = loader.getController();
|
||||
|
|
|
@ -21,7 +21,7 @@ import io.bitsquare.BitSquare;
|
|||
import io.bitsquare.gui.CachedViewController;
|
||||
import io.bitsquare.gui.NavigationItem;
|
||||
import io.bitsquare.gui.main.arbitrators.registration.ArbitratorRegistrationController;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class HomeController extends CachedViewController {
|
|||
@Override
|
||||
public Initializable loadViewAndGetChildController(NavigationItem navigationItem) {
|
||||
// don't use caching here, cause exc. -> need to investigate and is rarely called so no caching is better
|
||||
final BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
final ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
try {
|
||||
final Parent view = loader.load();
|
||||
arbitratorRegistrationController = loader.getController();
|
||||
|
|
|
@ -23,6 +23,7 @@ import io.bitsquare.trade.Trade;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
// TODO don't use inheritance
|
||||
public class PendingTradesListItem extends OrderBookListItem {
|
||||
private static final Logger log = LoggerFactory.getLogger(PendingTradesListItem.class);
|
||||
|
||||
|
@ -30,7 +31,7 @@ public class PendingTradesListItem extends OrderBookListItem {
|
|||
private final Trade trade;
|
||||
|
||||
public PendingTradesListItem(Trade trade) {
|
||||
super(trade.getOffer());
|
||||
super(trade.getOffer(), trade.getOffer().getBankAccountCountry());
|
||||
this.trade = trade;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,20 +17,13 @@
|
|||
|
||||
package io.bitsquare.gui.main.trade;
|
||||
|
||||
import io.bitsquare.trade.Direction;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BuyViewCB extends TradeViewCB {
|
||||
|
||||
@Inject
|
||||
public BuyViewCB(TradePM presentationModel) {
|
||||
super(presentationModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initOrderBook() {
|
||||
orderBookViewCB.initOrderBook(Direction.BUY, presentationModel.getOrderBookInfo());
|
||||
public BuyViewCB() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,28 +26,40 @@ import javafx.beans.property.ObjectProperty;
|
|||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
/**
|
||||
* Shared data between the different trade UIs
|
||||
* Holds shared data between the different trade UIs
|
||||
*/
|
||||
public class OrderBookInfo {
|
||||
|
||||
private final ObjectProperty<Direction> direction = new SimpleObjectProperty<>();
|
||||
|
||||
private Fiat price;
|
||||
private Coin amount;
|
||||
private Fiat price;
|
||||
private Fiat volume;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public OrderBookInfo() {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Coin getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Coin amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public void setPrice(Fiat price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public void setVolume(Fiat volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public void setDirection(Direction direction) {
|
||||
this.direction.set(direction);
|
||||
}
|
||||
|
@ -57,12 +69,16 @@ public class OrderBookInfo {
|
|||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Coin getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public Fiat getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Fiat price) {
|
||||
this.price = price;
|
||||
public Fiat getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
|
@ -72,6 +88,4 @@ public class OrderBookInfo {
|
|||
public ObjectProperty<Direction> directionProperty() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,22 +17,13 @@
|
|||
|
||||
package io.bitsquare.gui.main.trade;
|
||||
|
||||
import io.bitsquare.trade.Direction;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class SellViewCB extends TradeViewCB {
|
||||
|
||||
@Inject
|
||||
public SellViewCB(TradePM presentationModel) {
|
||||
super(presentationModel);
|
||||
public SellViewCB() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initOrderBook() {
|
||||
orderBookViewCB.initOrderBook(Direction.SELL, presentationModel.getOrderBookInfo());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.trade;
|
||||
|
||||
import io.bitsquare.gui.UIModel;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TradeModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(TradeModel.class);
|
||||
|
||||
private OrderBookInfo orderBookInfo;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public TradeModel(OrderBookInfo orderBookInfo) {
|
||||
this.orderBookInfo = orderBookInfo;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public OrderBookInfo getOrderBookInfo() {
|
||||
return orderBookInfo;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,8 @@ import io.bitsquare.gui.components.InputTextField;
|
|||
import io.bitsquare.gui.main.trade.createoffer.CreateOfferViewCB;
|
||||
import io.bitsquare.gui.main.trade.orderbook.OrderBookViewCB;
|
||||
import io.bitsquare.gui.main.trade.takeoffer.TakeOfferController;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -43,10 +44,11 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
||||
public class TradeViewCB extends CachedViewCB {
|
||||
private static final Logger log = LoggerFactory.getLogger(TradeViewCB.class);
|
||||
|
||||
protected OrderBookViewCB orderBookViewCB;
|
||||
private final OrderBookInfo orderBookInfo = new OrderBookInfo();
|
||||
private OrderBookViewCB orderBookViewCB;
|
||||
private CreateOfferViewCB createOfferViewCB;
|
||||
private TakeOfferController takeOfferController;
|
||||
private Node createOfferView;
|
||||
|
@ -56,8 +58,8 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected TradeViewCB(TradePM presentationModel) {
|
||||
super(presentationModel);
|
||||
protected TradeViewCB() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,8 +72,10 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
|
||||
Direction direction = (this instanceof BuyViewCB) ? Direction.BUY : Direction.SELL;
|
||||
orderBookInfo.setDirection(direction);
|
||||
|
||||
loadView(NavigationItem.ORDER_BOOK);
|
||||
initOrderBook();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -90,12 +94,8 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
tabPane.getTabs().addListener((ListChangeListener<Tab>) change -> {
|
||||
change.next();
|
||||
List<? extends Tab> removedTabs = change.getRemoved();
|
||||
if (removedTabs.size() == 1 && removedTabs.get(0).getContent().equals(createOfferView)) {
|
||||
if (createOfferViewCB != null) {
|
||||
createOfferViewCB.terminate();
|
||||
createOfferViewCB = null;
|
||||
}
|
||||
}
|
||||
if (removedTabs.size() == 1 && removedTabs.get(0).getContent().equals(createOfferView))
|
||||
onCreateOfferViewRemoved();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -124,8 +124,8 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
if (navigationItem == NavigationItem.ORDER_BOOK) {
|
||||
checkArgument(orderBookViewCB == null);
|
||||
// Orderbook must not be cached by GuiceFXMLLoader as we use 2 instances for sell and buy screens.
|
||||
BSFXMLLoader orderBookLoader =
|
||||
new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
ViewLoader orderBookLoader =
|
||||
new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
try {
|
||||
final Parent view = orderBookLoader.load();
|
||||
final Tab tab = new Tab("Orderbook");
|
||||
|
@ -134,6 +134,9 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
tabPane.getTabs().add(tab);
|
||||
orderBookViewCB = orderBookLoader.getController();
|
||||
orderBookViewCB.setParent(this);
|
||||
orderBookViewCB.setOrderBookInfo(orderBookInfo);
|
||||
orderBookViewCB.setNavigationListener(n -> loadView(n));
|
||||
|
||||
return orderBookViewCB;
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
|
@ -144,16 +147,13 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
|
||||
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times
|
||||
// in different graphs
|
||||
BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
try {
|
||||
createOfferView = loader.load();
|
||||
createOfferViewCB = loader.getController();
|
||||
createOfferViewCB.setParent(this);
|
||||
createOfferViewCB.setOnClose(() -> {
|
||||
orderBookViewCB.enableCreateOfferButton();
|
||||
return null;
|
||||
});
|
||||
|
||||
createOfferViewCB.initWithOrderBookInfo(orderBookInfo);
|
||||
createOfferViewCB.setCloseListener(() -> onCreateOfferViewRemoved());
|
||||
final Tab tab = new Tab("Create offer");
|
||||
tab.setContent(createOfferView);
|
||||
tabPane.getTabs().add(tab);
|
||||
|
@ -168,7 +168,7 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
|
||||
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times
|
||||
// in different graphs
|
||||
BSFXMLLoader loader = new BSFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
ViewLoader loader = new ViewLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
try {
|
||||
final Parent view = loader.load();
|
||||
takeOfferController = loader.getController();
|
||||
|
@ -193,22 +193,20 @@ public abstract class TradeViewCB extends CachedViewCB<TradePM> {
|
|||
// Public
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onCreateOfferViewRemoved() {
|
||||
createOfferViewCB = null;
|
||||
orderBookViewCB.enableCreateOfferButton();
|
||||
}
|
||||
|
||||
//TODO takeOfferController is not updated yet to new UI pattern
|
||||
public void onTakeOfferViewRemoved() {
|
||||
takeOfferController = null;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Abstract methods
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
abstract protected void initOrderBook();
|
||||
|
||||
|
||||
private void onCreateOfferViewRemoved() {
|
||||
if (createOfferViewCB != null)
|
||||
createOfferViewCB = null;
|
||||
orderBookViewCB.enableCreateOfferButton();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,32 +77,32 @@ public class CreateOfferModel extends UIModel {
|
|||
@Nullable private Direction direction = null;
|
||||
private AddressEntry addressEntry;
|
||||
|
||||
public final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
||||
public final StringProperty transactionId = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountCurrency = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountCounty = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountType = new SimpleStringProperty();
|
||||
public final StringProperty fiatCode = new SimpleStringProperty();
|
||||
public final StringProperty btcCode = new SimpleStringProperty();
|
||||
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
||||
final StringProperty transactionId = new SimpleStringProperty();
|
||||
final StringProperty bankAccountCurrency = new SimpleStringProperty();
|
||||
final StringProperty bankAccountCounty = new SimpleStringProperty();
|
||||
final StringProperty bankAccountType = new SimpleStringProperty();
|
||||
final StringProperty fiatCode = new SimpleStringProperty();
|
||||
final StringProperty btcCode = new SimpleStringProperty();
|
||||
|
||||
public final LongProperty collateralAsLong = new SimpleLongProperty();
|
||||
final LongProperty collateralAsLong = new SimpleLongProperty();
|
||||
|
||||
public final BooleanProperty requestPlaceOfferSuccess = new SimpleBooleanProperty();
|
||||
public final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
|
||||
public final BooleanProperty useMBTC = new SimpleBooleanProperty();
|
||||
final BooleanProperty requestPlaceOfferSuccess = new SimpleBooleanProperty();
|
||||
final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
|
||||
final BooleanProperty useMBTC = new SimpleBooleanProperty();
|
||||
|
||||
public final ObjectProperty<Coin> amountAsCoin = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Coin> minAmountAsCoin = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Fiat> priceAsFiat = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Fiat> volumeAsFiat = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Coin> collateralAsCoin = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Coin> offerFeeAsCoin = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Coin> networkFeeAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> amountAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> minAmountAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Fiat> priceAsFiat = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Fiat> volumeAsFiat = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> collateralAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> offerFeeAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> networkFeeAsCoin = new SimpleObjectProperty<>();
|
||||
|
||||
public final ObservableList<Country> acceptedCountries = FXCollections.observableArrayList();
|
||||
public final ObservableList<Locale> acceptedLanguages = FXCollections.observableArrayList();
|
||||
public final ObservableList<Arbitrator> acceptedArbitrators = FXCollections.observableArrayList();
|
||||
final ObservableList<Country> acceptedCountries = FXCollections.observableArrayList();
|
||||
final ObservableList<Locale> acceptedLanguages = FXCollections.observableArrayList();
|
||||
final ObservableList<Arbitrator> acceptedArbitrators = FXCollections.observableArrayList();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -144,6 +144,15 @@ public class CreateOfferModel extends UIModel {
|
|||
});
|
||||
updateBalance(walletFacade.getBalanceForAddress(getAddressEntry().getAddress()));
|
||||
}
|
||||
|
||||
if (user != null) {
|
||||
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> applyBankAccount(newValue));
|
||||
|
||||
applyBankAccount(user.getCurrentBankAccount());
|
||||
}
|
||||
|
||||
if (settings != null)
|
||||
btcCode.bind(settings.btcDenominationProperty());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,18 +165,6 @@ public class CreateOfferModel extends UIModel {
|
|||
acceptedCountries.setAll(settings.getAcceptedCountries());
|
||||
acceptedLanguages.setAll(settings.getAcceptedLanguageLocales());
|
||||
acceptedArbitrators.setAll(settings.getAcceptedArbitrators());
|
||||
btcCode.bind(settings.btcDenominationProperty());
|
||||
}
|
||||
|
||||
if (user != null) {
|
||||
BankAccount bankAccount = user.getCurrentBankAccount();
|
||||
if (bankAccount != null) {
|
||||
bankAccountType.set(bankAccount.getBankAccountType().toString());
|
||||
bankAccountCurrency.set(bankAccount.getCurrency().getCurrencyCode());
|
||||
bankAccountCounty.set(bankAccount.getCountry().getName());
|
||||
|
||||
fiatCode.set(bankAccount.getCurrency().getCurrencyCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +185,7 @@ public class CreateOfferModel extends UIModel {
|
|||
// Public
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void placeOffer() {
|
||||
void placeOffer() {
|
||||
// data validation is done in the trade domain
|
||||
tradeManager.requestPlaceOffer(offerId,
|
||||
direction,
|
||||
|
@ -203,10 +200,12 @@ public class CreateOfferModel extends UIModel {
|
|||
);
|
||||
}
|
||||
|
||||
public void calculateVolume() {
|
||||
void calculateVolume() {
|
||||
try {
|
||||
if (priceAsFiat.get() != null && amountAsCoin.get() != null && !amountAsCoin.get().isZero() && !priceAsFiat
|
||||
.get().isZero()) {
|
||||
if (priceAsFiat.get() != null &&
|
||||
amountAsCoin.get() != null &&
|
||||
!amountAsCoin.get().isZero() &&
|
||||
!priceAsFiat.get().isZero()) {
|
||||
volumeAsFiat.set(new ExchangeRate(priceAsFiat.get()).coinToFiat(amountAsCoin.get()));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
@ -215,14 +214,15 @@ public class CreateOfferModel extends UIModel {
|
|||
}
|
||||
}
|
||||
|
||||
public void calculateAmount() {
|
||||
void calculateAmount() {
|
||||
try {
|
||||
if (volumeAsFiat.get() != null && priceAsFiat.get() != null && !volumeAsFiat.get().isZero() && !priceAsFiat
|
||||
.get().isZero()) {
|
||||
amountAsCoin.set(new ExchangeRate(priceAsFiat.get()).fiatToCoin(volumeAsFiat.get()));
|
||||
|
||||
if (volumeAsFiat.get() != null &&
|
||||
priceAsFiat.get() != null &&
|
||||
!volumeAsFiat.get().isZero() &&
|
||||
!priceAsFiat.get().isZero()) {
|
||||
// If we got a btc value with more then 4 decimals we convert it to max 4 decimals
|
||||
amountAsCoin.set(reduceTo4Decimals(amountAsCoin.get()));
|
||||
amountAsCoin.set(reduceTo4Decimals(new ExchangeRate(priceAsFiat.get()).fiatToCoin(volumeAsFiat.get())));
|
||||
|
||||
calculateTotalToPay();
|
||||
calculateCollateral();
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ public class CreateOfferModel extends UIModel {
|
|||
}
|
||||
}
|
||||
|
||||
public void calculateTotalToPay() {
|
||||
void calculateTotalToPay() {
|
||||
calculateCollateral();
|
||||
try {
|
||||
if (collateralAsCoin.get() != null) {
|
||||
|
@ -244,7 +244,7 @@ public class CreateOfferModel extends UIModel {
|
|||
}
|
||||
}
|
||||
|
||||
public void calculateCollateral() {
|
||||
void calculateCollateral() {
|
||||
try {
|
||||
|
||||
if (amountAsCoin.get() != null)
|
||||
|
@ -255,7 +255,7 @@ public class CreateOfferModel extends UIModel {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isMinAmountLessOrEqualAmount() {
|
||||
boolean isMinAmountLessOrEqualAmount() {
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (minAmountAsCoin.get() != null && amountAsCoin.get() != null)
|
||||
return !minAmountAsCoin.get().isGreaterThan(amountAsCoin.get());
|
||||
|
@ -268,21 +268,21 @@ public class CreateOfferModel extends UIModel {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
public Direction getDirection() {
|
||||
Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(Direction direction) {
|
||||
void setDirection(Direction direction) {
|
||||
// direction can not be changed once it is initially set
|
||||
checkArgument(this.direction == null);
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public WalletFacade getWalletFacade() {
|
||||
WalletFacade getWalletFacade() {
|
||||
return walletFacade;
|
||||
}
|
||||
|
||||
public String getOfferId() {
|
||||
String getOfferId() {
|
||||
return offerId;
|
||||
}
|
||||
|
||||
|
@ -299,4 +299,14 @@ public class CreateOfferModel extends UIModel {
|
|||
public AddressEntry getAddressEntry() {
|
||||
return addressEntry;
|
||||
}
|
||||
|
||||
private void applyBankAccount(BankAccount bankAccount) {
|
||||
if (bankAccount != null) {
|
||||
bankAccountType.set(bankAccount.getBankAccountType().toString());
|
||||
bankAccountCurrency.set(bankAccount.getCurrency().getCurrencyCode());
|
||||
bankAccountCounty.set(bankAccount.getCountry().getName());
|
||||
|
||||
fiatCode.set(bankAccount.getCurrency().getCurrencyCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,45 +55,45 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
private final BtcValidator btcValidator;
|
||||
private final FiatValidator fiatValidator;
|
||||
|
||||
public final StringProperty amount = new SimpleStringProperty();
|
||||
public final StringProperty minAmount = new SimpleStringProperty();
|
||||
public final StringProperty price = new SimpleStringProperty();
|
||||
public final StringProperty volume = new SimpleStringProperty();
|
||||
public final StringProperty collateral = new SimpleStringProperty();
|
||||
public final StringProperty totalToPay = new SimpleStringProperty();
|
||||
public final StringProperty directionLabel = new SimpleStringProperty();
|
||||
public final StringProperty collateralLabel = new SimpleStringProperty();
|
||||
public final StringProperty offerFee = new SimpleStringProperty();
|
||||
public final StringProperty networkFee = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountType = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountCurrency = new SimpleStringProperty();
|
||||
public final StringProperty bankAccountCounty = new SimpleStringProperty();
|
||||
public final StringProperty acceptedCountries = new SimpleStringProperty();
|
||||
public final StringProperty acceptedLanguages = new SimpleStringProperty();
|
||||
public final StringProperty acceptedArbitrators = new SimpleStringProperty();
|
||||
public final StringProperty addressAsString = new SimpleStringProperty();
|
||||
public final StringProperty paymentLabel = new SimpleStringProperty();
|
||||
public final StringProperty transactionId = new SimpleStringProperty();
|
||||
public final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
||||
public final StringProperty btcCode = new SimpleStringProperty();
|
||||
public final StringProperty fiatCode = new SimpleStringProperty();
|
||||
final StringProperty amount = new SimpleStringProperty();
|
||||
final StringProperty minAmount = new SimpleStringProperty();
|
||||
final StringProperty price = new SimpleStringProperty();
|
||||
final StringProperty volume = new SimpleStringProperty();
|
||||
final StringProperty collateral = new SimpleStringProperty();
|
||||
final StringProperty totalToPay = new SimpleStringProperty();
|
||||
final StringProperty directionLabel = new SimpleStringProperty();
|
||||
final StringProperty collateralLabel = new SimpleStringProperty();
|
||||
final StringProperty offerFee = new SimpleStringProperty();
|
||||
final StringProperty networkFee = new SimpleStringProperty();
|
||||
final StringProperty bankAccountType = new SimpleStringProperty();
|
||||
final StringProperty bankAccountCurrency = new SimpleStringProperty();
|
||||
final StringProperty bankAccountCounty = new SimpleStringProperty();
|
||||
final StringProperty acceptedCountries = new SimpleStringProperty();
|
||||
final StringProperty acceptedLanguages = new SimpleStringProperty();
|
||||
final StringProperty acceptedArbitrators = new SimpleStringProperty();
|
||||
final StringProperty addressAsString = new SimpleStringProperty();
|
||||
final StringProperty paymentLabel = new SimpleStringProperty();
|
||||
final StringProperty transactionId = new SimpleStringProperty();
|
||||
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
||||
final StringProperty btcCode = new SimpleStringProperty();
|
||||
final StringProperty fiatCode = new SimpleStringProperty();
|
||||
|
||||
public final BooleanProperty isPlaceOfferButtonVisible = new SimpleBooleanProperty(false);
|
||||
public final BooleanProperty isPlaceOfferButtonDisabled = new SimpleBooleanProperty(true);
|
||||
public final BooleanProperty showWarningAdjustedVolume = new SimpleBooleanProperty();
|
||||
public final BooleanProperty showWarningInvalidFiatDecimalPlaces = new SimpleBooleanProperty();
|
||||
public final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
|
||||
public final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
|
||||
final BooleanProperty isPlaceOfferButtonVisible = new SimpleBooleanProperty(false);
|
||||
final BooleanProperty isPlaceOfferButtonDisabled = new SimpleBooleanProperty(true);
|
||||
final BooleanProperty showWarningAdjustedVolume = new SimpleBooleanProperty();
|
||||
final BooleanProperty showWarningInvalidFiatDecimalPlaces = new SimpleBooleanProperty();
|
||||
final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
|
||||
final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
|
||||
|
||||
public final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<InputValidator.ValidationResult> minAmountValidationResult = new
|
||||
final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<InputValidator.ValidationResult> minAmountValidationResult = new
|
||||
SimpleObjectProperty<>();
|
||||
public final ObjectProperty<InputValidator.ValidationResult> priceValidationResult = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<InputValidator.ValidationResult> volumeValidationResult = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<InputValidator.ValidationResult> priceValidationResult = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<InputValidator.ValidationResult> volumeValidationResult = new SimpleObjectProperty<>();
|
||||
|
||||
// Those are needed for the addressTextField
|
||||
public final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
||||
public final ObjectProperty<Address> address = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Address> address = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -154,7 +154,7 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// setOrderBookFilter is a one time call
|
||||
public void setOrderBookFilter(@NotNull OrderBookInfo orderBookInfo) {
|
||||
void setOrderBookFilter(@NotNull OrderBookInfo orderBookInfo) {
|
||||
model.setDirection(orderBookInfo.getDirection());
|
||||
directionLabel.set(model.getDirection() == Direction.BUY ? BSResources.get("shared.buy") : BSResources.get
|
||||
("shared.sell"));
|
||||
|
@ -176,7 +176,7 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
// UI actions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onPlaceOffer() {
|
||||
void onPlaceOffer() {
|
||||
model.requestPlaceOfferErrorMessage.set(null);
|
||||
model.requestPlaceOfferSuccess.set(false);
|
||||
|
||||
|
@ -190,12 +190,12 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
// UI events
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onShowPayFundsScreen() {
|
||||
void onShowPayFundsScreen() {
|
||||
isPlaceOfferButtonVisible.set(true);
|
||||
}
|
||||
|
||||
// On focus out we do validation and apply the data to the model
|
||||
public void onFocusOutAmountTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
void onFocusOutAmountTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isBtcInputValid(amount.get());
|
||||
amountValidationResult.set(result);
|
||||
|
@ -222,7 +222,7 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
}
|
||||
}
|
||||
|
||||
public void onFocusOutMinAmountTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
void onFocusOutMinAmountTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isBtcInputValid(minAmount.get());
|
||||
minAmountValidationResult.set(result);
|
||||
|
@ -244,7 +244,7 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
}
|
||||
}
|
||||
|
||||
public void onFocusOutPriceTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
void onFocusOutPriceTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isFiatInputValid(price.get());
|
||||
boolean isValid = result.isValid;
|
||||
|
@ -259,7 +259,7 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
}
|
||||
}
|
||||
|
||||
public void onFocusOutVolumeTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
void onFocusOutVolumeTextField(Boolean oldValue, Boolean newValue, String userInput) {
|
||||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isBtcInputValid(volume.get());
|
||||
volumeValidationResult.set(result);
|
||||
|
@ -283,7 +283,7 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public WalletFacade getWalletFacade() {
|
||||
WalletFacade getWalletFacade() {
|
||||
return model.getWalletFacade();
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,6 @@ public class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setupListeners() {
|
||||
|
||||
// Bidirectional bindings are used for all input fields: amount, price, volume and minAmount
|
||||
// We do volume/amount calculation during input, so user has immediate feedback
|
||||
amount.addListener((ov, oldValue, newValue) -> {
|
||||
|
|
|
@ -47,19 +47,6 @@
|
|||
<TitledGroupBg fx:id="priceAmountPane" text="%createOffer.amountPriceBox.title"
|
||||
GridPane.rowSpan="3" GridPane.columnSpan="3"/>
|
||||
|
||||
<!-- <Pane fx:id="priceAmountPane" id="form-group-background-active" GridPane.columnSpan="3"
|
||||
GridPane.rowSpan="3">
|
||||
<GridPane.margin>
|
||||
<Insets right="-10" bottom="-10" left="-10" top="-10"/>
|
||||
</GridPane.margin>
|
||||
<Label fx:id="priceAmountTitleLabel" id="form-group-title-active"
|
||||
text="%createOffer.amountPriceBox.title" layoutX="8" layoutY="-8">
|
||||
<padding>
|
||||
<Insets left="5" right="7"/>
|
||||
</padding>
|
||||
</Label>
|
||||
</Pane> -->
|
||||
|
||||
<VBox alignment="CENTER" spacing="6" GridPane.rowSpan="2">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0"/>
|
||||
|
@ -141,7 +128,7 @@
|
|||
</HBox>
|
||||
</VBox>
|
||||
|
||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2" prefWidth="740"
|
||||
text="%createOffer.amountPriceBox.info"/>
|
||||
|
||||
<Button fx:id="showPaymentInfoScreenButton" text="%createOffer.amountPriceBox.next" id="show-details-button"
|
||||
|
@ -158,19 +145,6 @@
|
|||
<TitledGroupBg fx:id="payFundsPane" text="%createOffer.fundsBox.title" GridPane.rowIndex="4"
|
||||
GridPane.rowSpan="4" GridPane.columnSpan="3" visible="false"/>
|
||||
|
||||
<!-- <Pane fx:id="payFundsPane" id="form-group-background-active" GridPane.columnSpan="3"
|
||||
GridPane.rowIndex="4" GridPane.rowSpan="4" visible="false">
|
||||
<GridPane.margin>
|
||||
<Insets right="-10" bottom="-10" left="-10" top="-10"/>
|
||||
</GridPane.margin>
|
||||
<Label fx:id="payFundsTitleLabel" text="%createOffer.fundsBox.title" id="form-group-title-active"
|
||||
layoutX="8" layoutY="-8">
|
||||
<padding>
|
||||
<Insets left="5" right="7"/>
|
||||
</padding>
|
||||
</Label>
|
||||
</Pane> -->
|
||||
|
||||
<HBox GridPane.rowIndex="4" spacing="4" alignment="CENTER_RIGHT">
|
||||
<Label fx:id="totalToPayLabel" text="%createOffer.fundsBox.totalsNeeded" visible="false"/>
|
||||
<Label fx:id="totalToPayInfoIconLabel" visible="false"/>
|
||||
|
@ -204,17 +178,17 @@
|
|||
</BalanceTextField>
|
||||
|
||||
<InfoDisplay fx:id="fundsBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenFundingHelp" rowIndex="7"
|
||||
text="%createOffer.fundsBox.info" visible="false"/>
|
||||
text="%createOffer.fundsBox.info" visible="false" prefWidth="740"/>
|
||||
|
||||
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="30" top="15.0"/>
|
||||
</GridPane.margin>
|
||||
<Button fx:id="showAdvancedSettingsButton" text="%createOffer.fundsBox.showAdvanced"
|
||||
onAction="#onToggleShowAdvancedSettings" visible="false"/>
|
||||
<Button fx:id="placeOfferButton" text="%createOffer.fundsBox.placeOffer" visible="false"
|
||||
defaultButton="true"
|
||||
onAction="#onPlaceOffer"/>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="30" top="15.0"/>
|
||||
</GridPane.margin>
|
||||
</HBox>
|
||||
|
||||
<!--
|
||||
|
@ -286,7 +260,7 @@
|
|||
</TextField>
|
||||
|
||||
<InfoDisplay fx:id="advancedInfoDisplay" gridPane="$gridPane" onAction="#onOpenAdvancedSettingsHelp"
|
||||
rowIndex="15" visible="false"
|
||||
rowIndex="15" visible="false" prefWidth="740"
|
||||
text="%createOffer.advancedBox.info">
|
||||
</InfoDisplay>
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package io.bitsquare.gui.main.trade.createoffer;
|
||||
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.gui.CloseListener;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.gui.NavigationItem;
|
||||
import io.bitsquare.gui.OverlayController;
|
||||
|
@ -38,7 +39,6 @@ import java.net.URL;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -76,32 +76,32 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
|
||||
private NavigationController navigationController;
|
||||
private OverlayController overlayController;
|
||||
private CloseListener closeListener;
|
||||
|
||||
private boolean detailsVisible;
|
||||
private boolean advancedScreenInited;
|
||||
private Callable<Void> onCloseCallable;
|
||||
|
||||
private ImageView expand;
|
||||
private ImageView collapse;
|
||||
private PopOver totalToPayInfoPopover;
|
||||
|
||||
@FXML private InfoDisplay advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||
@FXML private ScrollPane scrollPane;
|
||||
@FXML private TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
||||
@FXML private Label buyLabel, addressLabel,
|
||||
@FXML InfoDisplay advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||
@FXML ScrollPane scrollPane;
|
||||
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
||||
@FXML Label buyLabel, addressLabel,
|
||||
balanceLabel, totalToPayLabel, totalToPayInfoIconLabel,
|
||||
bankAccountTypeLabel, bankAccountCurrencyLabel, bankAccountCountyLabel,
|
||||
acceptedCountriesLabel, acceptedCountriesLabelIcon, acceptedLanguagesLabel, acceptedLanguagesLabelIcon,
|
||||
acceptedArbitratorsLabel, acceptedArbitratorsLabelIcon, amountBtcLabel,
|
||||
priceFiatLabel, volumeFiatLabel, minAmountBtcLabel, priceDescriptionLabel, volumeDescriptionLabel;
|
||||
@FXML private Button showPaymentInfoScreenButton, showAdvancedSettingsButton, placeOfferButton;
|
||||
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, placeOfferButton;
|
||||
|
||||
@FXML private InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
|
||||
@FXML private TextField acceptedArbitratorsTextField, totalToPayTextField, bankAccountTypeTextField,
|
||||
@FXML InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
|
||||
@FXML TextField acceptedArbitratorsTextField, totalToPayTextField, bankAccountTypeTextField,
|
||||
bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField,
|
||||
acceptedLanguagesTextField;
|
||||
@FXML private AddressTextField addressTextField;
|
||||
@FXML private BalanceTextField balanceTextField;
|
||||
@FXML AddressTextField addressTextField;
|
||||
@FXML BalanceTextField balanceTextField;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -147,14 +147,8 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
|
||||
// Inform parent that we gor removed.
|
||||
// Needed to reset disable state of createOfferButton in OrderBookController
|
||||
if (onCloseCallable != null) {
|
||||
try {
|
||||
onCloseCallable.call();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
if (closeListener != null)
|
||||
closeListener.onClosed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,22 +156,25 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
// Public methods (called form other views/CB)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setOrderBookFilter(OrderBookInfo orderBookInfo) {
|
||||
public void initWithOrderBookInfo(OrderBookInfo orderBookInfo) {
|
||||
presentationModel.setOrderBookFilter(orderBookInfo);
|
||||
}
|
||||
|
||||
public void setCloseListener(CloseListener closeListener) {
|
||||
this.closeListener = closeListener;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// UI Handlers
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@FXML
|
||||
private void onPlaceOffer() {
|
||||
void onPlaceOffer() {
|
||||
presentationModel.onPlaceOffer();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onShowPayFundsScreen() {
|
||||
void onShowPayFundsScreen() {
|
||||
priceAmountPane.setInactive();
|
||||
|
||||
showPaymentInfoScreenButton.setVisible(false);
|
||||
|
@ -205,7 +202,7 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
}
|
||||
|
||||
@FXML
|
||||
private void onToggleShowAdvancedSettings() {
|
||||
void onToggleShowAdvancedSettings() {
|
||||
detailsVisible = !detailsVisible;
|
||||
if (detailsVisible) {
|
||||
showAdvancedSettingsButton.setText(BSResources.get("createOffer.fundsBox.hideAdvanced"));
|
||||
|
@ -220,17 +217,17 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
}
|
||||
|
||||
@FXML
|
||||
private void onOpenGeneralHelp() {
|
||||
void onOpenGeneralHelp() {
|
||||
Help.openWindow(HelpId.CREATE_OFFER_GENERAL);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onOpenFundingHelp() {
|
||||
void onOpenFundingHelp() {
|
||||
Help.openWindow(HelpId.CREATE_OFFER_FUNDING);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onOpenAdvancedSettingsHelp() {
|
||||
void onOpenAdvancedSettingsHelp() {
|
||||
Help.openWindow(HelpId.CREATE_OFFER_ADVANCED);
|
||||
}
|
||||
|
||||
|
@ -359,9 +356,11 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
volumeDescriptionLabel.textProperty().bind(presentationModel.fiatCode);//Price per Bitcoin in EUR
|
||||
|
||||
priceDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("createOffer.amountPriceBox.priceDescr", presentationModel.fiatCode.get())));
|
||||
BSResources.get("createOffer.amountPriceBox.priceDescr", presentationModel.fiatCode.get()),
|
||||
presentationModel.fiatCode));
|
||||
volumeDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("createOffer.amountPriceBox.volumeDescr", presentationModel.fiatCode.get())));
|
||||
BSResources.get("createOffer.amountPriceBox.volumeDescr", presentationModel.fiatCode.get()),
|
||||
presentationModel.fiatCode));
|
||||
|
||||
buyLabel.textProperty().bind(presentationModel.directionLabel);
|
||||
|
||||
|
@ -527,9 +526,5 @@ public class CreateOfferViewCB extends CachedViewCB<CreateOfferPM> {
|
|||
double y = point.getY() + window.getY() + Math.floor(totalToPayInfoIconLabel.getHeight() / 2) - 9;
|
||||
return new Point2D(x, y);
|
||||
}
|
||||
|
||||
public void setOnClose(Callable<Void> onCloseCallBack) {
|
||||
this.onCloseCallable = onCloseCallBack;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,55 +17,48 @@
|
|||
|
||||
package io.bitsquare.gui.main.trade.orderbook;
|
||||
|
||||
import io.bitsquare.arbitrator.Arbitrator;
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.gui.main.trade.OrderBookInfo;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.msg.MessageFacade;
|
||||
import io.bitsquare.msg.listeners.OrderBookListener;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
import java.io.IOException;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
|
||||
import net.tomp2p.peers.Number640;
|
||||
import net.tomp2p.storage.Data;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/*
|
||||
TODO move to OrderBookModel when converted to new UI structure
|
||||
remove dependencies to tomp2p
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.storage.Data;
|
||||
*/
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* Holds and manages the unsorted and unfiltered orderbook list of both buy and sell offers.
|
||||
* As it is used only by the Buy and Sell UIs we treat it as local UI model.
|
||||
*/
|
||||
public class OrderBook {
|
||||
|
||||
public class OrderBook implements OrderBookListener {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderBook.class);
|
||||
private final ObservableList<OrderBookListItem> allOffers = FXCollections.observableArrayList();
|
||||
private final FilteredList<OrderBookListItem> filteredList = new FilteredList<>(allOffers);
|
||||
// FilteredList does not support sorting, so we need to wrap it to a SortedList
|
||||
private final SortedList<OrderBookListItem> offerList = new SortedList<>(filteredList);
|
||||
private final Settings settings;
|
||||
private final User user;
|
||||
|
||||
private final MessageFacade messageFacade;
|
||||
private final TradeManager tradeManager;
|
||||
private final User user;
|
||||
|
||||
private final ObservableList<OrderBookListItem> orderBookListItems = FXCollections.observableArrayList();
|
||||
private final OrderBookListener orderBookListener;
|
||||
private final ChangeListener<BankAccount> bankAccountChangeListener;
|
||||
private final ChangeListener<Boolean> dirtyListener;
|
||||
private String fiatCode;
|
||||
private AnimationTimer pollingTimer;
|
||||
private Country country;
|
||||
private int numClients = 0;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -73,143 +66,48 @@ public class OrderBook implements OrderBookListener {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public OrderBook(Settings settings, User user, MessageFacade messageFacade, TradeManager tradeManager) {
|
||||
this.settings = settings;
|
||||
this.user = user;
|
||||
public OrderBook(MessageFacade messageFacade, User user) {
|
||||
this.messageFacade = messageFacade;
|
||||
this.tradeManager = tradeManager;
|
||||
this.user = user;
|
||||
|
||||
bankAccountChangeListener = (observableValue, oldValue, newValue) -> setBankAccount(newValue);
|
||||
dirtyListener = (ov, oldValue, newValue) -> requestOffers();
|
||||
orderBookListener = new OrderBookListener() {
|
||||
@Override
|
||||
public void onOfferAdded(Offer offer) {
|
||||
addOfferToOrderBookListItems(offer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffersReceived(List<Offer> offers) {
|
||||
//TODO use deltas instead replacing the whole list
|
||||
orderBookListItems.clear();
|
||||
offers.stream().forEach(offer -> addOfferToOrderBookListItems(offer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOfferRemoved(Offer offer) {
|
||||
orderBookListItems.removeIf(item -> item.getOffer().equals(offer));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public API
|
||||
// Package scope
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void init() {
|
||||
messageFacade.addOrderBookListener(this);
|
||||
void addClient() {
|
||||
numClients++;
|
||||
if (numClients == 1)
|
||||
startPolling();
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
messageFacade.removeOrderBookListener(this);
|
||||
}
|
||||
|
||||
public void loadOffers() {
|
||||
if (user.getCurrentBankAccount() != null) {
|
||||
messageFacade.getOffers(user.getCurrentBankAccount().getCurrency().getCurrencyCode());
|
||||
}
|
||||
else {
|
||||
messageFacade.getOffers(CurrencyUtil.getDefaultCurrency().getCurrencyCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeOffer(Offer offer) {
|
||||
tradeManager.removeOffer(offer);
|
||||
}
|
||||
|
||||
public void applyFilter(OrderBookInfo orderBookInfo) {
|
||||
filteredList.setPredicate(orderBookListItem -> {
|
||||
Offer offer = orderBookListItem.getOffer();
|
||||
BankAccount currentBankAccount = user.getCurrentBankAccount();
|
||||
|
||||
if (orderBookInfo == null || currentBankAccount == null || orderBookInfo.getDirection() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The users current bank account currency must match the offer currency (1 to 1)
|
||||
boolean currencyResult = currentBankAccount.getCurrency().equals(offer.getCurrency());
|
||||
|
||||
// The offer bank account country must match one of the accepted countries defined in the settings (1 to n)
|
||||
boolean countryResult = countryInList(offer.getBankAccountCountry(), settings.getAcceptedCountries());
|
||||
|
||||
// One of the supported languages from the settings must match one of the offer languages (n to n)
|
||||
boolean languageResult =
|
||||
languagesInList(settings.getAcceptedLanguageLocales(), offer.getAcceptedLanguageLocales());
|
||||
|
||||
// Apply applyFilter only if there is a valid value set
|
||||
// The requested amount must be lower or equal then the offer amount
|
||||
boolean amountResult = true;
|
||||
if (orderBookInfo.getAmount() != null)
|
||||
amountResult = orderBookInfo.getAmount().compareTo(offer.getAmount()) <= 0;
|
||||
|
||||
// The requested trade direction must be opposite of the offerList trade direction
|
||||
boolean directionResult = !orderBookInfo.getDirection().equals(offer.getDirection());
|
||||
|
||||
// Apply applyFilter only if there is a valid value set
|
||||
boolean priceResult = true;
|
||||
if (orderBookInfo.getPrice() != null) {
|
||||
if (offer.getDirection() == Direction.SELL)
|
||||
priceResult = orderBookInfo.getPrice().compareTo(offer.getPrice()) >= 0;
|
||||
else
|
||||
priceResult = orderBookInfo.getPrice().compareTo(offer.getPrice()) <= 0;
|
||||
}
|
||||
|
||||
// The arbitrator defined in the offer must match one of the accepted arbitrators defined in the settings
|
||||
// (1 to n)
|
||||
boolean arbitratorResult = arbitratorsInList(offer.getArbitrators(), settings.getAcceptedArbitrators());
|
||||
|
||||
boolean result = currencyResult && countryResult && languageResult && amountResult && directionResult &&
|
||||
priceResult && arbitratorResult;
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: MessageListener
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void onOfferAdded(Data offerData, boolean success) {
|
||||
try {
|
||||
Object offerDataObject = offerData.object();
|
||||
if (offerDataObject instanceof Offer) {
|
||||
Offer offer = (Offer) offerDataObject;
|
||||
allOffers.add(new OrderBookListItem(offer));
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffersReceived(Map<Number640, Data> dataMap, boolean success) {
|
||||
if (success && dataMap != null) {
|
||||
allOffers.clear();
|
||||
|
||||
for (Data offerData : dataMap.values()) {
|
||||
try {
|
||||
Object offerDataObject = offerData.object();
|
||||
if (offerDataObject instanceof Offer) {
|
||||
Offer offer = (Offer) offerDataObject;
|
||||
OrderBookListItem orderBookListItem = new OrderBookListItem(offer);
|
||||
allOffers.add(orderBookListItem);
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
allOffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOfferRemoved(Data offerData, boolean success) {
|
||||
if (success && offerData != null) {
|
||||
try {
|
||||
Object offerDataObject = offerData.object();
|
||||
if (offerDataObject instanceof Offer) {
|
||||
Offer offer = (Offer) offerDataObject;
|
||||
allOffers.removeIf(orderBookListItem -> orderBookListItem.getOffer().getId().equals(offer.getId()));
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("onOfferRemoved failed");
|
||||
}
|
||||
void removeClient() {
|
||||
numClients--;
|
||||
checkArgument(numClients >= 0);
|
||||
if (numClients == 0)
|
||||
stopPolling();
|
||||
}
|
||||
|
||||
|
||||
|
@ -217,46 +115,69 @@ public class OrderBook implements OrderBookListener {
|
|||
// Getter
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public SortedList<OrderBookListItem> getOfferList() {
|
||||
return offerList;
|
||||
ObservableList<OrderBookListItem> getOrderBookListItems() {
|
||||
return orderBookListItems;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private Methods
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private boolean countryInList(Country countryToMatch, List<Country> list) {
|
||||
for (Country country : list) {
|
||||
if (country.getCode().equals(countryToMatch.getCode())) {
|
||||
return true;
|
||||
}
|
||||
private void setBankAccount(BankAccount bankAccount) {
|
||||
log.debug("setBankAccount " + bankAccount);
|
||||
if (bankAccount != null) {
|
||||
country = bankAccount.getCountry();
|
||||
fiatCode = bankAccount.getCurrency().getCurrencyCode();
|
||||
orderBookListItems.stream().forEach(e -> e.setBankAccountCountry(country));
|
||||
}
|
||||
else {
|
||||
fiatCode = CurrencyUtil.getDefaultCurrency().getCurrencyCode();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean languagesInList(List<Locale> list1, List<Locale> list2) {
|
||||
for (Locale locale1 : list2) {
|
||||
for (Locale locale2 : list1) {
|
||||
if (locale1.getLanguage().equals(locale2.getLanguage())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
private void addListeners() {
|
||||
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
|
||||
messageFacade.addOrderBookListener(orderBookListener);
|
||||
messageFacade.getIsDirtyProperty().addListener(dirtyListener);
|
||||
}
|
||||
|
||||
private boolean arbitratorsInList(List<Arbitrator> list1, List<Arbitrator> list2) {
|
||||
for (Arbitrator arbitrator1 : list2) {
|
||||
for (Arbitrator arbitrator2 : list1) {
|
||||
if (arbitrator1.getId().equals(arbitrator2.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
private void removeListeners() {
|
||||
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
|
||||
messageFacade.removeOrderBookListener(orderBookListener);
|
||||
messageFacade.getIsDirtyProperty().removeListener(dirtyListener);
|
||||
}
|
||||
|
||||
private void addOfferToOrderBookListItems(Offer offer) {
|
||||
if (offer != null) {
|
||||
orderBookListItems.add(new OrderBookListItem(offer, country));
|
||||
}
|
||||
}
|
||||
|
||||
private void requestOffers() {
|
||||
messageFacade.getOffers(fiatCode);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Polling
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO Just temporary, will be removed later when we have a push solution
|
||||
private void startPolling() {
|
||||
addListeners();
|
||||
setBankAccount(user.getCurrentBankAccount());
|
||||
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
|
||||
messageFacade.getDirtyFlag(fiatCode);
|
||||
return null;
|
||||
});
|
||||
|
||||
messageFacade.getOffers(fiatCode);
|
||||
}
|
||||
|
||||
private void stopPolling() {
|
||||
pollingTimer.stop();
|
||||
removeListeners();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,49 +17,52 @@
|
|||
|
||||
package io.bitsquare.gui.main.trade.orderbook;
|
||||
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.trade.Offer;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
public class OrderBookListItem {
|
||||
private final StringProperty price = new SimpleStringProperty();
|
||||
private final StringProperty amount = new SimpleStringProperty();
|
||||
private final StringProperty volume = new SimpleStringProperty();
|
||||
|
||||
|
||||
private final Offer offer;
|
||||
private final ObjectProperty<Country> bankAccountCountry = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
public OrderBookListItem(Offer offer) {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public OrderBookListItem(Offer offer, Country bankAccountCountry) {
|
||||
this.offer = offer;
|
||||
this.price.set(BSFormatter.formatFiat(offer.getPrice()));
|
||||
this.price.set(BSFormatter.formatFiat(offer.getPrice()));
|
||||
this.amount.set(BSFormatter.formatCoin(
|
||||
offer.getAmount()) + " (" + BSFormatter.formatCoin(offer.getMinAmount()) + ")");
|
||||
this.volume.set(BSFormatter.formatVolumeWithMinVolume(
|
||||
offer.getOfferVolume(), offer.getMinOfferVolume()));
|
||||
setBankAccountCountry(bankAccountCountry);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setBankAccountCountry(Country bankAccountCountry) {
|
||||
this.bankAccountCountry.set(bankAccountCountry);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Offer getOffer() {
|
||||
return offer;
|
||||
}
|
||||
|
||||
// called form table columns
|
||||
public Country getBankAccountCountry() {
|
||||
return bankAccountCountry.get();
|
||||
}
|
||||
|
||||
public final StringProperty priceProperty() {
|
||||
return this.price;
|
||||
public ObjectProperty<Country> bankAccountCountryProperty() {
|
||||
return bankAccountCountry;
|
||||
}
|
||||
|
||||
|
||||
public final StringProperty amountProperty() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
|
||||
public final StringProperty volumeProperty() {
|
||||
return this.volume;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,23 +17,120 @@
|
|||
|
||||
package io.bitsquare.gui.main.trade.orderbook;
|
||||
|
||||
import io.bitsquare.arbitrator.Arbitrator;
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.gui.UIModel;
|
||||
import io.bitsquare.gui.main.trade.OrderBookInfo;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.utils.ExchangeRate;
|
||||
import com.google.bitcoin.utils.Fiat;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.gui.util.BSFormatter.reduceTo4Decimals;
|
||||
|
||||
public class OrderBookModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderBookModel.class);
|
||||
|
||||
private final User user;
|
||||
private final OrderBook orderBook;
|
||||
private final Settings settings;
|
||||
private final TradeManager tradeManager;
|
||||
|
||||
private final FilteredList<OrderBookListItem> filteredItems;
|
||||
private final SortedList<OrderBookListItem> sortedItems;
|
||||
private OrderBookInfo orderBookInfo;
|
||||
private final ChangeListener<BankAccount> bankAccountChangeListener;
|
||||
|
||||
private final ObjectProperty<Coin> amountAsCoin = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<Fiat> priceAsFiat = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<Fiat> volumeAsFiat = new SimpleObjectProperty<>();
|
||||
|
||||
final StringProperty restrictionsInfo = new SimpleStringProperty();
|
||||
final StringProperty fiatCode = new SimpleStringProperty();
|
||||
final StringProperty btcCode = new SimpleStringProperty();
|
||||
final ObjectProperty<Country> bankAccountCountry = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Comparator<OrderBookListItem>> comparator = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public OrderBookModel() {
|
||||
public OrderBookModel(User user,
|
||||
TradeManager tradeManager,
|
||||
OrderBook orderBook,
|
||||
Settings settings) {
|
||||
this.tradeManager = tradeManager;
|
||||
this.user = user;
|
||||
this.orderBook = orderBook;
|
||||
this.settings = settings;
|
||||
|
||||
filteredItems = new FilteredList<>(orderBook.getOrderBookListItems());
|
||||
sortedItems = new SortedList<>(filteredItems);
|
||||
bankAccountChangeListener = (observableValue, oldValue, newValue) -> setBankAccount(newValue);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
orderBook.addClient();
|
||||
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
|
||||
btcCode.bind(settings.btcDenominationProperty());
|
||||
|
||||
setBankAccount(user.getCurrentBankAccount());
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
orderBook.removeClient();
|
||||
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
|
||||
btcCode.unbind();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,20 +138,226 @@ public class OrderBookModel extends UIModel {
|
|||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setOrderBookInfo(OrderBookInfo orderBookInfo) {
|
||||
this.orderBookInfo = orderBookInfo;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
void removeOffer(Offer offer) {
|
||||
tradeManager.removeOffer(offer);
|
||||
}
|
||||
|
||||
void calculateVolume() {
|
||||
try {
|
||||
if (priceAsFiat.get() != null &&
|
||||
amountAsCoin.get() != null &&
|
||||
!amountAsCoin.get().isZero() &&
|
||||
!priceAsFiat.get().isZero()) {
|
||||
volumeAsFiat.set(new ExchangeRate(priceAsFiat.get()).coinToFiat(amountAsCoin.get()));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Should be never reached
|
||||
log.error(t.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void calculateAmount() {
|
||||
try {
|
||||
if (volumeAsFiat.get() != null &&
|
||||
priceAsFiat.get() != null &&
|
||||
!volumeAsFiat.get().isZero() &&
|
||||
!priceAsFiat.get().isZero()) {
|
||||
// If we got a btc value with more then 4 decimals we convert it to max 4 decimals
|
||||
amountAsCoin.set(reduceTo4Decimals(new ExchangeRate(priceAsFiat.get()).fiatToCoin(volumeAsFiat.get())));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Should be never reached
|
||||
log.error(t.toString());
|
||||
}
|
||||
}
|
||||
|
||||
boolean isTradable(Offer offer) {
|
||||
log.debug("### isMatchingRestrictions " + offer);
|
||||
// if user has not registered yet we display all
|
||||
if (user.getCurrentBankAccount() == null)
|
||||
return true;
|
||||
|
||||
|
||||
boolean countryResult = offer.getAcceptedCountries().contains(user.getCurrentBankAccount().getCountry());
|
||||
if (!countryResult)
|
||||
restrictionsInfo.set("This offer requires that the payments account resides in one of those countries:\n" +
|
||||
BSFormatter.countryLocalesToString(offer.getAcceptedCountries()) +
|
||||
"\n\nThe country of your payments account (" + user.getCurrentBankAccount().getCountry().getName() +
|
||||
") is not included in that list.");
|
||||
//TODO
|
||||
|
||||
// One of the supported languages from the settings must match one of the offer languages (n to n)
|
||||
/* boolean languageResult =
|
||||
languagesInList(settings.getAcceptedLanguageLocales(), offer.getAcceptedLanguageLocales());
|
||||
|
||||
// Apply applyFilter only if there is a valid value set
|
||||
// The requested amount must be lower or equal then the offer amount
|
||||
boolean amountResult = true;
|
||||
if (orderBookInfo.getAmount() != null && orderBookInfo.getAmount().isPositive())
|
||||
amountResult = orderBookInfo.getAmount().compareTo(offer.getAmount()) <= 0;
|
||||
|
||||
|
||||
// Apply applyFilter only if there is a valid value set
|
||||
boolean priceResult = true;
|
||||
if (orderBookInfo.getPrice() != null && orderBookInfo.getPrice().isPositive()) {
|
||||
if (offer.getDirection() == Direction.SELL)
|
||||
priceResult = orderBookInfo.getPrice().compareTo(offer.getPrice()) >= 0;
|
||||
else
|
||||
priceResult = orderBookInfo.getPrice().compareTo(offer.getPrice()) <= 0;
|
||||
}
|
||||
|
||||
// The arbitrator defined in the offer must match one of the accepted arbitrators defined in the settings
|
||||
// (1 to n)
|
||||
boolean arbitratorResult = arbitratorsInList(offer.getArbitrators(), settings.getAcceptedArbitrators());
|
||||
|
||||
boolean result = countryResult && languageResult && amountResult && priceResult && arbitratorResult;
|
||||
|
||||
log.debug("getPrice " + orderBookInfo.getPrice());
|
||||
log.debug("getAmount " + orderBookInfo.getAmount());
|
||||
log.debug("countryResult " + countryResult);
|
||||
log.debug("languageResult " + languageResult);
|
||||
log.debug("amountResult " + amountResult);
|
||||
log.debug("priceResult " + priceResult);
|
||||
log.debug("arbitratorResult " + arbitratorResult);
|
||||
log.debug("Offer filter result " + result);*/
|
||||
|
||||
return countryResult;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setAmount(Coin amount) {
|
||||
amountAsCoin.set(amount);
|
||||
orderBookInfo.setAmount(amount);
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
void setPrice(Fiat price) {
|
||||
priceAsFiat.set(price);
|
||||
orderBookInfo.setPrice(price);
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
void setVolume(Fiat volume) {
|
||||
volumeAsFiat.set(volume);
|
||||
orderBookInfo.setVolume(volume);
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SortedList<OrderBookListItem> getOfferList() {
|
||||
return sortedItems;
|
||||
}
|
||||
|
||||
boolean isRegistered() {
|
||||
return user.getAccountId() != null;
|
||||
}
|
||||
|
||||
boolean isMyOffer(Offer offer) {
|
||||
return offer.getMessagePublicKey() != null ?
|
||||
offer.getMessagePublicKey().equals(user.getMessagePublicKey()) : false;
|
||||
}
|
||||
|
||||
Coin getAmountAsCoin() {
|
||||
return amountAsCoin.get();
|
||||
}
|
||||
|
||||
ObjectProperty<Coin> amountAsCoinProperty() {
|
||||
return amountAsCoin;
|
||||
}
|
||||
|
||||
Fiat getPriceAsFiat() {
|
||||
return priceAsFiat.get();
|
||||
}
|
||||
|
||||
ObjectProperty<Fiat> priceAsFiatProperty() {
|
||||
return priceAsFiat;
|
||||
}
|
||||
|
||||
Fiat getVolumeAsFiat() {
|
||||
return volumeAsFiat.get();
|
||||
}
|
||||
|
||||
ObjectProperty<Fiat> volumeAsFiatProperty() {
|
||||
return volumeAsFiat;
|
||||
}
|
||||
|
||||
OrderBookInfo getOrderBookInfo() {
|
||||
return orderBookInfo;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setBankAccount(BankAccount bankAccount) {
|
||||
if (bankAccount != null) {
|
||||
fiatCode.set(bankAccount.getCurrency().getCurrencyCode());
|
||||
bankAccountCountry.set(bankAccount.getCountry());
|
||||
sortedItems.stream().forEach(e -> e.setBankAccountCountry(bankAccount.getCountry()));
|
||||
}
|
||||
else {
|
||||
fiatCode.set(CurrencyUtil.getDefaultCurrency().getCurrencyCode());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean languagesInList(List<Locale> list1, List<Locale> list2) {
|
||||
for (Locale locale1 : list2) {
|
||||
for (Locale locale2 : list1) {
|
||||
if (locale1.getLanguage().equals(locale2.getLanguage())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean arbitratorsInList(List<Arbitrator> list1, List<Arbitrator> list2) {
|
||||
for (Arbitrator arbitrator1 : list2) {
|
||||
for (Arbitrator arbitrator2 : list1) {
|
||||
if (arbitrator1.getId().equals(arbitrator2.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void applyFilter() {
|
||||
filteredItems.setPredicate(orderBookListItem -> {
|
||||
Offer offer = orderBookListItem.getOffer();
|
||||
|
||||
boolean directionResult = offer.getDirection() != orderBookInfo.getDirection();
|
||||
|
||||
boolean amountResult = true;
|
||||
if (orderBookInfo.getAmount() != null && orderBookInfo.getAmount().isPositive())
|
||||
amountResult = orderBookInfo.getAmount().compareTo(offer.getAmount()) <= 0;
|
||||
|
||||
boolean priceResult = true;
|
||||
if (orderBookInfo.getPrice() != null && orderBookInfo.getPrice().isPositive()) {
|
||||
if (offer.getDirection() == Direction.SELL)
|
||||
priceResult = orderBookInfo.getPrice().compareTo(offer.getPrice()) >= 0;
|
||||
else
|
||||
priceResult = orderBookInfo.getPrice().compareTo(offer.getPrice()) <= 0;
|
||||
}
|
||||
|
||||
|
||||
//TODO
|
||||
|
||||
return directionResult && amountResult && priceResult;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,22 +18,123 @@
|
|||
package io.bitsquare.gui.main.trade.orderbook;
|
||||
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
import io.bitsquare.gui.main.trade.OrderBookInfo;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.validation.InputValidator;
|
||||
import io.bitsquare.gui.util.validation.OptionalBtcValidator;
|
||||
import io.bitsquare.gui.util.validation.OptionalFiatValidator;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.trade.Offer;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.gui.util.BSFormatter.*;
|
||||
|
||||
public class OrderBookPM extends PresentationModel<OrderBookModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderBookPM.class);
|
||||
|
||||
private final OptionalBtcValidator optionalBtcValidator;
|
||||
private final OptionalFiatValidator optionalFiatValidator;
|
||||
|
||||
final StringProperty amount = new SimpleStringProperty();
|
||||
final StringProperty price = new SimpleStringProperty();
|
||||
final StringProperty volume = new SimpleStringProperty();
|
||||
final StringProperty btcCode = new SimpleStringProperty();
|
||||
final StringProperty fiatCode = new SimpleStringProperty();
|
||||
final ObjectProperty<Country> bankAccountCountry = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Comparator<OrderBookListItem>> comparator = new SimpleObjectProperty<>();
|
||||
final StringProperty restrictionsInfo = new SimpleStringProperty();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public OrderBookPM(OrderBookModel model) {
|
||||
public OrderBookPM(OrderBookModel model,
|
||||
OptionalFiatValidator optionalFiatValidator,
|
||||
OptionalBtcValidator optionalBtcValidator) {
|
||||
super(model);
|
||||
|
||||
this.optionalFiatValidator = optionalFiatValidator;
|
||||
this.optionalBtcValidator = optionalBtcValidator;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
|
||||
btcCode.bind(model.btcCode);
|
||||
fiatCode.bind(model.fiatCode);
|
||||
bankAccountCountry.bind(model.bankAccountCountry);
|
||||
restrictionsInfo.bind(model.restrictionsInfo);
|
||||
comparator.bind(model.comparator);
|
||||
|
||||
// Bidirectional bindings are used for all input fields: amount, price and volume
|
||||
// We do volume/amount calculation during input, so user has immediate feedback
|
||||
amount.addListener((ov, oldValue, newValue) -> {
|
||||
if (isBtcInputValid(newValue).isValid) {
|
||||
setAmountToModel();
|
||||
setPriceToModel();
|
||||
model.calculateVolume();
|
||||
}
|
||||
});
|
||||
|
||||
price.addListener((ov, oldValue, newValue) -> {
|
||||
if (isFiatInputValid(newValue).isValid) {
|
||||
setAmountToModel();
|
||||
setPriceToModel();
|
||||
model.calculateVolume();
|
||||
}
|
||||
});
|
||||
|
||||
volume.addListener((ov, oldValue, newValue) -> {
|
||||
if (isFiatInputValid(newValue).isValid) {
|
||||
setPriceToModel();
|
||||
setVolumeToModel();
|
||||
model.calculateAmount();
|
||||
}
|
||||
});
|
||||
|
||||
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
|
||||
model.amountAsCoinProperty().addListener((ov, oldValue, newValue) -> amount.set(formatCoin(newValue)));
|
||||
model.priceAsFiatProperty().addListener((ov, oldValue, newValue) -> price.set(formatFiat(newValue)));
|
||||
model.volumeAsFiatProperty().addListener((ov, oldValue, newValue) -> volume.set(formatFiat(newValue)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,20 +142,95 @@ public class OrderBookPM extends PresentationModel<OrderBookModel> {
|
|||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setOrderBookInfo(OrderBookInfo orderBookInfo) {
|
||||
model.setOrderBookInfo(orderBookInfo);
|
||||
}
|
||||
|
||||
void removeOffer(Offer offer) {
|
||||
model.removeOffer(offer);
|
||||
}
|
||||
|
||||
boolean isTradable(Offer offer) {
|
||||
return model.isTradable(offer);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SortedList<OrderBookListItem> getOfferList() {
|
||||
return model.getOfferList();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
StringProperty getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
StringProperty getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
StringProperty getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
boolean isRegistered() {
|
||||
return model.isRegistered();
|
||||
}
|
||||
|
||||
boolean isMyOffer(Offer offer) {
|
||||
return model.isMyOffer(offer);
|
||||
}
|
||||
|
||||
String getAmount(OrderBookListItem item) {
|
||||
return (item != null) ? BSFormatter.formatCoin(item.getOffer().getAmount()) : "";
|
||||
}
|
||||
|
||||
String getPrice(OrderBookListItem item) {
|
||||
return (item != null) ? BSFormatter.formatFiat(item.getOffer().getPrice()) : "";
|
||||
}
|
||||
|
||||
String getVolume(OrderBookListItem item) {
|
||||
return (item != null) ? BSFormatter.formatFiat(item.getOffer().getOfferVolume()) : "";
|
||||
}
|
||||
|
||||
String getBankAccountType(OrderBookListItem item) {
|
||||
return (item != null) ? BSResources.get(item.getOffer().getBankAccountType().toString()) : "";
|
||||
}
|
||||
|
||||
String getDirectionLabel(Offer offer) {
|
||||
return BSFormatter.formatDirection(offer.getDirection(), true);
|
||||
}
|
||||
|
||||
OrderBookInfo getOrderBookInfo() {
|
||||
return model.getOrderBookInfo();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private InputValidator.ValidationResult isBtcInputValid(String input) {
|
||||
return optionalBtcValidator.validate(input);
|
||||
}
|
||||
|
||||
private InputValidator.ValidationResult isFiatInputValid(String input) {
|
||||
return optionalFiatValidator.validate(input);
|
||||
}
|
||||
|
||||
private void setAmountToModel() {
|
||||
model.setAmount(parseToCoinWith4Decimals(amount.get()));
|
||||
}
|
||||
|
||||
private void setPriceToModel() {
|
||||
model.setPrice(parseToFiatWith2Decimals(price.get()));
|
||||
}
|
||||
|
||||
private void setVolumeToModel() {
|
||||
model.setVolume(parseToFiatWith2Decimals(volume.get()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,70 +17,145 @@
|
|||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import io.bitsquare.gui.components.InputTextField?>
|
||||
<?import io.bitsquare.gui.components.TitledGroupBg?>
|
||||
<?import io.bitsquare.gui.components.TitledSeparator?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.control.cell.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.trade.orderbook.OrderBookViewCB"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="0.0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<HBox fx:id="topHBox" prefHeight="22.0" AnchorPane.topAnchor="10.0" AnchorPane.leftAnchor="10.0"
|
||||
AnchorPane.rightAnchor="10.0">
|
||||
<TextField fx:id="amount" prefHeight="26.0" prefWidth="60.0" alignment="CENTER_RIGHT">
|
||||
<HBox.margin>
|
||||
<Insets left="0.0"/>
|
||||
</HBox.margin>
|
||||
</TextField>
|
||||
<Label text="BTC for">
|
||||
<GridPane fx:id="gridPane" hgap="5.0" vgap="0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0"
|
||||
AnchorPane.topAnchor="0.0">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="25.0" top="30.0" right="25"/>
|
||||
</padding>
|
||||
|
||||
<TitledGroupBg fx:id="priceAmountPane" text="Order book filter" GridPane.rowIndex="0" GridPane.columnIndex="0"
|
||||
GridPane.rowSpan="5" GridPane.columnSpan="2"/>
|
||||
|
||||
<Label text="Filter by amount or price:" GridPane.rowIndex="0" GridPane.valignment="TOP">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
<Insets top="21.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<TextField fx:id="price" prefHeight="26.0" prefWidth="70.0" alignment="CENTER_RIGHT"/>
|
||||
<Label text="EUR/BTC =">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
</Label>
|
||||
<TextField fx:id="volume" prefHeight="26.0" prefWidth="70.0" alignment="CENTER_RIGHT" editable="false"/>
|
||||
<Label prefHeight="21.0" prefWidth="100.0" text="EUR in total">
|
||||
<padding>
|
||||
<Insets left="4.0" right="4.0" top="5.0"/>
|
||||
</padding>
|
||||
<HBox.margin>
|
||||
<Insets/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5" GridPane.rowIndex="0" GridPane.columnIndex="1">
|
||||
<VBox spacing="4">
|
||||
<Label id="input-description-label" text="Filter by Amount in BTC"
|
||||
prefWidth="137"/>
|
||||
<HBox>
|
||||
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
||||
promptText="Amount in BTC" prefWidth="137"
|
||||
alignment="CENTER_RIGHT"/>
|
||||
<Label fx:id="amountBtcLabel" id="currency-info-label"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
<Label text="x">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="3" right="3"/>
|
||||
</padding>
|
||||
</Label>
|
||||
|
||||
<Button fx:id="createOfferButton" text="Create new offer" onAction="#createOffer" AnchorPane.topAnchor="10.0"
|
||||
AnchorPane.rightAnchor="10.0"/>
|
||||
<VBox spacing="4">
|
||||
<Label fx:id="priceDescriptionLabel" id="input-description-label" prefWidth="123"/>
|
||||
<HBox>
|
||||
<InputTextField fx:id="priceTextField" id="text-input-with-currency-text-field"
|
||||
promptText="Filter by price" prefWidth="123"
|
||||
alignment="CENTER_RIGHT"/>
|
||||
<Label fx:id="priceFiatLabel" id="currency-info-label" alignment="CENTER"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
||||
<TableView fx:id="orderBookTable" AnchorPane.leftAnchor="10.0"
|
||||
AnchorPane.topAnchor="45.0" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0">
|
||||
<columns>
|
||||
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="120">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="amount"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="70">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="price"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="Amount in EUR (Min.)" fx:id="volumeColumn" minWidth="130">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="volume"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn text="Country" fx:id="countryColumn" minWidth="60"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" minWidth="140"/>
|
||||
<TableColumn text="" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
<Label text="=">
|
||||
<font>
|
||||
<Font name="Helvetica" size="20.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets top="14.0" left="2" right="2"/>
|
||||
</padding>
|
||||
</Label>
|
||||
|
||||
</columns>
|
||||
</TableView>
|
||||
<VBox spacing="4">
|
||||
<Label fx:id="volumeDescriptionLabel" id="input-description-label" prefWidth="135"/>
|
||||
<HBox>
|
||||
<InputTextField fx:id="volumeTextField" id="text-input-with-currency-text-field"
|
||||
prefWidth="135" alignment="CENTER_RIGHT"/>
|
||||
<Label fx:id="volumeFiatLabel" id="currency-info-label"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5"/>
|
||||
</GridPane.margin>
|
||||
</HBox>
|
||||
|
||||
<Label fx:id="extendedCheckBoxLabel" text="Show only matching offers:" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="2" visible="false" managed="false"/>
|
||||
<CheckBox fx:id="extendedCheckBox" visible="false" managed="false" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="2"/>
|
||||
|
||||
<Label fx:id="extendedButton1Label" text="Payments account countries:" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="3" visible="false" managed="false"/>
|
||||
<Button fx:id="extendedButton1" text="Open filter" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="3" visible="false" managed="false"/>
|
||||
|
||||
<Label fx:id="extendedButton2Label" text="Payments account methods:" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="4" visible="false" managed="false"/>
|
||||
<Button fx:id="extendedButton2" text="Open filter" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="4" visible="false" managed="false">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="-5"/>
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
|
||||
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="5">
|
||||
<Button fx:id="showAdvancedSettingsButton" text="Open advanced filter"
|
||||
onAction="#onToggleShowAdvancedSettings"/>
|
||||
<Button fx:id="createOfferButton" text="Create new offer" defaultButton="true" onAction="#createOffer"/>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="30" top="20"/>
|
||||
</GridPane.margin>
|
||||
</HBox>
|
||||
|
||||
<TitledSeparator text="Order book for buying Bitcoin" GridPane.rowIndex="6" GridPane.columnIndex="0"
|
||||
GridPane.columnSpan="2"/>
|
||||
|
||||
<TableView fx:id="orderBookTable" GridPane.rowIndex="6" GridPane.columnIndex="0" GridPane.columnSpan="2">
|
||||
<GridPane.margin>
|
||||
<Insets top="10.0" left="-10" right="-10" bottom="-30"/>
|
||||
</GridPane.margin>
|
||||
<columns>
|
||||
<TableColumn text="Amount in BTC (Min.)" fx:id="amountColumn" minWidth="130"/>
|
||||
<TableColumn text="Price" fx:id="priceColumn" minWidth="130"/>
|
||||
<TableColumn text="Amount in EUR (Min.)" fx:id="volumeColumn" minWidth="130"/>
|
||||
<TableColumn text="Country" fx:id="countryColumn" minWidth="60"/>
|
||||
<TableColumn text="Bank transfer type" fx:id="bankAccountTypeColumn" minWidth="130"/>
|
||||
<TableColumn text="" fx:id="directionColumn" minWidth="80" sortable="false"/>
|
||||
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="200"/>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
|
||||
<rowConstraints>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
</rowConstraints>
|
||||
|
||||
</GridPane>
|
||||
</AnchorPane>
|
||||
|
|
|
@ -17,56 +17,40 @@
|
|||
|
||||
package io.bitsquare.gui.main.trade.orderbook;
|
||||
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.gui.NavigationItem;
|
||||
import io.bitsquare.gui.NavigationListener;
|
||||
import io.bitsquare.gui.OverlayController;
|
||||
import io.bitsquare.gui.ViewCB;
|
||||
import io.bitsquare.gui.ViewController;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import io.bitsquare.gui.main.trade.OrderBookInfo;
|
||||
import io.bitsquare.gui.main.trade.createoffer.CreateOfferViewCB;
|
||||
import io.bitsquare.gui.main.trade.takeoffer.TakeOfferController;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.gui.util.validation.OptionalBtcValidator;
|
||||
import io.bitsquare.gui.util.validation.OptionalFiatValidator;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.msg.MessageFacade;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.utils.Fiat;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.*;
|
||||
|
@ -77,36 +61,39 @@ import org.controlsfx.control.action.AbstractAction;
|
|||
import org.controlsfx.control.action.Action;
|
||||
import org.controlsfx.dialog.Dialog;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static javafx.beans.binding.Bindings.createStringBinding;
|
||||
|
||||
public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderBookViewCB.class);
|
||||
|
||||
//TODO nav?
|
||||
private NavigationController navigationController;
|
||||
private OverlayController overlayController;
|
||||
private final OrderBook orderBook;
|
||||
private OrderBookInfo orderBookInfo;
|
||||
private final User user;
|
||||
private final MessageFacade messageFacade;
|
||||
private final WalletFacade walletFacade;
|
||||
private final Settings settings;
|
||||
private final Persistence persistence;
|
||||
private OptionalBtcValidator optionalBtcValidator;
|
||||
private OptionalFiatValidator optionalFiatValidator;
|
||||
private NavigationListener navigationListener;
|
||||
|
||||
private SortedList<OrderBookListItem> offerList;
|
||||
private AnimationTimer pollingTimer;
|
||||
private boolean detailsVisible;
|
||||
private boolean advancedScreenInited;
|
||||
|
||||
private final Image buyIcon = ImageUtil.getIconImage(ImageUtil.BUY);
|
||||
private final Image sellIcon = ImageUtil.getIconImage(ImageUtil.SELL);
|
||||
|
||||
@FXML public HBox topHBox;
|
||||
@FXML public TextField volume, amount, price;
|
||||
@FXML public TableView<OrderBookListItem> orderBookTable;
|
||||
@FXML public TableColumn<OrderBookListItem, String> priceColumn, amountColumn, volumeColumn;
|
||||
@FXML public Button createOfferButton;
|
||||
@FXML private TableColumn<String, OrderBookListItem> directionColumn, countryColumn, bankAccountTypeColumn;
|
||||
private ImageView expand;
|
||||
private ImageView collapse;
|
||||
|
||||
@FXML private GridPane gridPane;
|
||||
@FXML private CheckBox extendedCheckBox;
|
||||
@FXML private Label amountBtcLabel, priceDescriptionLabel, priceFiatLabel, volumeDescriptionLabel,
|
||||
volumeFiatLabel, extendedButton1Label, extendedButton2Label, extendedCheckBoxLabel;
|
||||
@FXML private InputTextField volumeTextField, amountTextField, priceTextField;
|
||||
@FXML private TableView<OrderBookListItem> orderBookTable;
|
||||
@FXML private Button createOfferButton, showAdvancedSettingsButton, extendedButton1, extendedButton2;
|
||||
@FXML private TableColumn<OrderBookListItem, OrderBookListItem> priceColumn, amountColumn, volumeColumn,
|
||||
directionColumn, countryColumn, bankAccountTypeColumn;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -117,19 +104,14 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
private OrderBookViewCB(OrderBookPM presentationModel,
|
||||
NavigationController navigationController,
|
||||
OverlayController overlayController,
|
||||
OrderBook orderBook, User user,
|
||||
MessageFacade messageFacade,
|
||||
WalletFacade walletFacade, Settings settings, Persistence persistence) {
|
||||
OptionalBtcValidator optionalBtcValidator,
|
||||
OptionalFiatValidator optionalFiatValidator) {
|
||||
super(presentationModel);
|
||||
|
||||
this.navigationController = navigationController;
|
||||
this.overlayController = overlayController;
|
||||
this.orderBook = orderBook;
|
||||
this.user = user;
|
||||
this.messageFacade = messageFacade;
|
||||
this.walletFacade = walletFacade;
|
||||
this.settings = settings;
|
||||
this.persistence = persistence;
|
||||
this.optionalBtcValidator = optionalBtcValidator;
|
||||
this.optionalFiatValidator = optionalFiatValidator;
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,86 +124,106 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
super.initialize(url, rb);
|
||||
|
||||
// init table
|
||||
setAmountColumnCellFactory();
|
||||
setPriceColumnCellFactory();
|
||||
setVolumeColumnCellFactory();
|
||||
setCountryColumnCellFactory();
|
||||
setBankAccountTypeColumnCellFactory();
|
||||
setDirectionColumnCellFactory();
|
||||
//setRowFactory();
|
||||
|
||||
amountTextField.textProperty().bindBidirectional(presentationModel.amount);
|
||||
priceTextField.textProperty().bindBidirectional(presentationModel.price);
|
||||
volumeTextField.textProperty().bindBidirectional(presentationModel.volume);
|
||||
amountBtcLabel.textProperty().bind(presentationModel.btcCode);
|
||||
priceFiatLabel.textProperty().bind(presentationModel.fiatCode);
|
||||
volumeFiatLabel.textProperty().bind(presentationModel.fiatCode);
|
||||
priceDescriptionLabel.textProperty().bind(presentationModel.fiatCode);
|
||||
volumeDescriptionLabel.textProperty().bind(presentationModel.fiatCode);//Price per Bitcoin in EUR
|
||||
priceDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("Filter by price in {0}", presentationModel.fiatCode.get()),
|
||||
presentationModel.fiatCode));
|
||||
volumeDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("Filter by amount in {0}", presentationModel.fiatCode.get()),
|
||||
presentationModel.fiatCode));
|
||||
volumeTextField.promptTextProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("Amount in {0}", presentationModel.fiatCode.get()),
|
||||
presentationModel.fiatCode));
|
||||
|
||||
orderBookTable.getSortOrder().add(priceColumn);
|
||||
orderBookTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
||||
amountTextField.setValidator(optionalBtcValidator);
|
||||
priceTextField.setValidator(optionalFiatValidator);
|
||||
volumeTextField.setValidator(optionalFiatValidator);
|
||||
|
||||
expand = ImageUtil.getIconImageView(ImageUtil.EXPAND);
|
||||
collapse = ImageUtil.getIconImageView(ImageUtil.COLLAPSE);
|
||||
showAdvancedSettingsButton.setGraphic(expand);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
SortedList<OrderBookListItem> offerList = presentationModel.getOfferList();
|
||||
orderBookTable.setItems(offerList);
|
||||
// presentationModel.comparator.bind(orderBookTable.comparatorProperty());
|
||||
offerList.comparatorProperty().bind(orderBookTable.comparatorProperty());
|
||||
|
||||
priceColumn.setComparator((o1, o2) -> o1.getOffer().getPrice().compareTo(o2.getOffer().getPrice()));
|
||||
amountColumn.setComparator((o1, o2) -> o1.getOffer().getAmount().compareTo(o2.getOffer().getAmount()));
|
||||
volumeColumn.setComparator((o1, o2) ->
|
||||
o1.getOffer().getOfferVolume().compareTo(o2.getOffer().getOfferVolume()));
|
||||
countryColumn.setComparator((o1, o2) -> o1.getOffer().getBankAccountCountry().getName().compareTo(o2.getOffer()
|
||||
.getBankAccountCountry().getName()));
|
||||
bankAccountTypeColumn.setComparator((o1, o2) -> o1.getOffer().getBankAccountType().compareTo(o2.getOffer()
|
||||
.getBankAccountType()));
|
||||
|
||||
priceColumn.setSortType((presentationModel.getOrderBookInfo().getDirection() == Direction.BUY) ?
|
||||
TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING);
|
||||
orderBookTable.sort();
|
||||
|
||||
|
||||
/* if (orderBookTable.getItems() != null)
|
||||
createOfferButton.setDefaultButton(orderBookTable.getItems().isEmpty());*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
orderBook.cleanup();
|
||||
|
||||
orderBookTable.setItems(null);
|
||||
orderBookTable.getSortOrder().clear();
|
||||
offerList.comparatorProperty().unbind();
|
||||
|
||||
if (pollingTimer != null) {
|
||||
pollingTimer.stop();
|
||||
pollingTimer = null;
|
||||
}
|
||||
// orderBookTable.getSelectionModel().clearSelection();
|
||||
// orderBookTable.setItems(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Navigation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void setParent(Initializable parent) {
|
||||
super.setParent(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Initializable loadView(NavigationItem navigationItem) {
|
||||
return super.loadView(navigationItem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void initOrderBook(Direction direction, OrderBookInfo orderBookInfo) {
|
||||
this.orderBookInfo = orderBookInfo;
|
||||
orderBook.init();
|
||||
offerList = orderBook.getOfferList();
|
||||
offerList.comparatorProperty().bind(orderBookTable.comparatorProperty());
|
||||
orderBookTable.setItems(offerList);
|
||||
orderBookTable.getSortOrder().add(priceColumn);
|
||||
orderBookTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
public void enableCreateOfferButton() {
|
||||
createOfferButton.setDisable(false);
|
||||
}
|
||||
|
||||
orderBook.loadOffers();
|
||||
|
||||
// handlers
|
||||
amount.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
orderBookInfo.setAmount(BSFormatter.parseToCoin(newValue));
|
||||
updateVolume();
|
||||
});
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setter
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
price.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
orderBookInfo.setPrice(BSFormatter.parseToFiat(newValue));
|
||||
updateVolume();
|
||||
});
|
||||
public void setOrderBookInfo(OrderBookInfo orderBookInfo) {
|
||||
presentationModel.setOrderBookInfo(orderBookInfo);
|
||||
}
|
||||
|
||||
orderBookInfo.directionProperty().addListener((observable) -> applyOffers());
|
||||
|
||||
user.currentBankAccountProperty().addListener((ov) -> orderBook.loadOffers());
|
||||
|
||||
createOfferButton.setOnAction(e -> createOffer());
|
||||
|
||||
//TODO do polling until broadcast works
|
||||
setupPolling();
|
||||
orderBookTable.getSelectionModel().clearSelection();
|
||||
price.setText("");
|
||||
this.orderBookInfo.setDirection(direction);
|
||||
public void setNavigationListener(NavigationListener navigationListener) {
|
||||
this.navigationListener = navigationListener;
|
||||
}
|
||||
|
||||
|
||||
|
@ -230,45 +232,36 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@FXML
|
||||
public void createOffer() {
|
||||
if (isRegistered()) {
|
||||
void createOffer() {
|
||||
if (presentationModel.isRegistered()) {
|
||||
createOfferButton.setDisable(true);
|
||||
|
||||
//TODO Remove that when all UIs are converted to CodeBehind
|
||||
Initializable nextController = null;
|
||||
if (parent != null) {
|
||||
if (parent instanceof ViewController)
|
||||
nextController = ((ViewController) parent).loadViewAndGetChildController(NavigationItem
|
||||
.CREATE_OFFER);
|
||||
else if (parent instanceof ViewCB)
|
||||
nextController = ((ViewCB) parent).loadView(NavigationItem
|
||||
.CREATE_OFFER);
|
||||
}
|
||||
|
||||
if (nextController != null)
|
||||
((CreateOfferViewCB) nextController).setOrderBookFilter(orderBookInfo);
|
||||
navigationListener.navigate(NavigationItem.CREATE_OFFER);
|
||||
}
|
||||
else {
|
||||
openSetupScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void onToggleShowAdvancedSettings() {
|
||||
detailsVisible = !detailsVisible;
|
||||
if (detailsVisible) {
|
||||
showAdvancedSettingsButton.setText(BSResources.get("Hide extended filter options"));
|
||||
showAdvancedSettingsButton.setGraphic(collapse);
|
||||
showDetailsScreen();
|
||||
}
|
||||
else {
|
||||
showAdvancedSettingsButton.setText(BSResources.get("Show more filter options"));
|
||||
showAdvancedSettingsButton.setGraphic(expand);
|
||||
hideDetailsScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private boolean isRegistered() {
|
||||
return user.getAccountId() != null;
|
||||
}
|
||||
|
||||
private boolean areSettingsValid() {
|
||||
return !settings.getAcceptedLanguageLocales().isEmpty() &&
|
||||
!settings.getAcceptedCountries().isEmpty() &&
|
||||
!settings.getAcceptedArbitrators().isEmpty() &&
|
||||
user.getCurrentBankAccount() != null;
|
||||
}
|
||||
|
||||
|
||||
private void openSetupScreen() {
|
||||
overlayController.blurContent();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
|
@ -284,36 +277,9 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
"You don't have a trading account.", actions);
|
||||
}
|
||||
|
||||
private void payRegistrationFee() {
|
||||
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
||||
log.debug("payRegistrationFee onSuccess");
|
||||
if (transaction != null) {
|
||||
log.info("payRegistrationFee onSuccess tx id:" + transaction.getHashAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
log.debug("payRegistrationFee onFailure");
|
||||
}
|
||||
};
|
||||
try {
|
||||
walletFacade.payRegistrationFee(user.getStringifiedBankAccounts(), callback);
|
||||
if (walletFacade.getRegistrationAddressEntry() != null) {
|
||||
user.setAccountID(walletFacade.getRegistrationAddressEntry().toString());
|
||||
}
|
||||
|
||||
persistence.write(user.getClass().getName(), user);
|
||||
} catch (InsufficientMoneyException e1) {
|
||||
Popups.openInsufficientMoneyPopup();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO not updated yet
|
||||
private void takeOffer(Offer offer) {
|
||||
if (isRegistered()) {
|
||||
|
||||
if (presentationModel.isRegistered()) {
|
||||
//TODO Remove that when all UIs are converted to CodeBehind
|
||||
TakeOfferController takeOfferController = null;
|
||||
if (parent != null) {
|
||||
|
@ -328,8 +294,8 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
}
|
||||
|
||||
Coin requestedAmount;
|
||||
if (!"".equals(amount.getText())) {
|
||||
requestedAmount = BSFormatter.parseToCoin(amount.getText());
|
||||
if (!"".equals(amountTextField.getText())) {
|
||||
requestedAmount = BSFormatter.parseToCoin(amountTextField.getText());
|
||||
}
|
||||
else {
|
||||
requestedAmount = offer.getAmount();
|
||||
|
@ -344,50 +310,131 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
}
|
||||
}
|
||||
|
||||
private void removeOffer(Offer offer) {
|
||||
orderBook.removeOffer(offer);
|
||||
private void openRestrictionsWarning(String restrictionsInfo) {
|
||||
List<Action> actions = new ArrayList<>();
|
||||
actions.add(Dialog.Actions.YES);
|
||||
actions.add(Dialog.Actions.CLOSE);
|
||||
|
||||
Action response = Popups.openConfirmPopup("Information",
|
||||
restrictionsInfo,
|
||||
"You do not fulfill the requirements of that offer.",
|
||||
actions);
|
||||
|
||||
if (response == Dialog.Actions.YES)
|
||||
navigationController.navigationTo(NavigationItem.ACCOUNT, NavigationItem.ACCOUNT_SETTINGS,
|
||||
NavigationItem.RESTRICTIONS);
|
||||
else
|
||||
orderBookTable.getSelectionModel().clearSelection();
|
||||
}
|
||||
|
||||
private void applyOffers() {
|
||||
orderBook.applyFilter(orderBookInfo);
|
||||
|
||||
priceColumn.setSortType((orderBookInfo.getDirection() == Direction.BUY) ?
|
||||
TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING);
|
||||
orderBookTable.sort();
|
||||
|
||||
if (orderBookTable.getItems() != null) {
|
||||
createOfferButton.setDefaultButton(orderBookTable.getItems().isEmpty());
|
||||
private void showDetailsScreen() {
|
||||
log.debug("showDetailsScreen");
|
||||
if (!advancedScreenInited) {
|
||||
advancedScreenInited = true;
|
||||
}
|
||||
|
||||
toggleDetailsScreen(true);
|
||||
}
|
||||
|
||||
private void setupPolling() {
|
||||
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
|
||||
if (user.getCurrentBankAccount() != null) {
|
||||
messageFacade.getDirtyFlag(user.getCurrentBankAccount().getCurrency());
|
||||
}
|
||||
else {
|
||||
messageFacade.getDirtyFlag(CurrencyUtil.getDefaultCurrency());
|
||||
}
|
||||
return null;
|
||||
});
|
||||
private void hideDetailsScreen() {
|
||||
toggleDetailsScreen(false);
|
||||
log.debug("hideDetailsScreen");
|
||||
}
|
||||
|
||||
messageFacade.getIsDirtyProperty().addListener((observableValue, oldValue, newValue) -> orderBook.loadOffers());
|
||||
private void toggleDetailsScreen(boolean visible) {
|
||||
gridPane.setVgap(visible ? 5 : 0);
|
||||
|
||||
extendedButton1Label.setVisible(visible);
|
||||
extendedButton1Label.setManaged(visible);
|
||||
|
||||
extendedButton2Label.setVisible(visible);
|
||||
extendedButton2Label.setManaged(visible);
|
||||
|
||||
extendedCheckBoxLabel.setVisible(visible);
|
||||
extendedCheckBoxLabel.setManaged(visible);
|
||||
|
||||
extendedButton1.setVisible(visible);
|
||||
extendedButton1.setManaged(visible);
|
||||
|
||||
extendedButton2.setVisible(visible);
|
||||
extendedButton2.setManaged(visible);
|
||||
|
||||
extendedCheckBox.setVisible(visible);
|
||||
extendedCheckBox.setManaged(visible);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Table columns
|
||||
// Table
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setAmountColumnCellFactory() {
|
||||
amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
amountColumn.setCellFactory(
|
||||
new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem,
|
||||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getAmount(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setPriceColumnCellFactory() {
|
||||
priceColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
priceColumn.setCellFactory(
|
||||
new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem,
|
||||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getPrice(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setVolumeColumnCellFactory() {
|
||||
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
volumeColumn.setCellFactory(
|
||||
new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem,
|
||||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setText(presentationModel.getVolume(item));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setDirectionColumnCellFactory() {
|
||||
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
directionColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() {
|
||||
new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem,
|
||||
OrderBookListItem>>() {
|
||||
|
||||
@Override
|
||||
public TableCell<String, OrderBookListItem> call(
|
||||
TableColumn<String, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<String, OrderBookListItem>() {
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
final ImageView iconView = new ImageView();
|
||||
final Button button = new Button();
|
||||
|
||||
|
@ -396,34 +443,57 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
button.setMinWidth(70);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
|
||||
super.updateItem(orderBookListItem, empty);
|
||||
private void verifyIfTradable(final OrderBookListItem item) {
|
||||
boolean isMatchingRestrictions = presentationModel.isTradable(item
|
||||
.getOffer());
|
||||
button.setDisable(!isMatchingRestrictions);
|
||||
|
||||
if (orderBookListItem != null) {
|
||||
TableRow tableRow = getTableRow();
|
||||
if (tableRow != null)
|
||||
tableRow.setOpacity(isMatchingRestrictions ? 1 : 0.4);
|
||||
|
||||
if (isMatchingRestrictions) {
|
||||
button.setDefaultButton(getIndex() == 0);
|
||||
if (tableRow != null) {
|
||||
getTableRow().setOnMouseClicked(null);
|
||||
getTableRow().setTooltip(null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
button.setDefaultButton(false);
|
||||
if (tableRow != null) {
|
||||
getTableRow().setTooltip(new Tooltip("Click for more information."));
|
||||
getTableRow().setOnMouseClicked((e) -> openRestrictionsWarning
|
||||
(presentationModel.restrictionsInfo.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null) {
|
||||
String title;
|
||||
Image icon;
|
||||
Offer offer = orderBookListItem.getOffer();
|
||||
Offer offer = item.getOffer();
|
||||
|
||||
if (offer.getMessagePublicKey().equals(user.getMessagePublicKey())) {
|
||||
if (presentationModel.isMyOffer(offer)) {
|
||||
icon = ImageUtil.getIconImage(ImageUtil.REMOVE);
|
||||
title = "Remove";
|
||||
button.setOnAction(event -> removeOffer(orderBookListItem.getOffer()));
|
||||
button.setOnAction(event -> presentationModel.removeOffer(item
|
||||
.getOffer()));
|
||||
}
|
||||
else {
|
||||
if (offer.getDirection() == Direction.SELL) {
|
||||
icon = buyIcon;
|
||||
title = BSFormatter.formatDirection(Direction.BUY, true);
|
||||
}
|
||||
else {
|
||||
icon = sellIcon;
|
||||
title = BSFormatter.formatDirection(Direction.SELL, true);
|
||||
}
|
||||
|
||||
button.setDefaultButton(getIndex() == 0);
|
||||
button.setOnAction(event -> takeOffer(orderBookListItem.getOffer()));
|
||||
icon = offer.getDirection() == Direction.SELL ? buyIcon : sellIcon;
|
||||
title = presentationModel.getDirectionLabel(offer);
|
||||
button.setOnAction(event -> takeOffer(item.getOffer()));
|
||||
}
|
||||
|
||||
item.bankAccountCountryProperty().addListener((ov, o, n) ->
|
||||
verifyIfTradable(item));
|
||||
verifyIfTradable(item);
|
||||
|
||||
iconView.setImage(icon);
|
||||
button.setText(title);
|
||||
|
@ -441,12 +511,13 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
private void setCountryColumnCellFactory() {
|
||||
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
countryColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() {
|
||||
new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem,
|
||||
OrderBookListItem>>() {
|
||||
|
||||
@Override
|
||||
public TableCell<String, OrderBookListItem> call(
|
||||
TableColumn<String, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<String, OrderBookListItem>() {
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
final HBox hBox = new HBox();
|
||||
|
||||
{
|
||||
|
@ -462,15 +533,8 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
hBox.getChildren().clear();
|
||||
if (orderBookListItem != null) {
|
||||
Country country = orderBookListItem.getOffer().getBankAccountCountry();
|
||||
try {
|
||||
hBox.getChildren().add(ImageUtil.getIconImageView(
|
||||
"/images/countries/" + country.getCode().toLowerCase() + ".png"));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("Country icon not found: /images/countries/" +
|
||||
country.getCode().toLowerCase() + ".png country name: " +
|
||||
country.getName());
|
||||
}
|
||||
hBox.getChildren().add(ImageUtil.getCountryIconImageView(orderBookListItem
|
||||
.getOffer().getBankAccountCountry()));
|
||||
Tooltip.install(this, new Tooltip(country.getName()));
|
||||
}
|
||||
}
|
||||
|
@ -482,60 +546,21 @@ public class OrderBookViewCB extends CachedViewCB<OrderBookPM> {
|
|||
private void setBankAccountTypeColumnCellFactory() {
|
||||
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
|
||||
bankAccountTypeColumn.setCellFactory(
|
||||
new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() {
|
||||
|
||||
new Callback<TableColumn<OrderBookListItem, OrderBookListItem>, TableCell<OrderBookListItem,
|
||||
OrderBookListItem>>() {
|
||||
@Override
|
||||
public TableCell<String, OrderBookListItem> call(
|
||||
TableColumn<String, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<String, OrderBookListItem>() {
|
||||
public TableCell<OrderBookListItem, OrderBookListItem> call(
|
||||
TableColumn<OrderBookListItem, OrderBookListItem> directionColumn) {
|
||||
return new TableCell<OrderBookListItem, OrderBookListItem>() {
|
||||
@Override
|
||||
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
|
||||
super.updateItem(orderBookListItem, empty);
|
||||
|
||||
if (orderBookListItem != null) {
|
||||
BankAccountType bankAccountType = orderBookListItem.getOffer().getBankAccountType();
|
||||
setText(BSResources.get(bankAccountType.toString()));
|
||||
}
|
||||
else {
|
||||
setText("");
|
||||
}
|
||||
setText(presentationModel.getBankAccountType(orderBookListItem));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Utils
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private double textInputToNumber(String oldValue, String newValue) {
|
||||
//TODO use regex.... or custom textfield component
|
||||
double d = 0.0;
|
||||
if (!"".equals(newValue)) {
|
||||
try {
|
||||
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
|
||||
d = decimalFormat.parse(newValue).doubleValue();
|
||||
} catch (ParseException e) {
|
||||
amount.setText(oldValue);
|
||||
d = BSFormatter.parseToDouble(oldValue);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private void updateVolume() {
|
||||
double a = textInputToNumber(amount.getText(), amount.getText());
|
||||
double p = textInputToNumber(price.getText(), price.getText());
|
||||
//TODO
|
||||
volume.setText(BSFormatter.formatFiat(Fiat.valueOf("EUR", (long) (a * p))));
|
||||
}
|
||||
|
||||
public void enableCreateOfferButton() {
|
||||
createOfferButton.setDisable(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -78,11 +78,13 @@ public class BSFormatter {
|
|||
public BSFormatter(User user) {
|
||||
if (user.currentBankAccountProperty().get() == null)
|
||||
setFiatCurrencyCode(Currency.getInstance(Locale.getDefault()).getCurrencyCode());
|
||||
else
|
||||
else if (user.currentBankAccountProperty().get() != null)
|
||||
setFiatCurrencyCode(user.currentBankAccountProperty().get().getCurrency().getCurrencyCode());
|
||||
|
||||
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) ->
|
||||
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode()));
|
||||
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (newValue != null)
|
||||
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,9 +17,15 @@
|
|||
|
||||
package io.bitsquare.gui.util;
|
||||
|
||||
import io.bitsquare.locale.Country;
|
||||
|
||||
import javafx.scene.image.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ImageUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(ImageUtil.class);
|
||||
|
||||
public static final String SPLASH_LOGO = "/images/logo_600_600.png";
|
||||
|
||||
|
@ -64,4 +70,17 @@ public class ImageUtil {
|
|||
public static ImageView getIconImageView(String iconName) {
|
||||
return new ImageView(new Image(ImageUtil.class.getResourceAsStream(iconName)));
|
||||
}
|
||||
|
||||
public static ImageView getCountryIconImageView(Country country) {
|
||||
try {
|
||||
return ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Country icon not found URL = /images/countries/" + country.getCode().toLowerCase() +
|
||||
".png / country name = " + country.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -47,11 +47,13 @@ public final class FiatValidator extends NumberValidator {
|
|||
if (user != null) {
|
||||
if (user.currentBankAccountProperty().get() == null)
|
||||
setFiatCurrencyCode(Currency.getInstance(Locale.getDefault()).getCurrencyCode());
|
||||
else
|
||||
else if (user.currentBankAccountProperty().get() != null)
|
||||
setFiatCurrencyCode(user.currentBankAccountProperty().get().getCurrency().getCurrencyCode());
|
||||
|
||||
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) ->
|
||||
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode()));
|
||||
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (newValue != null)
|
||||
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ public class InputValidator {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class ValidationResult {
|
||||
|
||||
|
||||
public final boolean isValid;
|
||||
public final String errorMessage;
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.util.validation;
|
||||
|
||||
import io.bitsquare.locale.BSResources;
|
||||
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* BtcValidator for validating BTC values.
|
||||
* <p>
|
||||
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
|
||||
*/
|
||||
public final class OptionalBtcValidator extends NumberValidator {
|
||||
private static final Logger log = LoggerFactory.getLogger(OptionalBtcValidator.class);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public ValidationResult validate(String input) {
|
||||
ValidationResult result = validateIfNotEmpty(input);
|
||||
|
||||
// we accept empty input
|
||||
if (!result.isValid)
|
||||
return new ValidationResult(true);
|
||||
|
||||
if (result.isValid) {
|
||||
input = cleanInput(input);
|
||||
result = validateIfNumber(input);
|
||||
}
|
||||
|
||||
if (result.isValid) {
|
||||
result = validateIfNotZero(input);
|
||||
if (result.isValid) {
|
||||
result = validateIfNotNegative(input)
|
||||
.and(validateIfNotFractionalBtcValue(input))
|
||||
.and(validateIfNotExceedsMaxBtcValue(input));
|
||||
}
|
||||
else {
|
||||
// we accept zero input
|
||||
return new ValidationResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private ValidationResult validateIfNotFractionalBtcValue(String input) {
|
||||
BigDecimal bd = new BigDecimal(input);
|
||||
final BigDecimal satoshis = bd.movePointRight(8);
|
||||
if (satoshis.scale() > 0)
|
||||
return new ValidationResult(false, BSResources.get("validation.btc.toSmall"));
|
||||
else
|
||||
return new ValidationResult(true);
|
||||
}
|
||||
|
||||
private ValidationResult validateIfNotExceedsMaxBtcValue(String input) {
|
||||
BigDecimal bd = new BigDecimal(input);
|
||||
final BigDecimal satoshis = bd.movePointRight(8);
|
||||
if (satoshis.longValue() > NetworkParameters.MAX_MONEY.longValue())
|
||||
return new ValidationResult(false, BSResources.get("validation.btc.toLarge"));
|
||||
else
|
||||
return new ValidationResult(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.util.validation;
|
||||
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* FiatNumberValidator for validating fiat values.
|
||||
* <p>
|
||||
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
|
||||
*/
|
||||
public final class OptionalFiatValidator extends NumberValidator {
|
||||
private static final Logger log = LoggerFactory.getLogger(OptionalFiatValidator.class);
|
||||
|
||||
//TODO Find appropriate values - depends on currencies
|
||||
public static final double MIN_FIAT_VALUE = 0.01; // usually a cent is the smallest currency unit
|
||||
public static final double MAX_FIAT_VALUE = 1000000;
|
||||
private String currencyCode = "Fiat";
|
||||
|
||||
|
||||
@Inject
|
||||
public OptionalFiatValidator(User user) {
|
||||
if (user != null) {
|
||||
if (user.currentBankAccountProperty().get() == null)
|
||||
setFiatCurrencyCode(Currency.getInstance(Locale.getDefault()).getCurrencyCode());
|
||||
else if (user.currentBankAccountProperty().get() != null)
|
||||
setFiatCurrencyCode(user.currentBankAccountProperty().get().getCurrency().getCurrencyCode());
|
||||
|
||||
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (newValue != null)
|
||||
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public ValidationResult validate(String input) {
|
||||
ValidationResult result = validateIfNotEmpty(input);
|
||||
|
||||
// we accept empty input
|
||||
if (!result.isValid)
|
||||
return new ValidationResult(true);
|
||||
|
||||
if (result.isValid) {
|
||||
input = cleanInput(input);
|
||||
result = validateIfNumber(input);
|
||||
}
|
||||
|
||||
if (result.isValid) {
|
||||
result = validateIfNotZero(input);
|
||||
if (result.isValid) {
|
||||
result = validateIfNotNegative(input)
|
||||
.and(validateIfNotExceedsMinFiatValue(input))
|
||||
.and(validateIfNotExceedsMaxFiatValue(input));
|
||||
}
|
||||
else {
|
||||
// we accept zero input
|
||||
return new ValidationResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setter
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setFiatCurrencyCode(String currencyCode) {
|
||||
this.currencyCode = currencyCode;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private ValidationResult validateIfNotExceedsMinFiatValue(String input) {
|
||||
double d = Double.parseDouble(input);
|
||||
if (d < MIN_FIAT_VALUE)
|
||||
return new ValidationResult(false, BSResources.get("validation.fiat.toSmall", currencyCode));
|
||||
else
|
||||
return new ValidationResult(true);
|
||||
}
|
||||
|
||||
private ValidationResult validateIfNotExceedsMaxFiatValue(String input) {
|
||||
double d = Double.parseDouble(input);
|
||||
if (d > MAX_FIAT_VALUE)
|
||||
return new ValidationResult(false, BSResources.get("validation.fiat.toLarge", currencyCode));
|
||||
else
|
||||
return new ValidationResult(true);
|
||||
}
|
||||
}
|
|
@ -35,9 +35,9 @@ import java.io.IOException;
|
|||
import java.security.PublicKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -56,6 +56,7 @@ import net.tomp2p.futures.BaseFutureAdapter;
|
|||
import net.tomp2p.futures.BaseFutureListener;
|
||||
import net.tomp2p.futures.FutureDirect;
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.peers.Number640;
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.storage.Data;
|
||||
import net.tomp2p.utils.Utils;
|
||||
|
@ -184,14 +185,22 @@ public class MessageFacade implements MessageBroker {
|
|||
if (future.isSuccess()) {
|
||||
Platform.runLater(() -> {
|
||||
addOfferListener.onComplete();
|
||||
orderBookListeners.stream().forEach(listener ->
|
||||
listener.onOfferAdded(offerData, future.isSuccess()));
|
||||
orderBookListeners.stream().forEach(listener -> {
|
||||
try {
|
||||
Object offerDataObject = offerData.object();
|
||||
if (offerDataObject instanceof Offer) {
|
||||
listener.onOfferAdded((Offer) offerDataObject);
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("Add offer to DHT failed: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
// TODO will be removed when we don't use polling anymore
|
||||
setDirty(locationKey);
|
||||
log.trace("Add offer to DHT was successful. Stored data: [locationKey: " + locationKey +
|
||||
", " +
|
||||
"value: " + offerData + "]");
|
||||
log.trace("Add offer to DHT was successful. Added data: [locationKey: " + locationKey +
|
||||
", value: " + offerData + "]");
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
@ -229,28 +238,39 @@ public class MessageFacade implements MessageBroker {
|
|||
futureRemove.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
Platform.runLater(() -> {
|
||||
orderBookListeners.stream().forEach(orderBookListener ->
|
||||
orderBookListener.onOfferRemoved(offerData, future.isSuccess()));
|
||||
setDirty(locationKey);
|
||||
});
|
||||
if (future.isSuccess()) {
|
||||
log.trace("Remove offer from DHT was successful. Stored data: [key: " + locationKey + ", " +
|
||||
Platform.runLater(() -> {
|
||||
orderBookListeners.stream().forEach(orderBookListener -> {
|
||||
try {
|
||||
Object offerDataObject = offerData.object();
|
||||
if (offerDataObject instanceof Offer) {
|
||||
orderBookListener.onOfferRemoved((Offer) offerDataObject);
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
setDirty(locationKey);
|
||||
});
|
||||
|
||||
log.trace("Remove offer from DHT was successful. Removed data: [key: " + locationKey + ", " +
|
||||
"value: " + offerData + "]");
|
||||
}
|
||||
else {
|
||||
log.error("Remove offer from DHT failed. locationKey: " + locationKey + ", Reason: " + future
|
||||
.failedReason());
|
||||
log.error("Remove offer from DHT was not successful. locationKey: " + locationKey + ", " +
|
||||
"Reason: " + future.failedReason());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
log.error(t.toString());
|
||||
log.error("Remove offer from DHT failed. Error: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,14 +280,31 @@ public class MessageFacade implements MessageBroker {
|
|||
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture baseFuture) throws Exception {
|
||||
Platform.runLater(() -> orderBookListeners.stream().forEach(orderBookListener -> orderBookListener
|
||||
.onOffersReceived(futureGet.dataMap(), baseFuture.isSuccess())));
|
||||
if (baseFuture.isSuccess()) {
|
||||
log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey
|
||||
+ ", values: " + futureGet.dataMap() + "]");
|
||||
final Map<Number640, Data> dataMap = futureGet.dataMap();
|
||||
final List<Offer> offers = new ArrayList<>();
|
||||
if (dataMap != null) {
|
||||
for (Data offerData : dataMap.values()) {
|
||||
try {
|
||||
Object offerDataObject = offerData.object();
|
||||
if (offerDataObject instanceof Offer) {
|
||||
offers.add((Offer) offerDataObject);
|
||||
}
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Platform.runLater(() -> orderBookListeners.stream().forEach(listener ->
|
||||
listener.onOffersReceived(offers)));
|
||||
}
|
||||
|
||||
log.trace("Get offers from DHT was successful");
|
||||
/* log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey
|
||||
+ ", values: " + futureGet.dataMap() + "]");*/
|
||||
}
|
||||
else {
|
||||
log.error("Get offers from DHT failed with reason:" + baseFuture.failedReason());
|
||||
log.error("Get offers from DHT was not successful with reason:" + baseFuture.failedReason());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -409,8 +446,8 @@ public class MessageFacade implements MessageBroker {
|
|||
return isDirty;
|
||||
}
|
||||
|
||||
public void getDirtyFlag(Currency currency) {
|
||||
Number160 locationKey = Number160.createHash(currency.getCurrencyCode());
|
||||
public void getDirtyFlag(String currencyCode) {
|
||||
Number160 locationKey = Number160.createHash(currencyCode);
|
||||
try {
|
||||
FutureGet getFuture = p2pNode.getData(getDirtyLocationKey(locationKey));
|
||||
getFuture.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
|
||||
package io.bitsquare.msg.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import io.bitsquare.trade.Offer;
|
||||
|
||||
import net.tomp2p.peers.Number640;
|
||||
import net.tomp2p.storage.Data;
|
||||
import java.util.List;
|
||||
|
||||
public interface OrderBookListener {
|
||||
void onOfferAdded(Data offerData, boolean success);
|
||||
void onOfferAdded(Offer offer);
|
||||
|
||||
void onOffersReceived(Map<Number640, Data> dataMap, boolean success);
|
||||
void onOffersReceived(List<Offer> offers);
|
||||
|
||||
void onOfferRemoved(Data data, boolean success);
|
||||
void onOfferRemoved(Offer offer);
|
||||
}
|
|
@ -154,20 +154,20 @@ public class Offer implements Serializable {
|
|||
return acceptedLanguageLocales;
|
||||
}
|
||||
|
||||
public Fiat getVolumeForCoin(Coin coin) {
|
||||
if (price != null && coin != null && !coin.isZero() && !price.isZero()) {
|
||||
return new ExchangeRate(price).coinToFiat(coin);
|
||||
public Fiat getVolumeByAmount(Coin amount) {
|
||||
if (price != null && amount != null && !amount.isZero() && !price.isZero()) {
|
||||
return new ExchangeRate(price).coinToFiat(amount);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public Fiat getOfferVolume() {
|
||||
return getVolumeForCoin(amount);
|
||||
return getVolumeByAmount(amount);
|
||||
}
|
||||
|
||||
public Fiat getMinOfferVolume() {
|
||||
return getVolumeForCoin(minAmount);
|
||||
return getVolumeByAmount(minAmount);
|
||||
}
|
||||
|
||||
public String getOfferFeePaymentTxID() {
|
||||
|
|
|
@ -59,7 +59,7 @@ public class Trade implements Serializable {
|
|||
}
|
||||
|
||||
public Fiat getTradeVolume() {
|
||||
return offer.getVolumeForCoin(tradeAmount);
|
||||
return offer.getVolumeByAmount(tradeAmount);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -36,8 +36,8 @@ import org.slf4j.LoggerFactory;
|
|||
* Guice support for fxml controllers
|
||||
* Support caching to speed up switches between UI screens.
|
||||
*/
|
||||
public class BSFXMLLoader {
|
||||
private static final Logger log = LoggerFactory.getLogger(BSFXMLLoader.class);
|
||||
public class ViewLoader {
|
||||
private static final Logger log = LoggerFactory.getLogger(ViewLoader.class);
|
||||
private static Injector injector = null;
|
||||
private FXMLLoader loader;
|
||||
private final boolean isCached;
|
||||
|
@ -45,27 +45,27 @@ public class BSFXMLLoader {
|
|||
private Item item;
|
||||
|
||||
public static void setInjector(Injector injector) {
|
||||
BSFXMLLoader.injector = injector;
|
||||
ViewLoader.injector = injector;
|
||||
}
|
||||
|
||||
// TODO maybe add more sophisticated caching strategy with removal of rarely accessed items
|
||||
private static final Map<URL, Item> cachedGUIItems = new HashMap<>();
|
||||
|
||||
public BSFXMLLoader(URL url) {
|
||||
public ViewLoader(URL url) {
|
||||
this(url, true);
|
||||
}
|
||||
|
||||
// TODO check relationship with CachedViewCB -> derive caching strategy, but there are some special cases where
|
||||
// we need an override, as caching is done manually in the client class
|
||||
public BSFXMLLoader(URL url, boolean useCaching) {
|
||||
public ViewLoader(URL url, boolean useCaching) {
|
||||
this.url = url;
|
||||
|
||||
isCached = useCaching && cachedGUIItems.containsKey(url);
|
||||
if (!isCached) {
|
||||
loader = new FXMLLoader(url, BSResources.getResourceBundle());
|
||||
|
||||
if (BSFXMLLoader.injector != null)
|
||||
loader.setControllerFactory(new GuiceControllerFactory(BSFXMLLoader.injector));
|
||||
if (ViewLoader.injector != null)
|
||||
loader.setControllerFactory(new GuiceControllerFactory(ViewLoader.injector));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
# shared
|
||||
shared.readMore=Read more...
|
||||
shared.readMore=Read more
|
||||
shared.openHelp=Open Help
|
||||
shared.warning=Warning
|
||||
shared.error=Error
|
||||
shared.close=Close
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.account;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class AccountSettingsUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class AccountSettingsUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/AccountSettingsView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.account;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class AccountUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class AccountUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/AccountView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.account;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class RegistrationUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class RegistrationUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/content/RegistrationView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.account;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class SetupUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class SetupUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/setup/SetupView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.bitsquare.gui.main.account.registration.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -37,7 +37,7 @@ public class FundRegistrationWalletUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 650);
|
||||
|
@ -50,7 +50,7 @@ public class FundRegistrationWalletUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/registration/uimock/FundRegistrationWalletViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.bitsquare.gui.main.account.registration.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -37,7 +37,7 @@ public class RegistrationUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 660);
|
||||
|
@ -50,7 +50,7 @@ public class RegistrationUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/registration/uimock/RegistrationViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class FiatAccountUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class FiatAccountUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/content/FiatAccountView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class PasswordUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class PasswordUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/content/PasswordView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class RegistrationUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 530);
|
||||
|
@ -67,7 +67,7 @@ public class RegistrationUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/content/RegistrationView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class RestrictionsUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 530);
|
||||
|
@ -67,7 +67,7 @@ public class RestrictionsUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/content/RestrictionsView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class SeedWordsUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class SeedWordsUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/account/content/SeedWordsView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class BankAccountSettingsUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 1200);
|
||||
|
@ -67,7 +67,7 @@ public class BankAccountSettingsUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/settings/uimock/BankAccountSettingsViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class RestrictionSettingsUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 1200);
|
||||
|
@ -67,7 +67,7 @@ public class RestrictionSettingsUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/settings/uimock/RestrictionSettingsViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.bitsquare.gui.main.settings.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -37,7 +37,7 @@ public class SeedWordsUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 1200);
|
||||
|
@ -50,7 +50,7 @@ public class SeedWordsUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/settings/uimock/SeedWordsViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.bitsquare.gui.main.settings.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -37,7 +37,7 @@ public class SetPasswordUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 1200);
|
||||
|
@ -50,7 +50,7 @@ public class SetPasswordUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/settings/uimock/SetPasswordViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.trade.createoffer;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class CreateOfferUITestRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class CreateOfferUITestRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/trade/createoffer/CreateOfferView.fxml"), false);
|
||||
try {
|
||||
view = loader.load();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.trade.createoffer.uimock;
|
||||
|
||||
import io.bitsquare.di.BitSquareModule;
|
||||
import io.bitsquare.util.BSFXMLLoader;
|
||||
import io.bitsquare.util.ViewLoader;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -54,7 +54,7 @@ public class CreateOfferUIMockRunner extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
Injector injector = Guice.createInjector(new BitSquareModule());
|
||||
BSFXMLLoader.setInjector(injector);
|
||||
ViewLoader.setInjector(injector);
|
||||
|
||||
pane = new StackPane();
|
||||
scene = new Scene(pane, 1000, 630);
|
||||
|
@ -67,7 +67,7 @@ public class CreateOfferUIMockRunner extends Application {
|
|||
public void loadMainWindow() {
|
||||
log.debug("re load");
|
||||
pane.getChildren().removeAll();
|
||||
BSFXMLLoader loader = new BSFXMLLoader(
|
||||
ViewLoader loader = new ViewLoader(
|
||||
getUrl("/io/bitsquare/gui/trade/createoffer/uimock/CreateOfferViewUIMock.fxml"), false);
|
||||
|
||||
try {
|
||||
|
|
Loading…
Add table
Reference in a new issue