mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-22 14:42:37 +01:00
fixed validation bugs and bugs at create order view
This commit is contained in:
parent
844029d967
commit
7e8ee84ed1
19 changed files with 328 additions and 246 deletions
|
@ -648,7 +648,7 @@ public class WalletFacade
|
|||
Coin fee = FeePolicy.CREATE_OFFER_FEE.subtract(FeePolicy.TX_FEE);
|
||||
log.trace("fee: " + fee.toFriendlyString());
|
||||
tx.addOutput(fee, feePolicy.getAddressForCreateOfferFee());
|
||||
printInputs("payCreateOfferFee", tx);
|
||||
// printInputs("payCreateOfferFee", tx);
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
|
||||
sendRequest.shuffleOutputs = false;
|
||||
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation)
|
||||
|
|
|
@ -20,7 +20,6 @@ import io.bitsquare.settings.Settings;
|
|||
import io.bitsquare.storage.Persistence;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.trade.orderbook.OrderBook;
|
||||
import io.bitsquare.trade.orderbook.OrderBookFilter;
|
||||
import io.bitsquare.user.User;
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -34,7 +33,6 @@ public class BitSquareModule extends AbstractModule
|
|||
bind(OrderBook.class).asEagerSingleton();
|
||||
bind(Persistence.class).asEagerSingleton();
|
||||
bind(Settings.class).asEagerSingleton();
|
||||
bind(OrderBookFilter.class).asEagerSingleton();
|
||||
|
||||
bind(CryptoFacade.class).asEagerSingleton();
|
||||
bind(WalletFacade.class).asEagerSingleton();
|
||||
|
|
|
@ -40,8 +40,8 @@ public class GuiceFXMLLoader
|
|||
{
|
||||
this.url = url;
|
||||
|
||||
// useCaching = false;
|
||||
isCached = useCaching && cachedGUIItems.containsKey(url);
|
||||
|
||||
if (!isCached)
|
||||
{
|
||||
loader = new FXMLLoader(url, Localisation.getResourceBundle());
|
||||
|
|
|
@ -6,7 +6,6 @@ import io.bitsquare.btc.WalletFacade;
|
|||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.di.GuiceFXMLLoader;
|
||||
import io.bitsquare.gui.components.NetworkSyncPane;
|
||||
import io.bitsquare.gui.market.MarketController;
|
||||
import io.bitsquare.gui.orders.OrdersController;
|
||||
import io.bitsquare.gui.util.ImageUtil;
|
||||
import io.bitsquare.gui.util.Profiler;
|
||||
|
@ -14,7 +13,6 @@ import io.bitsquare.gui.util.Transitions;
|
|||
import io.bitsquare.msg.BootstrapListener;
|
||||
import io.bitsquare.msg.MessageFacade;
|
||||
import io.bitsquare.storage.Persistence;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.AWTSystemTray;
|
||||
|
@ -332,11 +330,6 @@ public class MainController implements Initializable, NavigationController
|
|||
|
||||
controller = loadView(navigationItem);
|
||||
|
||||
if (controller instanceof MarketController)
|
||||
{
|
||||
((MarketController) controller).setDirection(navigationItem == NavigationItem.BUY ? Direction.BUY : Direction.SELL);
|
||||
}
|
||||
|
||||
persistence.write(this, "selectedNavigationItem", navigationItem);
|
||||
|
||||
prevToggleButton = toggleButton;
|
||||
|
|
|
@ -6,8 +6,8 @@ public enum NavigationItem
|
|||
{
|
||||
MAIN("/io/bitsquare/gui/MainView.fxml"),
|
||||
HOME("/io/bitsquare/gui/home/HomeView.fxml", ImageUtil.HOME, ImageUtil.HOME_ACTIVE),
|
||||
BUY("/io/bitsquare/gui/market/MarketView.fxml", ImageUtil.NAV_BUY, ImageUtil.NAV_BUY_ACTIVE),
|
||||
SELL("/io/bitsquare/gui/market/MarketView.fxml", ImageUtil.NAV_SELL, ImageUtil.NAV_SELL_ACTIVE),
|
||||
BUY("/io/bitsquare/gui/market/BuyView.fxml", ImageUtil.NAV_BUY, ImageUtil.NAV_BUY_ACTIVE),
|
||||
SELL("/io/bitsquare/gui/market/SellView.fxml", ImageUtil.NAV_SELL, ImageUtil.NAV_SELL_ACTIVE),
|
||||
ORDERS("/io/bitsquare/gui/orders/OrdersView.fxml", ImageUtil.ORDERS, ImageUtil.ORDERS_ACTIVE),
|
||||
FUNDS("/io/bitsquare/gui/funds/FundsView.fxml", ImageUtil.FUNDS, ImageUtil.FUNDS_ACTIVE),
|
||||
MSG("/io/bitsquare/gui/msg/MsgView.fxml", ImageUtil.MSG, ImageUtil.MSG_ACTIVE),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.bitsquare.gui.components;
|
||||
|
||||
import io.bitsquare.gui.util.NumberValidator;
|
||||
import java.util.LinkedList;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.geometry.Insets;
|
||||
|
@ -28,21 +27,26 @@ import org.slf4j.LoggerFactory;
|
|||
public class ValidatingTextField extends TextField
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ValidatingTextField.class);
|
||||
private static final Effect DEFAULT_EFFECT = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
|
||||
private static PopOver popOver;
|
||||
|
||||
// we hold all error popups any only display the latest one
|
||||
private static final LinkedList<PopOver> allErrorPopups = new LinkedList<>();
|
||||
private Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
|
||||
|
||||
private Effect invalidEffect = DEFAULT_EFFECT;
|
||||
private final BooleanProperty valid = new SimpleBooleanProperty(true);
|
||||
private final BooleanProperty isValid = new SimpleBooleanProperty(true);
|
||||
private NumberValidator numberValidator;
|
||||
private boolean validateOnFocusOut = true;
|
||||
private boolean needsValidationOnFocusOut;
|
||||
private PopOver popOver;
|
||||
|
||||
private Region errorPopupLayoutReference;
|
||||
private double errorPopOverX;
|
||||
private double errorPopOverY;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Static
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void hidePopover()
|
||||
{
|
||||
if (popOver != null)
|
||||
popOver.hide();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -52,6 +56,7 @@ public class ValidatingTextField extends TextField
|
|||
public ValidatingTextField()
|
||||
{
|
||||
super();
|
||||
|
||||
setupListeners();
|
||||
}
|
||||
|
||||
|
@ -75,19 +80,44 @@ public class ValidatingTextField extends TextField
|
|||
this.numberValidator = numberValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param errorPopupLayoutReference The node used as reference for positioning
|
||||
*/
|
||||
public void setErrorPopupLayoutReference(Region errorPopupLayoutReference)
|
||||
{
|
||||
this.errorPopupLayoutReference = errorPopupLayoutReference;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean getIsValid()
|
||||
{
|
||||
return isValid.get();
|
||||
}
|
||||
|
||||
public BooleanProperty isValidProperty()
|
||||
{
|
||||
return isValid;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setupListeners()
|
||||
{
|
||||
this.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
sceneProperty().addListener((ov, oldValue, newValue) -> {
|
||||
// we got removed from the scene
|
||||
// lets hide an open popup
|
||||
if (newValue == null)
|
||||
hidePopover();
|
||||
});
|
||||
|
||||
textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (numberValidator != null)
|
||||
{
|
||||
if (!validateOnFocusOut)
|
||||
|
@ -97,12 +127,12 @@ public class ValidatingTextField extends TextField
|
|||
}
|
||||
});
|
||||
|
||||
this.focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (validateOnFocusOut && needsValidationOnFocusOut && !newValue && getScene()!= null && getScene().getWindow().isFocused())
|
||||
focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
if (validateOnFocusOut && needsValidationOnFocusOut && !newValue && getScene() != null && getScene().getWindow().isFocused())
|
||||
validate(getText());
|
||||
});
|
||||
|
||||
this.valid.addListener((ov, oldValue, newValue) -> applyEffect(newValue));
|
||||
isValid.addListener((ov, oldValue, newValue) -> applyEffect(newValue));
|
||||
}
|
||||
|
||||
private void validate(String input)
|
||||
|
@ -110,7 +140,7 @@ public class ValidatingTextField extends TextField
|
|||
if (input != null)
|
||||
{
|
||||
NumberValidator.ValidationResult validationResult = numberValidator.validate(input);
|
||||
valid.set(validationResult.isValid);
|
||||
isValid.set(validationResult.isValid);
|
||||
applyErrorMessage(validationResult);
|
||||
}
|
||||
}
|
||||
|
@ -119,35 +149,19 @@ public class ValidatingTextField extends TextField
|
|||
{
|
||||
if (validationResult.isValid)
|
||||
{
|
||||
if (allErrorPopups.contains(popOver))
|
||||
if (popOver != null)
|
||||
{
|
||||
allErrorPopups.remove(popOver);
|
||||
popOver.hide();
|
||||
}
|
||||
if (allErrorPopups.size() > 0)
|
||||
{
|
||||
PopOver lastPopOver = allErrorPopups.getLast();
|
||||
lastPopOver.show(getScene().getWindow());
|
||||
}
|
||||
popOver = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (allErrorPopups.size() > 0)
|
||||
{
|
||||
PopOver lastPopOver = allErrorPopups.getLast();
|
||||
lastPopOver.hide();
|
||||
}
|
||||
if (popOver == null)
|
||||
createErrorPopOver(validationResult.errorMessage);
|
||||
else
|
||||
setErrorMessage(validationResult.errorMessage);
|
||||
|
||||
if (allErrorPopups.contains(popOver))
|
||||
{
|
||||
allErrorPopups.remove(popOver);
|
||||
popOver.hide();
|
||||
}
|
||||
|
||||
popOver = createErrorPopOver(validationResult.errorMessage);
|
||||
popOver.show(getScene().getWindow(), errorPopOverX, errorPopOverY);
|
||||
allErrorPopups.add(popOver);
|
||||
popOver.show(getScene().getWindow(), getErrorPopupPosition().getX(), getErrorPopupPosition().getY());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,30 +170,39 @@ public class ValidatingTextField extends TextField
|
|||
setEffect(isValid ? null : invalidEffect);
|
||||
}
|
||||
|
||||
private PopOver createErrorPopOver(String errorMessage)
|
||||
private Point2D getErrorPopupPosition()
|
||||
{
|
||||
Window window = getScene().getWindow();
|
||||
Point2D point;
|
||||
double x;
|
||||
if (errorPopupLayoutReference == null)
|
||||
{
|
||||
point = localToScene(0, 0);
|
||||
x = point.getX() + window.getX() + getWidth() + 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
point = errorPopupLayoutReference.localToScene(0, 0);
|
||||
x = point.getX() + window.getX() + errorPopupLayoutReference.getWidth() + 20;
|
||||
}
|
||||
double y = point.getY() + window.getY() + Math.floor(getHeight() / 2);
|
||||
return new Point2D(x, y);
|
||||
}
|
||||
|
||||
private static void setErrorMessage(String errorMessage)
|
||||
{
|
||||
((Label) popOver.getContentNode()).setText(errorMessage);
|
||||
}
|
||||
|
||||
private static void createErrorPopOver(String errorMessage)
|
||||
{
|
||||
Label errorLabel = new Label(errorMessage);
|
||||
errorLabel.setId("validation-error");
|
||||
errorLabel.setPadding(new Insets(0, 10, 0, 10));
|
||||
|
||||
PopOver popOver = new PopOver(errorLabel);
|
||||
popOver = new PopOver(errorLabel);
|
||||
popOver.setAutoFix(true);
|
||||
popOver.setDetachedTitle("");
|
||||
popOver.setArrowIndent(5);
|
||||
Window window = getScene().getWindow();
|
||||
|
||||
Point2D point;
|
||||
if (errorPopupLayoutReference == null)
|
||||
{
|
||||
point = localToScene(0, 0);
|
||||
errorPopOverX = point.getX() + window.getX() + getWidth() + 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
point = errorPopupLayoutReference.localToScene(0, 0);
|
||||
errorPopOverX = point.getX() + window.getX() + errorPopupLayoutReference.getWidth() + 20;
|
||||
}
|
||||
errorPopOverY = point.getY() + window.getY() + Math.floor(getHeight() / 2);
|
||||
return popOver;
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ public class BalanceTextField extends AnchorPane
|
|||
private WalletFacade walletFacade;
|
||||
private ConfidenceListener confidenceListener;
|
||||
private BalanceListener balanceListener;
|
||||
private Coin balance;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,11 +97,21 @@ public class BalanceTextField extends AnchorPane
|
|||
walletFacade.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Coin getBalance()
|
||||
{
|
||||
return balance;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private void updateConfidence(TransactionConfidence confidence)
|
||||
{
|
||||
if (confidence != null)
|
||||
|
@ -136,10 +147,12 @@ public class BalanceTextField extends AnchorPane
|
|||
|
||||
private void updateBalance(Coin balance)
|
||||
{
|
||||
this.balance = balance;
|
||||
if (balance != null)
|
||||
{
|
||||
//TODO use BitSquareFormatter
|
||||
balanceTextField.setText(balance.toFriendlyString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
14
src/main/java/io/bitsquare/gui/market/BuyController.java
Normal file
14
src/main/java/io/bitsquare/gui/market/BuyController.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package io.bitsquare.gui.market;
|
||||
|
||||
import io.bitsquare.trade.Direction;
|
||||
|
||||
public class BuyController extends SellController
|
||||
{
|
||||
@Override
|
||||
protected void applyDirection()
|
||||
{
|
||||
//tabPane.getSelectionModel().select(0);
|
||||
orderBookController.applyDirection(Direction.BUY);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,4 +4,4 @@
|
|||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<TabPane xmlns:fx="http://javafx.com/fxml/1" fx:id="tabPane" AnchorPane.bottomAnchor="0.0"
|
||||
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
||||
fx:controller="io.bitsquare.gui.market.MarketController"/>
|
||||
fx:controller="io.bitsquare.gui.market.BuyController"/>
|
|
@ -1,135 +0,0 @@
|
|||
package io.bitsquare.gui.market;
|
||||
|
||||
import io.bitsquare.di.GuiceFXMLLoader;
|
||||
import io.bitsquare.gui.ChildController;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.gui.NavigationItem;
|
||||
import io.bitsquare.gui.market.orderbook.OrderBookController;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
|
||||
public class MarketController implements Initializable, NavigationController, ChildController
|
||||
{
|
||||
private boolean orderbookCreated;
|
||||
|
||||
private OrderBookController orderBookController;
|
||||
|
||||
@FXML
|
||||
private TabPane tabPane;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: Initializable
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
navigateToView(NavigationItem.ORDER_BOOK);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: NavigationController
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Override
|
||||
public ChildController navigateToView(NavigationItem navigationItem)
|
||||
{
|
||||
|
||||
if (navigationItem == NavigationItem.ORDER_BOOK && orderbookCreated)
|
||||
{
|
||||
tabPane.getSelectionModel().select(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
|
||||
try
|
||||
{
|
||||
final Parent view = loader.load();
|
||||
ChildController childController = loader.getController();
|
||||
childController.setNavigationController(this);
|
||||
|
||||
if (childController instanceof OrderBookController)
|
||||
{
|
||||
orderBookController = (OrderBookController) childController;
|
||||
}
|
||||
|
||||
String tabLabel;
|
||||
switch (navigationItem)
|
||||
{
|
||||
case CREATE_OFFER:
|
||||
tabLabel = "Create offer";
|
||||
break;
|
||||
case TAKE_OFFER:
|
||||
tabLabel = "Take offer";
|
||||
break;
|
||||
default:
|
||||
tabLabel = "Orderbook";
|
||||
break;
|
||||
}
|
||||
final Tab tab = new Tab(tabLabel);
|
||||
tab.setContent(view);
|
||||
tabPane.getTabs().add(tab);
|
||||
|
||||
if (navigationItem == NavigationItem.ORDER_BOOK)
|
||||
{
|
||||
tab.setClosable(false);
|
||||
orderbookCreated = true;
|
||||
}
|
||||
|
||||
tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1);
|
||||
|
||||
return childController;
|
||||
} catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: ChildController
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void setNavigationController(NavigationController navigationController)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
if (orderBookController != null)
|
||||
{
|
||||
orderBookController.cleanup();
|
||||
orderBookController = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setter
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setDirection(Direction direction)
|
||||
{
|
||||
tabPane.getSelectionModel().select(0);
|
||||
if (orderBookController != null)
|
||||
{
|
||||
orderBookController.setDirection(direction);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
143
src/main/java/io/bitsquare/gui/market/SellController.java
Normal file
143
src/main/java/io/bitsquare/gui/market/SellController.java
Normal file
|
@ -0,0 +1,143 @@
|
|||
package io.bitsquare.gui.market;
|
||||
|
||||
import io.bitsquare.di.GuiceFXMLLoader;
|
||||
import io.bitsquare.gui.ChildController;
|
||||
import io.bitsquare.gui.NavigationController;
|
||||
import io.bitsquare.gui.NavigationItem;
|
||||
import io.bitsquare.gui.components.ValidatingTextField;
|
||||
import io.bitsquare.gui.market.orderbook.OrderBookController;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public class SellController implements Initializable, NavigationController, ChildController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(SellController.class);
|
||||
|
||||
protected OrderBookController orderBookController;
|
||||
protected GuiceFXMLLoader orderBookLoader;
|
||||
|
||||
@FXML
|
||||
protected TabPane tabPane;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: Initializable
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
// TODO find better solution
|
||||
// Textfield focus out triggers validation, use runLater as quick fix...
|
||||
tabPane.getSelectionModel().selectedIndexProperty().addListener((observableValue) -> Platform.runLater(() -> ValidatingTextField.hidePopover()));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: NavigationController
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public ChildController navigateToView(NavigationItem navigationItem)
|
||||
{
|
||||
if (navigationItem == NavigationItem.ORDER_BOOK)
|
||||
{
|
||||
return loadOrderBook();
|
||||
}
|
||||
else
|
||||
{
|
||||
checkArgument(navigationItem.equals(NavigationItem.CREATE_OFFER) || navigationItem.equals(NavigationItem.TAKE_OFFER));
|
||||
|
||||
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times in different graphs
|
||||
GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
|
||||
try
|
||||
{
|
||||
final Parent view = loader.load();
|
||||
ChildController childController = loader.getController();
|
||||
childController.setNavigationController(this);
|
||||
|
||||
String tabLabel = navigationItem.equals(NavigationItem.CREATE_OFFER) ? "Create offer" : "Take offer";
|
||||
final Tab tab = new Tab(tabLabel);
|
||||
tab.setContent(view);
|
||||
tabPane.getTabs().add(tab);
|
||||
tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1);
|
||||
|
||||
return childController;
|
||||
} catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: ChildController
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void setNavigationController(NavigationController navigationController)
|
||||
{
|
||||
navigateToView(NavigationItem.ORDER_BOOK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup()
|
||||
{
|
||||
if (orderBookController != null)
|
||||
{
|
||||
orderBookController.cleanup();
|
||||
orderBookController = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected void applyDirection()
|
||||
{
|
||||
orderBookController.applyDirection(Direction.SELL);
|
||||
}
|
||||
|
||||
protected ChildController loadOrderBook()
|
||||
{
|
||||
// Orderbook must not be cached by GuiceFXMLLoader as we use 2 instances for sell and buy screens.
|
||||
if (orderBookLoader == null)
|
||||
{
|
||||
orderBookLoader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.ORDER_BOOK.getFxmlUrl()), false);
|
||||
try
|
||||
{
|
||||
final Parent view = orderBookLoader.load();
|
||||
final Tab tab = new Tab("Orderbook");
|
||||
tab.setClosable(false);
|
||||
tab.setContent(view);
|
||||
tabPane.getTabs().add(tab);
|
||||
} catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
orderBookController = orderBookLoader.getController();
|
||||
orderBookController.setNavigationController(this);
|
||||
applyDirection();
|
||||
return orderBookController;
|
||||
}
|
||||
|
||||
}
|
||||
|
7
src/main/java/io/bitsquare/gui/market/SellView.fxml
Normal file
7
src/main/java/io/bitsquare/gui/market/SellView.fxml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.TabPane?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<TabPane xmlns:fx="http://javafx.com/fxml/1" fx:id="tabPane" AnchorPane.bottomAnchor="0.0"
|
||||
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
||||
fx:controller="io.bitsquare.gui.market.SellController"/>
|
|
@ -77,6 +77,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
|
|||
final ViewModel viewModel = new ViewModel();
|
||||
private final double collateral;
|
||||
private Direction direction;
|
||||
private AddressEntry addressEntry;
|
||||
|
||||
@FXML private AnchorPane rootContainer;
|
||||
@FXML private Label buyLabel, confirmationLabel, txTitleLabel, collateralLabel;
|
||||
|
@ -137,17 +138,13 @@ public class CreateOfferController implements Initializable, ChildController, Hi
|
|||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
|
||||
// Node wrappedButton = Borders.wrap(button).etchedBorder().buildAll()
|
||||
|
||||
|
||||
setupBindings();
|
||||
setupValidation();
|
||||
|
||||
//TODO
|
||||
if (walletFacade.getWallet() != null)
|
||||
{
|
||||
AddressEntry addressEntry = walletFacade.getUnusedTradeAddressInfo();
|
||||
addressEntry = walletFacade.getUnusedTradeAddressInfo();
|
||||
addressTextField.setAddress(addressEntry.getAddress().toString());
|
||||
|
||||
balanceTextField.setAddress(addressEntry.getAddress());
|
||||
|
@ -215,11 +212,18 @@ public class CreateOfferController implements Initializable, ChildController, Hi
|
|||
|
||||
placeOfferButton.visibleProperty().bind(viewModel.isOfferPlacedScreen.not());
|
||||
closeButton.visibleProperty().bind(viewModel.isOfferPlacedScreen);
|
||||
|
||||
//TODO
|
||||
/* progressIndicator.visibleProperty().bind(viewModel.isOfferPlacedScreen);
|
||||
confirmationLabel.visibleProperty().bind(viewModel.isOfferPlacedScreen);
|
||||
txTitleLabel.visibleProperty().bind(viewModel.isOfferPlacedScreen);
|
||||
transactionIdTextField.visibleProperty().bind(viewModel.isOfferPlacedScreen);
|
||||
*/
|
||||
|
||||
placeOfferButton.disableProperty().bind(amountTextField.isValidProperty()
|
||||
.and(minAmountTextField.isValidProperty())
|
||||
.and(volumeTextField.isValidProperty())
|
||||
.and(priceTextField.isValidProperty()).not());
|
||||
}
|
||||
|
||||
private void setupValidation()
|
||||
|
@ -258,7 +262,7 @@ public class CreateOfferController implements Initializable, ChildController, Hi
|
|||
priceTextField.focusedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
// only on focus out and ignore focus loss from window
|
||||
if (!newValue && priceTextField.getScene() != null && priceTextField.getScene().getWindow().isFocused())
|
||||
volumeTextField.reValidate();
|
||||
volumeTextField.reValidate();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -302,20 +306,30 @@ public class CreateOfferController implements Initializable, ChildController, Hi
|
|||
@FXML
|
||||
public void onPlaceOffer()
|
||||
{
|
||||
viewModel.isPlaceOfferButtonDisabled.set(true);
|
||||
amountTextField.reValidate();
|
||||
minAmountTextField.reValidate();
|
||||
volumeTextField.reValidate();
|
||||
priceTextField.reValidate();
|
||||
|
||||
tradeManager.requestPlaceOffer(direction,
|
||||
BitSquareFormatter.parseToDouble(viewModel.price.get()),
|
||||
BitSquareFormatter.parseToCoin(viewModel.amount.get()),
|
||||
BitSquareFormatter.parseToCoin(viewModel.minAmount.get()),
|
||||
(transaction) -> {
|
||||
viewModel.isOfferPlacedScreen.set(true);
|
||||
viewModel.transactionId.set(transaction.getHashAsString());
|
||||
},
|
||||
errorMessage -> {
|
||||
Popups.openErrorPopup("An error occurred", errorMessage);
|
||||
viewModel.isPlaceOfferButtonDisabled.set(false);
|
||||
});
|
||||
//balanceTextField.getBalance()
|
||||
|
||||
if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() && amountTextField.getIsValid())
|
||||
{
|
||||
viewModel.isPlaceOfferButtonDisabled.set(true);
|
||||
|
||||
tradeManager.requestPlaceOffer(direction,
|
||||
BitSquareFormatter.parseToDouble(viewModel.price.get()),
|
||||
BitSquareFormatter.parseToCoin(viewModel.amount.get()),
|
||||
BitSquareFormatter.parseToCoin(viewModel.minAmount.get()),
|
||||
(transaction) -> {
|
||||
viewModel.isOfferPlacedScreen.set(true);
|
||||
viewModel.transactionId.set(transaction.getHashAsString());
|
||||
},
|
||||
errorMessage -> {
|
||||
Popups.openErrorPopup("An error occurred", errorMessage);
|
||||
viewModel.isPlaceOfferButtonDisabled.set(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" fx:id="rootContainer" prefHeight="500" prefWidth="800" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"
|
||||
AnchorPane.topAnchor="10.0" xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.market.createOffer.CreateOfferController">
|
||||
<AnchorPane fx:id="rootContainer" prefHeight="500" prefWidth="800" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"
|
||||
AnchorPane.topAnchor="10.0" xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.market.createOffer.CreateOfferController" xmlns:fx="http://javafx.com/fxml/1" >
|
||||
|
||||
<GridPane hgap="5.0" vgap="5.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
|
||||
|
||||
|
@ -63,7 +63,7 @@
|
|||
|
||||
<!-- button -->
|
||||
<VSpacer GridPane.rowIndex="7" prefHeight="10"/>
|
||||
<Button GridPane.rowIndex="8" GridPane.columnIndex="1" fx:id="placeOfferButton" onAction="#onPlaceOffer" defaultButton="true" text="Place offer"/>
|
||||
<Button GridPane.rowIndex="8" GridPane.columnIndex="1" fx:id="placeOfferButton" onAction="#onPlaceOffer" disable="true" defaultButton="true" text="Place offer"/>
|
||||
<Button GridPane.rowIndex="8" GridPane.columnIndex="1" fx:id="closeButton" onAction="#onClose" visible="false" defaultButton="true" focusTraversable="false" text="Close"/>
|
||||
|
||||
|
||||
|
|
|
@ -92,15 +92,16 @@ public class OrderBookController implements Initializable, ChildController
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Persistence persistence)
|
||||
private OrderBookController(OrderBook orderBook, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Persistence persistence)
|
||||
{
|
||||
this.orderBook = orderBook;
|
||||
this.orderBookFilter = orderBookFilter;
|
||||
this.user = user;
|
||||
this.messageFacade = messageFacade;
|
||||
this.walletFacade = walletFacade;
|
||||
this.settings = settings;
|
||||
this.persistence = persistence;
|
||||
|
||||
this.orderBookFilter = new OrderBookFilter();
|
||||
}
|
||||
|
||||
|
||||
|
@ -111,12 +112,15 @@ public class OrderBookController implements Initializable, ChildController
|
|||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb)
|
||||
{
|
||||
orderBook.init();
|
||||
|
||||
// init table
|
||||
setCountryColumnCellFactory();
|
||||
setBankAccountTypeColumnCellFactory();
|
||||
setDirectionColumnCellFactory();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
orderBook.init();
|
||||
offerList = orderBook.getOfferList();
|
||||
offerList.comparatorProperty().bind(orderBookTable.comparatorProperty());
|
||||
orderBookTable.setItems(offerList);
|
||||
|
@ -178,8 +182,9 @@ public class OrderBookController implements Initializable, ChildController
|
|||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setDirection(Direction direction)
|
||||
public void applyDirection(Direction direction)
|
||||
{
|
||||
init();
|
||||
orderBookTable.getSelectionModel().clearSelection();
|
||||
price.setText("");
|
||||
orderBookFilter.setDirection(direction);
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory;
|
|||
public class BtcValidator extends NumberValidator
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(BtcValidator.class);
|
||||
private ValidationResult overriddenValidationResult;
|
||||
private ValidationResult externalValidationResult;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -23,6 +23,9 @@ public class BtcValidator extends NumberValidator
|
|||
@Override
|
||||
public ValidationResult validate(String input)
|
||||
{
|
||||
if (externalValidationResult != null)
|
||||
return externalValidationResult;
|
||||
|
||||
ValidationResult result = validateIfNotEmpty(input);
|
||||
if (result.isValid)
|
||||
{
|
||||
|
@ -37,23 +40,21 @@ public class BtcValidator extends NumberValidator
|
|||
.and(validateIfNotFractionalBtcValue(input))
|
||||
.and(validateIfNotExceedsMaxBtcValue(input));
|
||||
}
|
||||
|
||||
if (overriddenValidationResult != null)
|
||||
return overriddenValidationResult;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to integrate external validation (e.g. for MinAmount/Amount)
|
||||
* TODO Might be improved but does the job for now...
|
||||
* TODO To be improved but does the job for now...
|
||||
*
|
||||
* @param overriddenValidationResult
|
||||
* @param externalValidationResult
|
||||
*/
|
||||
public void overrideResult(ValidationResult overriddenValidationResult)
|
||||
public void overrideResult(ValidationResult externalValidationResult)
|
||||
{
|
||||
this.overriddenValidationResult = overriddenValidationResult;
|
||||
this.externalValidationResult = externalValidationResult;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected methods
|
||||
|
|
|
@ -25,7 +25,6 @@ public abstract class NumberValidator
|
|||
// Protected methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
protected ValidationResult validateIfNotEmpty(String input)
|
||||
{
|
||||
if (input == null || input.length() == 0)
|
||||
|
|
|
@ -140,7 +140,7 @@ public class OrderBook implements OrderBookListener
|
|||
//noinspection UnnecessaryLocalVariable
|
||||
boolean result = currencyResult && countryResult && languageResult && amountResult && directionResult && priceResult && arbitratorResult;
|
||||
|
||||
/*
|
||||
/*
|
||||
log.debug("result = " + result +
|
||||
", currencyResult = " + currencyResult +
|
||||
", countryResult = " + countryResult +
|
||||
|
@ -149,8 +149,8 @@ public class OrderBook implements OrderBookListener
|
|||
", directionResult = " + directionResult +
|
||||
", priceResult = " + priceResult +
|
||||
", arbitratorResult = " + arbitratorResult
|
||||
);
|
||||
|
||||
);*/
|
||||
/*
|
||||
log.debug("currentBankAccount.getCurrency() = " + currentBankAccount.getCurrency() +
|
||||
", offer.getCurrency() = " + offer.getCurrency());
|
||||
log.debug("offer.getCountryLocale() = " + offer.getBankAccountCountryLocale() +
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package io.bitsquare.trade.protocol.createoffer.tasks;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.Restritions;
|
||||
import io.bitsquare.trade.Offer;
|
||||
import io.bitsquare.trade.handlers.FaultHandler;
|
||||
|
@ -37,17 +39,22 @@ public class ValidateOffer
|
|||
|
||||
checkArgument(offer.getAcceptedCountries().size() > 0);
|
||||
checkArgument(offer.getAcceptedLanguageLocales().size() > 0);
|
||||
checkArgument(offer.getAmount().isGreaterThan(Restritions.MIN_TRADE_AMOUNT));
|
||||
checkArgument(offer.getMinAmount().compareTo(Restritions.MIN_TRADE_AMOUNT) >= 0);
|
||||
checkArgument(offer.getAmount().compareTo(Restritions.MIN_TRADE_AMOUNT) >= 0);
|
||||
checkArgument(offer.getAmount().compareTo(offer.getMinAmount()) >= 0);
|
||||
checkArgument(offer.getCollateral() > 0);
|
||||
checkArgument(offer.getPrice() > 0);
|
||||
|
||||
// TODO check balance
|
||||
Coin collateralAsCoin = offer.getAmount().divide((long) (1d / offer.getCollateral()));
|
||||
Coin totalsToFund = collateralAsCoin.add(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE));
|
||||
// getAddressInfoByTradeID(offerId)
|
||||
// TODO when offer is flattened continue here...
|
||||
|
||||
resultHandler.onResult();
|
||||
} catch (Throwable t)
|
||||
{
|
||||
faultHandler.onFault("Offer validation failed with exception: " + t.getMessage(), t);
|
||||
faultHandler.onFault("Offer validation failed.", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue