From 7d0676a9952007c65ac18e533199de5eaf8f0bab Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 May 2014 00:30:55 +0200 Subject: [PATCH] formatting, rename packages --- src/main/java/io/bitsquare/BitSquare.java | 50 +- .../io/bitsquare/btc/BlockChainFacade.java | 6 +- .../io/bitsquare/gui/ChildController.java | 1 - .../java/io/bitsquare/gui/MainController.java | 54 +- .../bitsquare/gui/NavigationController.java | 9 +- .../MarketController.java} | 219 +++-- .../TradeView.fxml => market/MarketView.fxml} | 2 +- .../offer/CreateOfferController.java | 450 ++++----- .../offer/CreateOfferView.fxml | 2 +- .../orderbook/OrderBookController.java | 696 +++++++------- .../orderbook/OrderBookListItem.java | 2 +- .../orderbook/OrderBookView.fxml | 2 +- .../trade/TradeController.java} | 875 +++++++++--------- .../trade/TradeView.fxml} | 4 +- .../bitsquare/gui/setup/SetupController.java | 2 +- .../java/io/bitsquare/gui/util/Formatter.java | 2 - .../java/io/bitsquare/gui/util/Popups.java | 16 + .../java/io/bitsquare/settings/Settings.java | 17 +- .../java/io/bitsquare/storage/Storage.java | 63 +- .../java/io/bitsquare/trade/Contract.java | 45 +- src/main/java/io/bitsquare/trade/Trading.java | 3 +- .../trade/orderbook/MockOrderBook.java | 4 +- .../bitsquare/trade/orderbook/OrderBook.java | 56 +- .../trade/orderbook/OrderBookFilter.java | 16 +- src/main/java/io/bitsquare/user/User.java | 64 +- 25 files changed, 1354 insertions(+), 1306 deletions(-) rename src/main/java/io/bitsquare/gui/{trade/TradeController.java => market/MarketController.java} (60%) rename src/main/java/io/bitsquare/gui/{trade/TradeView.fxml => market/MarketView.fxml} (82%) rename src/main/java/io/bitsquare/gui/{trade => market}/offer/CreateOfferController.java (96%) rename src/main/java/io/bitsquare/gui/{trade => market}/offer/CreateOfferView.fxml (96%) rename src/main/java/io/bitsquare/gui/{trade => market}/orderbook/OrderBookController.java (93%) rename src/main/java/io/bitsquare/gui/{trade => market}/orderbook/OrderBookListItem.java (96%) rename src/main/java/io/bitsquare/gui/{trade => market}/orderbook/OrderBookView.fxml (97%) rename src/main/java/io/bitsquare/gui/{trade/tradeprocess/TradeProcessController.java => market/trade/TradeController.java} (55%) rename src/main/java/io/bitsquare/gui/{trade/tradeprocess/TradeProcessView.fxml => market/trade/TradeView.fxml} (92%) create mode 100644 src/main/java/io/bitsquare/gui/util/Popups.java diff --git a/src/main/java/io/bitsquare/BitSquare.java b/src/main/java/io/bitsquare/BitSquare.java index cd924f5464..fd5aa9a94f 100644 --- a/src/main/java/io/bitsquare/BitSquare.java +++ b/src/main/java/io/bitsquare/BitSquare.java @@ -2,6 +2,8 @@ package io.bitsquare; import com.google.inject.Guice; import com.google.inject.Injector; +import io.bitsquare.bank.BankAccount; +import io.bitsquare.bank.BankAccountType; import io.bitsquare.btc.WalletFacade; import io.bitsquare.di.BitSquareModule; import io.bitsquare.di.GuiceFXMLLoader; @@ -10,6 +12,7 @@ import io.bitsquare.settings.Settings; import io.bitsquare.storage.Storage; import io.bitsquare.user.Arbitrator; import io.bitsquare.user.User; +import io.bitsquare.util.MockData; import javafx.application.Application; import javafx.scene.Parent; import javafx.scene.Scene; @@ -100,32 +103,35 @@ public class BitSquare extends Application storage.write(settings.getClass().getName(), settings); - /* - BankAccount bankAccount1 = new BankAccount(new BankAccountType(BankAccountType.BankAccountTypeEnum.SEPA,"Iban", "Bic"), - MockData.getCurrencies().get(0), - MockData.getLocales().get(0), - "Main account", - "Manfred Karrer", - "564613242346", - "23432432434" - ); - BankAccount bankAccount2 = new BankAccount(new BankAccountType(BankAccountType.BankAccountTypeEnum.OK_PAY,"Number", "ID"), - MockData.getCurrencies().get(0), - MockData.getLocales().get(0), - "OK account", - "Manfred Karrer", - "22312123123123123", - "asdasdasdas" - ); - user.addBankAccount(bankAccount2); - user.addBankAccount(bankAccount1); - user.setAccountID(UUID.randomUUID().toString()); - storage.write(user.getClass().getName(), user); - */ + initMockUser(storage, user); } else { settings.updateFromStorage(savedSettings); } } + + private void initMockUser(Storage storage, User user) + { + BankAccount bankAccount1 = new BankAccount(new BankAccountType(BankAccountType.BankAccountTypeEnum.SEPA, "Iban", "Bic"), + MockData.getCurrencies().get(0), + MockData.getLocales().get(0), + "Main account", + "Manfred Karrer", + "564613242346", + "23432432434" + ); + BankAccount bankAccount2 = new BankAccount(new BankAccountType(BankAccountType.BankAccountTypeEnum.OK_PAY, "Number", "ID"), + MockData.getCurrencies().get(0), + MockData.getLocales().get(0), + "OK account", + "Manfred Karrer", + "22312123123123123", + "asdasdasdas" + ); + user.addBankAccount(bankAccount2); + user.addBankAccount(bankAccount1); + user.setAccountID(UUID.randomUUID().toString()); + storage.write(user.getClass().getName(), user); + } } diff --git a/src/main/java/io/bitsquare/btc/BlockChainFacade.java b/src/main/java/io/bitsquare/btc/BlockChainFacade.java index e53e86f85a..a8f82a1fe4 100644 --- a/src/main/java/io/bitsquare/btc/BlockChainFacade.java +++ b/src/main/java/io/bitsquare/btc/BlockChainFacade.java @@ -18,12 +18,14 @@ public class BlockChainFacade public boolean verifyEmbeddedData(String address) { + // tx id 76982adc582657b2eb68f3e43341596a68aadc4ef6b9590e88e93387d4d5d1f9 + // address: mjbxLbuVpU1cNXLJbrJZyirYwweoRPVVTj return true; - /* + /* if (findAddressInBlockChain(address) && isFeePayed(address)) return getDataForTxWithAddress(address) != null; else - return true; */ + return true; */ } private boolean findAddressInBlockChain(String address) diff --git a/src/main/java/io/bitsquare/gui/ChildController.java b/src/main/java/io/bitsquare/gui/ChildController.java index b7ba6eadd8..2d44b2fd25 100644 --- a/src/main/java/io/bitsquare/gui/ChildController.java +++ b/src/main/java/io/bitsquare/gui/ChildController.java @@ -3,5 +3,4 @@ package io.bitsquare.gui; public interface ChildController { void setNavigationController(NavigationController navigationController); - } diff --git a/src/main/java/io/bitsquare/gui/MainController.java b/src/main/java/io/bitsquare/gui/MainController.java index 17ea9e1fa7..db5eef0527 100644 --- a/src/main/java/io/bitsquare/gui/MainController.java +++ b/src/main/java/io/bitsquare/gui/MainController.java @@ -5,8 +5,8 @@ import io.bitsquare.bank.BankAccount; import io.bitsquare.btc.WalletFacade; import io.bitsquare.di.GuiceFXMLLoader; import io.bitsquare.gui.components.NetworkSyncPane; +import io.bitsquare.gui.market.MarketController; import io.bitsquare.gui.setup.SetupController; -import io.bitsquare.gui.trade.TradeController; import io.bitsquare.gui.util.Formatter; import io.bitsquare.gui.util.Icons; import io.bitsquare.gui.util.Localisation; @@ -56,6 +56,11 @@ public class MainController implements Initializable, NavigationController, Wall @FXML public AnchorPane anchorPane; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + @Inject public MainController(User user, WalletFacade walletFacade) { @@ -63,6 +68,11 @@ public class MainController implements Initializable, NavigationController, Wall this.walletFacade = walletFacade; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: Initializable + /////////////////////////////////////////////////////////////////////////////////////////// + @Override public void initialize(URL url, ResourceBundle rb) { @@ -87,6 +97,10 @@ public class MainController implements Initializable, NavigationController, Wall } + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: NavigationController + /////////////////////////////////////////////////////////////////////////////////////////// + @Override public ChildController navigateToView(String fxmlView, String title) { @@ -102,9 +116,9 @@ public class MainController implements Initializable, NavigationController, Wall return null; } - if (childController instanceof TradeController) + if (childController instanceof MarketController) { - ((TradeController) childController).cleanup(); + ((MarketController) childController).cleanup(); } final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle()); @@ -122,6 +136,11 @@ public class MainController implements Initializable, NavigationController, Wall return null; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: WalletFacade.DownloadListener + /////////////////////////////////////////////////////////////////////////////////////////// + @Override public void progress(double percent, int blocksSoFar, Date date) { @@ -136,15 +155,10 @@ public class MainController implements Initializable, NavigationController, Wall Platform.runLater(networkSyncPane::doneDownload); } - public ChildController navigateToView(String fxmlView, Direction direction) - { - childController = navigateToView(fxmlView, direction == Direction.BUY ? "Orderbook Buy" : "Orderbook Sell"); - if (childController instanceof TradeController && direction != null) - { - ((TradeController) childController).setDirection(direction); - } - return childController; - } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private methods + /////////////////////////////////////////////////////////////////////////////////////////// private void buildSetupView() { @@ -165,8 +179,8 @@ public class MainController implements Initializable, NavigationController, Wall toggleGroup = new ToggleGroup(); ToggleButton homeButton = addNavButton(leftNavPane, "Overview", Icons.HOME, Icons.HOME, NavigationController.HOME); - ToggleButton buyButton = addNavButton(leftNavPane, "Buy BTC", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE, NavigationController.TRADE, Direction.BUY); - ToggleButton sellButton = addNavButton(leftNavPane, "Sell BTC", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE, NavigationController.TRADE, Direction.SELL); + ToggleButton buyButton = addNavButton(leftNavPane, "Buy BTC", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE, NavigationController.MARKET, Direction.BUY); + ToggleButton sellButton = addNavButton(leftNavPane, "Sell BTC", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE, NavigationController.MARKET, Direction.SELL); addNavButton(leftNavPane, "Orders", Icons.ORDERS, Icons.ORDERS, NavigationController.ORDERS); addNavButton(leftNavPane, "History", Icons.HISTORY, Icons.HISTORY, NavigationController.HISTORY); addNavButton(leftNavPane, "Funds", Icons.FUNDS, Icons.FUNDS, NavigationController.FUNDS); @@ -201,12 +215,18 @@ public class MainController implements Initializable, NavigationController, Wall prevToggleButtonIcon = ((ImageView) (toggleButton.getGraphic())).getImage(); ((ImageView) (toggleButton.getGraphic())).setImage(Icons.getIconImage(iconIdActivated)); - if (childController instanceof TradeController && direction != null) + if (childController instanceof MarketController && direction != null) { - ((TradeController) childController).setDirection(direction); + ((MarketController) childController).setDirection(direction); } else - navigateToView(navTarget, direction); + { + childController = navigateToView(navTarget, direction == Direction.BUY ? "Orderbook Buy" : "Orderbook Sell"); + if (childController instanceof MarketController && direction != null) + { + ((MarketController) childController).setDirection(direction); + } + } prevToggleButton = toggleButton; diff --git a/src/main/java/io/bitsquare/gui/NavigationController.java b/src/main/java/io/bitsquare/gui/NavigationController.java index 683eeb11a7..2849d43a67 100644 --- a/src/main/java/io/bitsquare/gui/NavigationController.java +++ b/src/main/java/io/bitsquare/gui/NavigationController.java @@ -2,20 +2,19 @@ package io.bitsquare.gui; public interface NavigationController { - public static final String SETUP = "/io/bitsquare/gui/setup/SetupView.fxml"; public static final String HOME = "/io/bitsquare/gui/home/HomeView.fxml"; - public static final String TRADE = "/io/bitsquare/gui/trade/TradeView.fxml"; + public static final String MARKET = "/io/bitsquare/gui/market/MarketView.fxml"; public static final String ORDERS = "/io/bitsquare/gui/orders/OrdersView.fxml"; public static final String FUNDS = "/io/bitsquare/gui/funds/FundsView.fxml"; public static final String MSG = "/io/bitsquare/gui/msg/MsgView.fxml"; public static final String HISTORY = "/io/bitsquare/gui/history/HistoryView.fxml"; public static final String SETTINGS = "/io/bitsquare/gui/settings/SettingsView.fxml"; - public static final String TRADE__ORDER_BOOK = "/io/bitsquare/gui/trade/orderbook/OrderBookView.fxml"; - public static final String TRADE__PROCESS = "/io/bitsquare/gui/trade/tradeprocess/TradeProcessView.fxml"; - public static final String TRADE__CREATE_OFFER = "/io/bitsquare/gui/trade/offer/CreateOfferView.fxml"; + public static final String ORDER_BOOK = "/io/bitsquare/gui/market/orderbook/OrderBookView.fxml"; + public static final String TRADE = "/io/bitsquare/gui/market/trade/TradeView.fxml"; + public static final String CREATE_OFFER = "/io/bitsquare/gui/market/offer/CreateOfferView.fxml"; ChildController navigateToView(String fxmlView, String title); } diff --git a/src/main/java/io/bitsquare/gui/trade/TradeController.java b/src/main/java/io/bitsquare/gui/market/MarketController.java similarity index 60% rename from src/main/java/io/bitsquare/gui/trade/TradeController.java rename to src/main/java/io/bitsquare/gui/market/MarketController.java index 8492e633e2..3c69dab6cb 100644 --- a/src/main/java/io/bitsquare/gui/trade/TradeController.java +++ b/src/main/java/io/bitsquare/gui/market/MarketController.java @@ -1,97 +1,122 @@ -package io.bitsquare.gui.trade; - -import io.bitsquare.di.GuiceFXMLLoader; -import io.bitsquare.gui.ChildController; -import io.bitsquare.gui.NavigationController; -import io.bitsquare.gui.trade.orderbook.OrderBookController; -import io.bitsquare.gui.util.Localisation; -import io.bitsquare.trade.Direction; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.Tab; -import javafx.scene.control.TabPane; -import javafx.scene.layout.Pane; - -import java.io.IOException; -import java.net.URL; -import java.util.ResourceBundle; - -public class TradeController implements Initializable, NavigationController, ChildController -{ - @FXML - private TabPane tabPane; - - private ChildController childController; - private boolean orderbookCreated; - private NavigationController navigationController; - private OrderBookController orderBookController; - - @Override - public ChildController navigateToView(String fxmlView, String title) - { - if (fxmlView.equals(NavigationController.TRADE__ORDER_BOOK) && orderbookCreated) - { - tabPane.getSelectionModel().select(0); - return null; - } - - final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle()); - try - { - Pane view = loader.load(); - childController = loader.getController(); - childController.setNavigationController(this); - - if (childController instanceof OrderBookController) - orderBookController = (OrderBookController) childController; - - Tab tab = new Tab(title); - tab.setContent(view); - tabPane.getTabs().add(tab); - - if (fxmlView.equals(NavigationController.TRADE__ORDER_BOOK)) - { - tab.setClosable(false); - orderbookCreated = true; - } - - tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1); - - return childController; - } catch (IOException e) - { - e.printStackTrace(); - } - return null; - } - - @Override - public void initialize(URL url, ResourceBundle rb) - { - navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook"); - } - - @Override - public void setNavigationController(NavigationController navigationController) - { - - this.navigationController = navigationController; - } - - public void setDirection(Direction direction) - { - tabPane.getSelectionModel().select(0); - orderBookController.setDirection(direction); - } - - public void cleanup() - { - if (orderBookController != null) - { - orderBookController.cleanup(); - orderBookController = null; - } - } - -} - +package io.bitsquare.gui.market; + +import io.bitsquare.di.GuiceFXMLLoader; +import io.bitsquare.gui.ChildController; +import io.bitsquare.gui.NavigationController; +import io.bitsquare.gui.market.orderbook.OrderBookController; +import io.bitsquare.gui.util.Localisation; +import io.bitsquare.trade.Direction; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.layout.Pane; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +public class MarketController implements Initializable, NavigationController, ChildController +{ + private ChildController childController; + private boolean orderbookCreated; + private NavigationController navigationController; + private OrderBookController orderBookController; + + @FXML + private TabPane tabPane; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: Initializable + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void initialize(URL url, ResourceBundle rb) + { + navigateToView(NavigationController.ORDER_BOOK, "Orderbook"); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: NavigationController + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public ChildController navigateToView(String fxmlView, String title) + { + if (fxmlView.equals(NavigationController.ORDER_BOOK) && orderbookCreated) + { + tabPane.getSelectionModel().select(0); + return null; + } + + final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle()); + try + { + Pane view = loader.load(); + childController = loader.getController(); + childController.setNavigationController(this); + + if (childController instanceof OrderBookController) + orderBookController = (OrderBookController) childController; + + Tab tab = new Tab(title); + tab.setContent(view); + tabPane.getTabs().add(tab); + + if (fxmlView.equals(NavigationController.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) + { + + this.navigationController = navigationController; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public methods + /////////////////////////////////////////////////////////////////////////////////////////// + + public void cleanup() + { + if (orderBookController != null) + { + orderBookController.cleanup(); + orderBookController = null; + } + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Setter + /////////////////////////////////////////////////////////////////////////////////////////// + + public void setDirection(Direction direction) + { + tabPane.getSelectionModel().select(0); + orderBookController.setDirection(direction); + } + +} + diff --git a/src/main/java/io/bitsquare/gui/trade/TradeView.fxml b/src/main/java/io/bitsquare/gui/market/MarketView.fxml similarity index 82% rename from src/main/java/io/bitsquare/gui/trade/TradeView.fxml rename to src/main/java/io/bitsquare/gui/market/MarketView.fxml index 47c670d0fa..5292a8634d 100644 --- a/src/main/java/io/bitsquare/gui/trade/TradeView.fxml +++ b/src/main/java/io/bitsquare/gui/market/MarketView.fxml @@ -4,4 +4,4 @@ \ No newline at end of file + fx:controller="io.bitsquare.gui.market.MarketController"/> \ No newline at end of file diff --git a/src/main/java/io/bitsquare/gui/trade/offer/CreateOfferController.java b/src/main/java/io/bitsquare/gui/market/offer/CreateOfferController.java similarity index 96% rename from src/main/java/io/bitsquare/gui/trade/offer/CreateOfferController.java rename to src/main/java/io/bitsquare/gui/market/offer/CreateOfferController.java index 59580bbab9..e1b22c0a56 100644 --- a/src/main/java/io/bitsquare/gui/trade/offer/CreateOfferController.java +++ b/src/main/java/io/bitsquare/gui/market/offer/CreateOfferController.java @@ -1,225 +1,225 @@ -package io.bitsquare.gui.trade.offer; - -import com.google.bitcoin.core.InsufficientMoneyException; -import com.google.inject.Inject; -import io.bitsquare.btc.Fees; -import io.bitsquare.btc.WalletFacade; -import io.bitsquare.gui.ChildController; -import io.bitsquare.gui.NavigationController; -import io.bitsquare.gui.components.ConfirmationComponent; -import io.bitsquare.gui.util.*; -import io.bitsquare.settings.Settings; -import io.bitsquare.trade.Direction; -import io.bitsquare.trade.Offer; -import io.bitsquare.trade.Trading; -import io.bitsquare.trade.orderbook.OrderBookFilter; -import io.bitsquare.user.User; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TabPane; -import javafx.scene.control.TextField; -import javafx.scene.image.Image; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.GridPane; -import org.controlsfx.dialog.Dialogs; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.math.BigInteger; -import java.net.URL; -import java.util.ResourceBundle; - -public class CreateOfferController implements Initializable, ChildController, WalletFacade.WalletListener -{ - private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class); - - private NavigationController navigationController; - private Trading trading; - private WalletFacade walletFacade; - private Settings settings; - private User user; - private Direction direction; - - private Button placeOfferButton; - private int gridRow; - - @FXML - private AnchorPane holderPane; - @FXML - private GridPane formGridPane; - @FXML - public Label buyLabel; - @FXML - public TextField volume, amount, price, minAmount; - - @Inject - public CreateOfferController(Trading trading, WalletFacade walletFacade, Settings settings, User user) - { - this.trading = trading; - this.walletFacade = walletFacade; - this.settings = settings; - this.user = user; - } - - @Override - public void initialize(URL url, ResourceBundle rb) - { - walletFacade.addRegistrationWalletListener(this); - - gridRow = 2; - FormBuilder.addVSpacer(formGridPane, ++gridRow); - FormBuilder.addHeaderLabel(formGridPane, "Offer details:", ++gridRow); - FormBuilder.addTextField(formGridPane, "Bank account type:", Localisation.get(user.getCurrentBankAccount().getBankAccountType().getType().toString()), ++gridRow); - FormBuilder.addTextField(formGridPane, "Bank account currency:", user.getCurrentBankAccount().getCurrency().getCurrencyCode(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Bank account county:", user.getCurrentBankAccount().getCountryLocale().getDisplayCountry(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Accepted countries:", Formatter.countryLocalesToString(settings.getAcceptedCountryLocales()), ++gridRow); - FormBuilder.addTextField(formGridPane, "Accepted languages:", Formatter.languageLocalesToString(settings.getAcceptedLanguageLocales()), ++gridRow); - - FormBuilder.addVSpacer(formGridPane, ++gridRow); - Label placeOfferTitle = FormBuilder.addHeaderLabel(formGridPane, "Place offer:", ++gridRow); - - TextField feeLabel = FormBuilder.addTextField(formGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++gridRow); - feeLabel.setMouseTransparent(true); - - placeOfferButton = new Button("Place offer"); - formGridPane.add(placeOfferButton, 1, ++gridRow); - placeOfferButton.setDefaultButton(true); - - // handlers - amount.textProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) - { - updateVolume(); - } - }); - - price.textProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) - { - updateVolume(); - } - }); - - placeOfferButton.setOnAction(e -> { - - if (inputValid()) - { - Offer offer = new Offer(user.getAccountID(), - user.getMessageID(), - direction, - Converter.stringToDouble(price.getText()), - Converter.stringToDouble(amount.getText()), - Converter.stringToDouble(minAmount.getText()), - user.getCurrentBankAccount().getBankAccountType().getType(), - user.getCurrentBankAccount().getCurrency(), - user.getCurrentBankAccount().getCountryLocale(), - settings.getRandomArbitrator(), - settings.getAcceptedCountryLocales(), - settings.getAcceptedLanguageLocales()); - - try - { - String txID = trading.placeNewOffer(offer); - formGridPane.getChildren().remove(placeOfferButton); - placeOfferTitle.setText("Transaction sent:"); - buildConfirmationView(txID); - } catch (InsufficientMoneyException e1) - { - Dialogs.create() - .title("Not enough money available") - .message("There is not enough money available. Please pay in first to your wallet.") - .nativeTitleBar() - .lightweight() - .showError(); - } - } - }); - } - - - @Override - public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks) - { - log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks); - } - - @Override - public void onCoinsReceived(BigInteger newBalance) - { - log.info("onCoinsReceived " + newBalance); - } - - private void buildConfirmationView(String txID) - { - FormBuilder.addTextField(formGridPane, "Transaction ID:", txID, ++gridRow, false, true); - - ConfirmationComponent confirmationComponent = new ConfirmationComponent(walletFacade, formGridPane, ++gridRow); - - Button closeButton = new Button("Close"); - formGridPane.add(closeButton, 1, ++gridRow); - closeButton.setDefaultButton(true); - - - closeButton.setOnAction(e -> { - TabPane tabPane = ((TabPane) (holderPane.getParent().getParent())); - tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); - - navigationController.navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook"); - }); - } - - - @Override - public void setNavigationController(NavigationController navigationController) - { - this.navigationController = navigationController; - } - - public void setOrderBookFilter(OrderBookFilter orderBookFilter) - { - direction = orderBookFilter.getDirection(); - amount.setText(Formatter.formatPrice(orderBookFilter.getAmount())); - minAmount.setText(Formatter.formatPrice(orderBookFilter.getAmount())); - price.setText(Formatter.formatPrice(orderBookFilter.getPrice())); - - String iconPath = (direction == Direction.BUY) ? Icons.BUY : Icons.SELL; - buyLabel.setText(Formatter.formatDirection(direction, false) + ":"); - updateVolume(); - } - - //TODO - private boolean inputValid() - { - return true; - } - - private void updateVolume() - { - double amountAsDouble = Converter.stringToDouble(amount.getText()); - double priceAsDouble = Converter.stringToDouble(price.getText()); - volume.setText(Formatter.formatPrice(amountAsDouble * priceAsDouble)); - } - - private Image getConfirmIconImage(int numBroadcastPeers, int depthInBlocks) - { - if (depthInBlocks > 0) - return Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks)); - else - return Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers)); - } - - private String getConfirmationsText(int registrationConfirmationNumBroadcastPeers, int registrationConfirmationDepthInBlocks) - { - return registrationConfirmationDepthInBlocks + " confirmation(s) / " + "Seen by " + registrationConfirmationNumBroadcastPeers + " peer(s)"; - } - -} - +package io.bitsquare.gui.market.offer; + +import com.google.bitcoin.core.InsufficientMoneyException; +import com.google.inject.Inject; +import io.bitsquare.btc.Fees; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.gui.ChildController; +import io.bitsquare.gui.NavigationController; +import io.bitsquare.gui.components.ConfirmationComponent; +import io.bitsquare.gui.util.*; +import io.bitsquare.settings.Settings; +import io.bitsquare.trade.Direction; +import io.bitsquare.trade.Offer; +import io.bitsquare.trade.Trading; +import io.bitsquare.trade.orderbook.OrderBookFilter; +import io.bitsquare.user.User; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TabPane; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.GridPane; +import org.controlsfx.dialog.Dialogs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.net.URL; +import java.util.ResourceBundle; + +public class CreateOfferController implements Initializable, ChildController, WalletFacade.WalletListener +{ + private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class); + + private NavigationController navigationController; + private Trading trading; + private WalletFacade walletFacade; + private Settings settings; + private User user; + private Direction direction; + + private Button placeOfferButton; + private int gridRow; + + @FXML + private AnchorPane holderPane; + @FXML + private GridPane formGridPane; + @FXML + public Label buyLabel; + @FXML + public TextField volume, amount, price, minAmount; + + @Inject + public CreateOfferController(Trading trading, WalletFacade walletFacade, Settings settings, User user) + { + this.trading = trading; + this.walletFacade = walletFacade; + this.settings = settings; + this.user = user; + } + + @Override + public void initialize(URL url, ResourceBundle rb) + { + walletFacade.addRegistrationWalletListener(this); + + gridRow = 2; + FormBuilder.addVSpacer(formGridPane, ++gridRow); + FormBuilder.addHeaderLabel(formGridPane, "Offer details:", ++gridRow); + FormBuilder.addTextField(formGridPane, "Bank account type:", Localisation.get(user.getCurrentBankAccount().getBankAccountType().getType().toString()), ++gridRow); + FormBuilder.addTextField(formGridPane, "Bank account currency:", user.getCurrentBankAccount().getCurrency().getCurrencyCode(), ++gridRow); + FormBuilder.addTextField(formGridPane, "Bank account county:", user.getCurrentBankAccount().getCountryLocale().getDisplayCountry(), ++gridRow); + FormBuilder.addTextField(formGridPane, "Accepted countries:", Formatter.countryLocalesToString(settings.getAcceptedCountryLocales()), ++gridRow); + FormBuilder.addTextField(formGridPane, "Accepted languages:", Formatter.languageLocalesToString(settings.getAcceptedLanguageLocales()), ++gridRow); + + FormBuilder.addVSpacer(formGridPane, ++gridRow); + Label placeOfferTitle = FormBuilder.addHeaderLabel(formGridPane, "Place offer:", ++gridRow); + + TextField feeLabel = FormBuilder.addTextField(formGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++gridRow); + feeLabel.setMouseTransparent(true); + + placeOfferButton = new Button("Place offer"); + formGridPane.add(placeOfferButton, 1, ++gridRow); + placeOfferButton.setDefaultButton(true); + + // handlers + amount.textProperty().addListener(new ChangeListener() + { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) + { + updateVolume(); + } + }); + + price.textProperty().addListener(new ChangeListener() + { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) + { + updateVolume(); + } + }); + + placeOfferButton.setOnAction(e -> { + + if (inputValid()) + { + Offer offer = new Offer(user.getAccountID(), + user.getMessageID(), + direction, + Converter.stringToDouble(price.getText()), + Converter.stringToDouble(amount.getText()), + Converter.stringToDouble(minAmount.getText()), + user.getCurrentBankAccount().getBankAccountType().getType(), + user.getCurrentBankAccount().getCurrency(), + user.getCurrentBankAccount().getCountryLocale(), + settings.getRandomArbitrator(), + settings.getAcceptedCountryLocales(), + settings.getAcceptedLanguageLocales()); + + try + { + String txID = trading.placeNewOffer(offer); + formGridPane.getChildren().remove(placeOfferButton); + placeOfferTitle.setText("Transaction sent:"); + buildConfirmationView(txID); + } catch (InsufficientMoneyException e1) + { + Dialogs.create() + .title("Not enough money available") + .message("There is not enough money available. Please pay in first to your wallet.") + .nativeTitleBar() + .lightweight() + .showError(); + } + } + }); + } + + + @Override + public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks) + { + log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks); + } + + @Override + public void onCoinsReceived(BigInteger newBalance) + { + log.info("onCoinsReceived " + newBalance); + } + + private void buildConfirmationView(String txID) + { + FormBuilder.addTextField(formGridPane, "Transaction ID:", txID, ++gridRow, false, true); + + ConfirmationComponent confirmationComponent = new ConfirmationComponent(walletFacade, formGridPane, ++gridRow); + + Button closeButton = new Button("Close"); + formGridPane.add(closeButton, 1, ++gridRow); + closeButton.setDefaultButton(true); + + + closeButton.setOnAction(e -> { + TabPane tabPane = ((TabPane) (holderPane.getParent().getParent())); + tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); + + navigationController.navigateToView(NavigationController.ORDER_BOOK, "Orderbook"); + }); + } + + + @Override + public void setNavigationController(NavigationController navigationController) + { + this.navigationController = navigationController; + } + + public void setOrderBookFilter(OrderBookFilter orderBookFilter) + { + direction = orderBookFilter.getDirection(); + amount.setText(Formatter.formatPrice(orderBookFilter.getAmount())); + minAmount.setText(Formatter.formatPrice(orderBookFilter.getAmount())); + price.setText(Formatter.formatPrice(orderBookFilter.getPrice())); + + String iconPath = (direction == Direction.BUY) ? Icons.BUY : Icons.SELL; + buyLabel.setText(Formatter.formatDirection(direction, false) + ":"); + updateVolume(); + } + + //TODO + private boolean inputValid() + { + return true; + } + + private void updateVolume() + { + double amountAsDouble = Converter.stringToDouble(amount.getText()); + double priceAsDouble = Converter.stringToDouble(price.getText()); + volume.setText(Formatter.formatPrice(amountAsDouble * priceAsDouble)); + } + + private Image getConfirmIconImage(int numBroadcastPeers, int depthInBlocks) + { + if (depthInBlocks > 0) + return Icons.getIconImage(Icons.getIconIDForConfirmations(depthInBlocks)); + else + return Icons.getIconImage(Icons.getIconIDForPeersSeenTx(numBroadcastPeers)); + } + + private String getConfirmationsText(int registrationConfirmationNumBroadcastPeers, int registrationConfirmationDepthInBlocks) + { + return registrationConfirmationDepthInBlocks + " confirmation(s) / " + "Seen by " + registrationConfirmationNumBroadcastPeers + " peer(s)"; + } + +} + diff --git a/src/main/java/io/bitsquare/gui/trade/offer/CreateOfferView.fxml b/src/main/java/io/bitsquare/gui/market/offer/CreateOfferView.fxml similarity index 96% rename from src/main/java/io/bitsquare/gui/trade/offer/CreateOfferView.fxml rename to src/main/java/io/bitsquare/gui/market/offer/CreateOfferView.fxml index 91f0737e4c..fd78330a7b 100644 --- a/src/main/java/io/bitsquare/gui/trade/offer/CreateOfferView.fxml +++ b/src/main/java/io/bitsquare/gui/market/offer/CreateOfferView.fxml @@ -5,7 +5,7 @@ + fx:controller="io.bitsquare.gui.market.offer.CreateOfferController"> diff --git a/src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookController.java b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java similarity index 93% rename from src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookController.java rename to src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java index ae05ff1daf..737db99e78 100644 --- a/src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookController.java +++ b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookController.java @@ -1,348 +1,348 @@ -package io.bitsquare.gui.trade.orderbook; - -import com.google.inject.Inject; -import io.bitsquare.bank.BankAccountType; -import io.bitsquare.gui.ChildController; -import io.bitsquare.gui.NavigationController; -import io.bitsquare.gui.trade.offer.CreateOfferController; -import io.bitsquare.gui.trade.tradeprocess.TradeProcessController; -import io.bitsquare.gui.util.Converter; -import io.bitsquare.gui.util.Formatter; -import io.bitsquare.gui.util.Icons; -import io.bitsquare.gui.util.Localisation; -import io.bitsquare.trade.Direction; -import io.bitsquare.trade.orderbook.OrderBook; -import io.bitsquare.trade.orderbook.OrderBookFilter; -import io.bitsquare.user.User; -import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.transformation.SortedList; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.geometry.Pos; -import javafx.scene.control.*; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.HBox; -import javafx.util.Callback; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.URL; -import java.text.DecimalFormat; -import java.text.ParseException; -import java.util.Locale; -import java.util.ResourceBundle; - -public class OrderBookController implements Initializable, ChildController -{ - private static final Logger log = LoggerFactory.getLogger(OrderBookController.class); - private NavigationController navigationController; - private OrderBook orderBook; - - private SortedList offerList; - private final OrderBookFilter orderBookFilter; - private User user; - - - private Image buyIcon = Icons.getIconImage(Icons.BUY); - private Image sellIcon = Icons.getIconImage(Icons.SELL); - - @FXML - public AnchorPane holderPane; - @FXML - public HBox topHBox; - @FXML - public TextField volume, amount, price; - @FXML - public TableView orderBookTable; - @FXML - public TableColumn priceColumn, amountColumn, volumeColumn; - @FXML - private TableColumn directionColumn, countryColumn, bankAccountTypeColumn; - @FXML - public Button createOfferButton; - - @Inject - public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, User user) - { - this.orderBook = orderBook; - this.orderBookFilter = orderBookFilter; - this.user = user; - } - - @Override - public void initialize(URL url, ResourceBundle rb) - { - // setup table - setCountryColumnCellFactory(); - setBankAccountTypeColumnCellFactory(); - setDirectionColumnCellFactory(); - offerList = orderBook.getOfferList(); - offerList.comparatorProperty().bind(orderBookTable.comparatorProperty()); - orderBookTable.setItems(offerList); - orderBookTable.getSortOrder().add(priceColumn); - orderBookTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - - // handlers - amount.textProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) - { - orderBookFilter.setAmount(textInputToNumber(oldValue, newValue)); - updateVolume(); - } - }); - - price.textProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observable, String oldValue, String newValue) - { - orderBookFilter.setPrice(textInputToNumber(oldValue, newValue)); - updateVolume(); - } - }); - - orderBookFilter.getChangedProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) - { - updateOfferList(); - } - }); - user.getChangedProperty().addListener(new ChangeListener() - { - @Override - public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) - { - updateOfferList(); - } - }); - - createOfferButton.setOnAction(e -> { - ChildController nextController = navigationController.navigateToView(NavigationController.TRADE__CREATE_OFFER, "Create offer"); - ((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter); - }); - } - - @Override - public void setNavigationController(NavigationController navigationController) - { - this.navigationController = navigationController; - } - - public void setDirection(Direction direction) - { - orderBookTable.getSelectionModel().clearSelection(); - price.setText(""); - orderBookFilter.setDirection(direction); - } - - public void cleanup() - { - orderBookTable.setItems(null); - orderBookTable.getSortOrder().clear(); - offerList.comparatorProperty().unbind(); - } - - private void openTradeTab(OrderBookListItem orderBookListItem) - { - String title = orderBookListItem.getOffer().getDirection() == Direction.BUY ? "Trade: Sell Bitcoin" : "Trade: Buy Bitcoin"; - TradeProcessController tradeProcessController = (TradeProcessController) navigationController.navigateToView(NavigationController.TRADE__PROCESS, title); - - double requestedAmount = orderBookListItem.getOffer().getAmount(); - if (!amount.getText().equals("")) - requestedAmount = Converter.stringToDouble(amount.getText()); - - tradeProcessController.initWithData(orderBookListItem.getOffer(), requestedAmount); - } - - private void updateOfferList() - { - orderBook.updateFilter(orderBookFilter); - - priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING); - orderBookTable.sort(); - - if (orderBookTable.getItems() != null) - createOfferButton.setDefaultButton(orderBookTable.getItems().size() == 0); - } - - private void setDirectionColumnCellFactory() - { - directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); - directionColumn.setCellFactory(new Callback, TableCell>() - { - @Override - public TableCell call(TableColumn directionColumn) - { - return new TableCell() - { - final ImageView iconView = new ImageView(); - final Button button = new Button(); - - { - button.setGraphic(iconView); - button.setMinWidth(70); - } - - @Override - public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) - { - super.updateItem(orderBookListItem, empty); - - if (orderBookListItem != null) - { - String title; - Image icon; - if (orderBookListItem.getOffer().getDirection() == Direction.SELL) - { - icon = buyIcon; - title = Formatter.formatDirection(Direction.BUY, true); - } - else - { - icon = sellIcon; - title = Formatter.formatDirection(Direction.SELL, true); - } - iconView.setImage(icon); - button.setText(title); - setGraphic(button); - - button.setDefaultButton(getIndex() == 0); - button.setOnAction(event -> openTradeTab(orderBookListItem)); - } - else - { - setGraphic(null); - } - } - }; - } - }); - } - - private void setCountryColumnCellFactory() - { - countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); - countryColumn.setCellFactory(new Callback, TableCell>() - { - @Override - public TableCell call(TableColumn directionColumn) - { - return new TableCell() - { - final HBox hBox = new HBox(); - - { - hBox.setSpacing(3); - hBox.setAlignment(Pos.CENTER); - setGraphic(hBox); - } - - @Override - public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) - { - super.updateItem(orderBookListItem, empty); - - hBox.getChildren().clear(); - if (orderBookListItem != null) - { - Locale countryLocale = orderBookListItem.getOffer().getBankAccountCountryLocale(); - try - { - hBox.getChildren().add(Icons.getIconImageView("/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png")); - - } catch (Exception e) - { - log.warn("Country icon not found: " + "/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png country name: " + countryLocale.getDisplayCountry()); - } - Tooltip.install(this, new Tooltip(countryLocale.getDisplayCountry())); - } - } - }; - } - }); - } - - private void setBankAccountTypeColumnCellFactory() - { - bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); - bankAccountTypeColumn.setCellFactory(new Callback, TableCell>() - { - @Override - public TableCell call(TableColumn directionColumn) - { - return new TableCell() - { - @Override - public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) - { - super.updateItem(orderBookListItem, empty); - - if (orderBookListItem != null) - { - BankAccountType.BankAccountTypeEnum bankAccountTypeEnum = orderBookListItem.getOffer().getBankAccountTypeEnum(); - setText(Localisation.get(bankAccountTypeEnum.toString())); - } - else - { - setText(""); - } - } - }; - } - }); - } - - private double textInputToNumber(String oldValue, String newValue) - { - //TODO use regex.... or custom textfield component - double d = 0.0; - if (!newValue.equals("")) - { - try - { - DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault()); - d = decimalFormat.parse(newValue).doubleValue(); - } catch (ParseException e) - { - amount.setText(oldValue); - d = Converter.stringToDouble(oldValue); - } - } - return d; - } - - private void updateVolume() - { - double a = textInputToNumber(amount.getText(), amount.getText()); - double p = textInputToNumber(price.getText(), price.getText()); - volume.setText(Formatter.formatPrice(a * p)); - } - - - // the scrollbar width is not handled correctly from the layout initially - /* private void forceTableLayoutUpdate() - { - final List items = orderBookTable.getItems(); - if (items == null || items.size() == 0) return; - - final OrderBookListItem item = orderBookTable.getItems().get(0); - items.remove(0); - Platform.runLater(new Runnable() - { - @Override - public void run() - { - items.add(0, item); - } - }); - } */ -} - +package io.bitsquare.gui.market.orderbook; + +import com.google.inject.Inject; +import io.bitsquare.bank.BankAccountType; +import io.bitsquare.gui.ChildController; +import io.bitsquare.gui.NavigationController; +import io.bitsquare.gui.market.offer.CreateOfferController; +import io.bitsquare.gui.market.trade.TradeController; +import io.bitsquare.gui.util.Converter; +import io.bitsquare.gui.util.Formatter; +import io.bitsquare.gui.util.Icons; +import io.bitsquare.gui.util.Localisation; +import io.bitsquare.trade.Direction; +import io.bitsquare.trade.orderbook.OrderBook; +import io.bitsquare.trade.orderbook.OrderBookFilter; +import io.bitsquare.user.User; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.transformation.SortedList; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.util.Callback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URL; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.util.Locale; +import java.util.ResourceBundle; + +public class OrderBookController implements Initializable, ChildController +{ + private static final Logger log = LoggerFactory.getLogger(OrderBookController.class); + private NavigationController navigationController; + private OrderBook orderBook; + + private SortedList offerList; + private final OrderBookFilter orderBookFilter; + private User user; + + + private Image buyIcon = Icons.getIconImage(Icons.BUY); + private Image sellIcon = Icons.getIconImage(Icons.SELL); + + @FXML + public AnchorPane holderPane; + @FXML + public HBox topHBox; + @FXML + public TextField volume, amount, price; + @FXML + public TableView orderBookTable; + @FXML + public TableColumn priceColumn, amountColumn, volumeColumn; + @FXML + private TableColumn directionColumn, countryColumn, bankAccountTypeColumn; + @FXML + public Button createOfferButton; + + @Inject + public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, User user) + { + this.orderBook = orderBook; + this.orderBookFilter = orderBookFilter; + this.user = user; + } + + @Override + public void initialize(URL url, ResourceBundle rb) + { + // setup table + setCountryColumnCellFactory(); + setBankAccountTypeColumnCellFactory(); + setDirectionColumnCellFactory(); + offerList = orderBook.getOfferList(); + offerList.comparatorProperty().bind(orderBookTable.comparatorProperty()); + orderBookTable.setItems(offerList); + orderBookTable.getSortOrder().add(priceColumn); + orderBookTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + + // handlers + amount.textProperty().addListener(new ChangeListener() + { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) + { + orderBookFilter.setAmount(textInputToNumber(oldValue, newValue)); + updateVolume(); + } + }); + + price.textProperty().addListener(new ChangeListener() + { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) + { + orderBookFilter.setPrice(textInputToNumber(oldValue, newValue)); + updateVolume(); + } + }); + + orderBookFilter.getChangedProperty().addListener(new ChangeListener() + { + @Override + public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) + { + updateOfferList(); + } + }); + user.getChangedProperty().addListener(new ChangeListener() + { + @Override + public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) + { + updateOfferList(); + } + }); + + createOfferButton.setOnAction(e -> { + ChildController nextController = navigationController.navigateToView(NavigationController.CREATE_OFFER, "Create offer"); + ((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter); + }); + } + + @Override + public void setNavigationController(NavigationController navigationController) + { + this.navigationController = navigationController; + } + + public void setDirection(Direction direction) + { + orderBookTable.getSelectionModel().clearSelection(); + price.setText(""); + orderBookFilter.setDirection(direction); + } + + public void cleanup() + { + orderBookTable.setItems(null); + orderBookTable.getSortOrder().clear(); + offerList.comparatorProperty().unbind(); + } + + private void openTradeTab(OrderBookListItem orderBookListItem) + { + String title = orderBookListItem.getOffer().getDirection() == Direction.BUY ? "Trade: Sell Bitcoin" : "Trade: Buy Bitcoin"; + TradeController tradeController = (TradeController) navigationController.navigateToView(NavigationController.TRADE, title); + + double requestedAmount = orderBookListItem.getOffer().getAmount(); + if (!amount.getText().equals("")) + requestedAmount = Converter.stringToDouble(amount.getText()); + + tradeController.initWithData(orderBookListItem.getOffer(), requestedAmount); + } + + private void updateOfferList() + { + orderBook.updateFilter(orderBookFilter); + + priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING); + orderBookTable.sort(); + + if (orderBookTable.getItems() != null) + createOfferButton.setDefaultButton(orderBookTable.getItems().size() == 0); + } + + private void setDirectionColumnCellFactory() + { + directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); + directionColumn.setCellFactory(new Callback, TableCell>() + { + @Override + public TableCell call(TableColumn directionColumn) + { + return new TableCell() + { + final ImageView iconView = new ImageView(); + final Button button = new Button(); + + { + button.setGraphic(iconView); + button.setMinWidth(70); + } + + @Override + public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) + { + super.updateItem(orderBookListItem, empty); + + if (orderBookListItem != null) + { + String title; + Image icon; + if (orderBookListItem.getOffer().getDirection() == Direction.SELL) + { + icon = buyIcon; + title = Formatter.formatDirection(Direction.BUY, true); + } + else + { + icon = sellIcon; + title = Formatter.formatDirection(Direction.SELL, true); + } + iconView.setImage(icon); + button.setText(title); + setGraphic(button); + + button.setDefaultButton(getIndex() == 0); + button.setOnAction(event -> openTradeTab(orderBookListItem)); + } + else + { + setGraphic(null); + } + } + }; + } + }); + } + + private void setCountryColumnCellFactory() + { + countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); + countryColumn.setCellFactory(new Callback, TableCell>() + { + @Override + public TableCell call(TableColumn directionColumn) + { + return new TableCell() + { + final HBox hBox = new HBox(); + + { + hBox.setSpacing(3); + hBox.setAlignment(Pos.CENTER); + setGraphic(hBox); + } + + @Override + public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) + { + super.updateItem(orderBookListItem, empty); + + hBox.getChildren().clear(); + if (orderBookListItem != null) + { + Locale countryLocale = orderBookListItem.getOffer().getBankAccountCountryLocale(); + try + { + hBox.getChildren().add(Icons.getIconImageView("/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png")); + + } catch (Exception e) + { + log.warn("Country icon not found: " + "/images/countries/" + countryLocale.getCountry().toLowerCase() + ".png country name: " + countryLocale.getDisplayCountry()); + } + Tooltip.install(this, new Tooltip(countryLocale.getDisplayCountry())); + } + } + }; + } + }); + } + + private void setBankAccountTypeColumnCellFactory() + { + bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); + bankAccountTypeColumn.setCellFactory(new Callback, TableCell>() + { + @Override + public TableCell call(TableColumn directionColumn) + { + return new TableCell() + { + @Override + public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) + { + super.updateItem(orderBookListItem, empty); + + if (orderBookListItem != null) + { + BankAccountType.BankAccountTypeEnum bankAccountTypeEnum = orderBookListItem.getOffer().getBankAccountTypeEnum(); + setText(Localisation.get(bankAccountTypeEnum.toString())); + } + else + { + setText(""); + } + } + }; + } + }); + } + + private double textInputToNumber(String oldValue, String newValue) + { + //TODO use regex.... or custom textfield component + double d = 0.0; + if (!newValue.equals("")) + { + try + { + DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault()); + d = decimalFormat.parse(newValue).doubleValue(); + } catch (ParseException e) + { + amount.setText(oldValue); + d = Converter.stringToDouble(oldValue); + } + } + return d; + } + + private void updateVolume() + { + double a = textInputToNumber(amount.getText(), amount.getText()); + double p = textInputToNumber(price.getText(), price.getText()); + volume.setText(Formatter.formatPrice(a * p)); + } + + + // the scrollbar width is not handled correctly from the layout initially + /* private void forceTableLayoutUpdate() + { + final List items = orderBookTable.getItems(); + if (items == null || items.size() == 0) return; + + final OrderBookListItem item = orderBookTable.getItems().get(0); + items.remove(0); + Platform.runLater(new Runnable() + { + @Override + public void run() + { + items.add(0, item); + } + }); + } */ +} + diff --git a/src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookListItem.java b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java similarity index 96% rename from src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookListItem.java rename to src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java index 829e0f45ba..18be3e298c 100644 --- a/src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookListItem.java +++ b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookListItem.java @@ -1,4 +1,4 @@ -package io.bitsquare.gui.trade.orderbook; +package io.bitsquare.gui.market.orderbook; import io.bitsquare.gui.util.Formatter; import io.bitsquare.trade.Offer; diff --git a/src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookView.fxml b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookView.fxml similarity index 97% rename from src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookView.fxml rename to src/main/java/io/bitsquare/gui/market/orderbook/OrderBookView.fxml index 2891c61aae..340984a980 100644 --- a/src/main/java/io/bitsquare/gui/trade/orderbook/OrderBookView.fxml +++ b/src/main/java/io/bitsquare/gui/market/orderbook/OrderBookView.fxml @@ -6,7 +6,7 @@ + fx:controller="io.bitsquare.gui.market.orderbook.OrderBookController"> processStepItems = new ArrayList(); - - private NavigationController navigationController; - private TextField amountTextField, totalToPayLabel, totalLabel; - private Label statusTextField; - private Button nextButton; - private ProgressBar progressBar; - - @FXML - private AnchorPane rootContainer; - @FXML - private ProcessStepBar processStepBar; - @FXML - private GridPane formGridPane; - @FXML - private VBox vBox; - private Label infoLabel; - private int gridRow; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor(s) - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - public TradeProcessController(Trading trading, User user, WalletFacade walletFacade, BlockChainFacade blockChainFacade, Settings settings, Storage storage) - { - this.trading = trading; - this.user = user; - this.walletFacade = walletFacade; - this.blockChainFacade = blockChainFacade; - this.settings = settings; - this.storage = storage; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Public methods - /////////////////////////////////////////////////////////////////////////////////////////// - - public void initWithData(Offer offer, double requestedAmount) - { - this.offer = offer; - this.requestedAmount = requestedAmount > 0 ? requestedAmount : offer.getAmount(); - - trade = trading.createNewTrade(offer); - trade.setTradeAmount(requestedAmount); - contract = trading.createNewContract(trade); - - processStepItems.add(new ProcessStepItem(takerIsSelling() ? "Sell BTC" : "Buy BTC")); - processStepItems.add(new ProcessStepItem("Bank transfer")); - processStepItems.add(new ProcessStepItem("Completed")); - processStepBar.setProcessStepItems(processStepItems); - - buildTakeOfferScreen(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Interface implementation: Initializable - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void initialize(URL url, ResourceBundle rb) - { - walletFacade.addRegistrationWalletListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Interface implementation: ChildController - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void setNavigationController(NavigationController navigationController) - { - this.navigationController = navigationController; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Interface implementation: WalletFacade.WalletListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks) - { - log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks); - } - - @Override - public void onCoinsReceived(BigInteger newBalance) - { - log.info("onCoinsReceived " + newBalance); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private methods - /////////////////////////////////////////////////////////////////////////////////////////// - - - /////////////////////////////////////////////////////////////////////////////////////////// - // trade process - /////////////////////////////////////////////////////////////////////////////////////////// - - - private void buildTakeOfferScreen() - { - - int gridRow = -1; - - FormBuilder.addHeaderLabel(formGridPane, "Take offer:", ++gridRow); - amountTextField = FormBuilder.addTextField(formGridPane, "Amount BTC:", Formatter.formatAmount(requestedAmount), ++gridRow, true, true); - amountTextField.textProperty().addListener(e -> { - setVolume(); - totalToPayLabel.setText(getTotalToPay()); - - }); - Label amountRangeLabel = new Label("(" + Formatter.formatAmount(offer.getMinAmount()) + " - " + Formatter.formatAmount(offer.getAmount()) + ")"); - formGridPane.add(amountRangeLabel, 2, gridRow); - - FormBuilder.addTextField(formGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++gridRow); - totalLabel = FormBuilder.addTextField(formGridPane, "Total:", Formatter.formatVolume(getVolume(), offer.getCurrency()), ++gridRow); - FormBuilder.addTextField(formGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_TAKER_FEE, true), ++gridRow); - totalToPayLabel = FormBuilder.addTextField(formGridPane, "Total to pay:", getTotalToPay(), ++gridRow); - - nextButton = FormBuilder.addButton(formGridPane, "Take offer and pay", ++gridRow); - nextButton.setDefaultButton(true); - nextButton.setOnAction(e -> { - initTrade(); - }); - - // details - FormBuilder.addVSpacer(formGridPane, ++gridRow); - FormBuilder.addHeaderLabel(formGridPane, "Offerer details:", ++gridRow); - TextField isOnlineTextField = FormBuilder.addTextField(formGridPane, "Online status:", "Checking offerers online status...", ++gridRow); - ProgressIndicator isOnlineChecker = new ProgressIndicator(); - isOnlineChecker.setPrefSize(20, 20); - isOnlineChecker.setLayoutY(3); - Pane isOnlineCheckerHolder = new Pane(); - isOnlineCheckerHolder.getChildren().addAll(isOnlineChecker); - formGridPane.add(isOnlineCheckerHolder, 2, gridRow); - checkIfOffererIsOnline(isOnlineCheckerHolder, isOnlineTextField); - - FormBuilder.addTextField(formGridPane, "Bank account type:", offer.getBankAccountTypeEnum().toString(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Bank account country:", offer.getBankAccountCountryLocale().getDisplayCountry(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Arbitrator:", offer.getArbitrator().getName(), ++gridRow); - Label arbitratorLink = new Label(offer.getArbitrator().getUrl()); - arbitratorLink.setId("label-url"); - formGridPane.add(arbitratorLink, 2, gridRow); - arbitratorLink.setOnMouseClicked(e -> { - try - { - Utils.openURL(offer.getArbitrator().getUrl()); - } catch (Exception e1) - { - log.warn(e1.toString()); - } - }); - - FormBuilder.addVSpacer(formGridPane, ++gridRow); - FormBuilder.addHeaderLabel(formGridPane, "More details:", ++gridRow); - FormBuilder.addTextField(formGridPane, "Offer ID:", offer.getUid().toString(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Account ID:", offer.getAccountID(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Messaging ID:", offer.getMessageID(), ++gridRow); - FormBuilder.addTextField(formGridPane, "Supported languages:", Formatter.languageLocalesToString(offer.getAcceptedLanguageLocales()), ++gridRow); - FormBuilder.addTextField(formGridPane, "Supported countries:", Formatter.countryLocalesToString(offer.getAcceptedCountryLocales()), ++gridRow); - - } - - private boolean tradeAmountValid() - { - double tradeAmount = Converter.stringToDouble(amountTextField.getText()); - return tradeAmount <= offer.getAmount() && tradeAmount >= offer.getMinAmount(); - } - - - private void initTrade() - { - if (tradeAmountValid()) - { - if (blockChainFacade.verifyEmbeddedData(offer.getAccountID())) - { - if (!blockChainFacade.isAccountIDBlacklisted(offer.getAccountID())) - { - amountTextField.setEditable(false); - - formGridPane.getChildren().clear(); - - int gridRow = -1; - FormBuilder.addHeaderLabel(formGridPane, "Trade request inited", ++gridRow, 0); - - statusTextField = FormBuilder.addLabel(formGridPane, "Current activity:", "Request confirmation from offerer to take that offer.", ++gridRow); - GridPane.setColumnSpan(statusTextField, 2); - FormBuilder.addLabel(formGridPane, "Progress:", "", ++gridRow); - progressBar = new ProgressBar(); - progressBar.setProgress(0.0); - progressBar.setPrefWidth(300); - GridPane.setFillWidth(progressBar, true); - formGridPane.add(progressBar, 1, gridRow); - - FormBuilder.addLabel(formGridPane, "Status:", "", ++gridRow); - ProgressIndicator progressIndicator = new ProgressIndicator(); - progressIndicator.setPrefSize(20, 20); - progressIndicator.setLayoutY(2); - Pane progressIndicatorHolder = new Pane(); - progressIndicatorHolder.getChildren().addAll(progressIndicator); - formGridPane.add(progressIndicatorHolder, 1, gridRow); - - trade.setTradeAmount(Converter.stringToDouble(amountTextField.getText())); - trading.sendTakeOfferRequest(trade); - - Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { - onTakeOfferRequestConfirmed(); - progressBar.setProgress(1.0 / 3.0); - return null; - }); - } - else - { - Dialogs.create() - .title("Offerers account ID is blacklisted") - .message("Offerers account ID is blacklisted.") - .nativeTitleBar() - .lightweight() - .showError(); - } - } - else - { - Dialogs.create() - .title("Offerers account ID not valid") - .message("Offerers registration tx is not found in blockchain or does not match the requirements.") - .nativeTitleBar() - .lightweight() - .showError(); - } - } - else - { - Dialogs.create() - .title("Your input is not valid") - .message("The requested amount you entered is outside of the range of the offered amount.") - .nativeTitleBar() - .lightweight() - .showError(); - } - } - - private void onTakeOfferRequestConfirmed() - { - trading.payOfferFee(trade); - - statusTextField.setText("Offer fee payed. Send offerer payment transaction ID for confirmation."); - Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { - onOfferFeePaymentConfirmed(); - progressBar.setProgress(2.0 / 3.0); - return null; - }); - } - - private void onOfferFeePaymentConfirmed() - { - trading.requestOffererDetailData(); - statusTextField.setText("Request bank account details from offerer."); - Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { - onUserDetailsReceived(); - progressBar.setProgress(1.0); - return null; - }); - } - - private void onUserDetailsReceived() - { - if (!walletFacade.verifyAccountRegistration(offer.getAccountID(), null, null, null, null)) - { - Dialogs.create() - .title("Offerers bank account is blacklisted") - .message("Offerers bank account is blacklisted.") - .nativeTitleBar() - .lightweight() - .showError(); - } - - trading.signContract(contract); - trading.payToDepositTx(trade); - - buildWaitBankTransfer(); - } - - private void buildWaitBankTransfer() - { - processStepBar.next(); - - formGridPane.getChildren().clear(); - - gridRow = -1; - FormBuilder.addHeaderLabel(formGridPane, "Bank transfer", ++gridRow, 0); - infoLabel = FormBuilder.addLabel(formGridPane, "Status:", "Wait for Bank transfer.", ++gridRow); - - Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { - onBankTransferInited(); - return null; - }); - } - - private void onBankTransferInited() - { - int gridRow = 1; - infoLabel.setText("Bank transfer has been inited."); - Label label = FormBuilder.addLabel(formGridPane, "", "Check your bank account and continue when you have received the money.", ++gridRow); - GridPane.setColumnSpan(label, 2); - - formGridPane.add(nextButton, 1, ++gridRow); - nextButton.setText("I have received the bank transfer"); - nextButton.setOnAction(e -> releaseBTC()); - } - - private void releaseBTC() - { - processStepBar.next(); - trading.releaseBTC(trade); - - nextButton.setText("Close"); - nextButton.setOnAction(e -> close()); - - formGridPane.getChildren().clear(); - gridRow = -1; - FormBuilder.addHeaderLabel(formGridPane, "Trade successfully completed", ++gridRow); - FormBuilder.addTextField(formGridPane, "You have payed:", getTotalToPay(), ++gridRow); - FormBuilder.addTextField(formGridPane, "You have received:", getTotalToReceive(), ++gridRow); - formGridPane.add(nextButton, 1, ++gridRow); - } - - - private void close() - { - walletFacade.removeRegistrationWalletListener(this); - - TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent())); - tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); - - navigationController.navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook"); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private methods - /////////////////////////////////////////////////////////////////////////////////////////// - - private boolean takerIsSelling() - { - return offer.getDirection() == Direction.BUY; - } - - private String getTotalToReceive() - { - if (takerIsSelling()) - return Formatter.formatVolume(getVolume(), offer.getCurrency()); - else - return Formatter.formatAmount(offer.getAmount(), true, true); - } - - private void checkIfOffererIsOnline(Node isOnlineChecker, TextField isOnlineTextField) - { - // mock - Utils.setTimeout(3000, (AnimationTimer animationTimer) -> { - offererIsOnline = Math.random() > 0.3 ? true : false; - isOnlineTextField.setText(offererIsOnline ? "Online" : "Offline"); - formGridPane.getChildren().remove(isOnlineChecker); - return null; - }); - } - - - private void setVolume() - { - totalLabel.setText(Formatter.formatVolume(getVolume(), offer.getCurrency())); - } - - private double getVolume() - { - return offer.getPrice() * Converter.stringToDouble(amountTextField.getText()); - } - - private String getTotalToPay() - { - String result = ""; - if (takerIsSelling()) - { - double btcValue = Converter.stringToDouble(amountTextField.getText()) + BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE)/* + - offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText())*/; - result = Formatter.formatAmount(btcValue, true, true); - } - else - { - double btcValue = BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE) /*+ offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText())*/; - result = Formatter.formatAmount(btcValue, true, true) + "\n" + Formatter.formatVolume(getVolume(), offer.getCurrency()); - } - return result; - } - -} - +package io.bitsquare.gui.market.trade; + +import com.google.inject.Inject; +import io.bitsquare.btc.BlockChainFacade; +import io.bitsquare.btc.BtcFormatter; +import io.bitsquare.btc.Fees; +import io.bitsquare.btc.WalletFacade; +import io.bitsquare.gui.ChildController; +import io.bitsquare.gui.NavigationController; +import io.bitsquare.gui.components.processbar.ProcessStepBar; +import io.bitsquare.gui.components.processbar.ProcessStepItem; +import io.bitsquare.gui.util.Converter; +import io.bitsquare.gui.util.FormBuilder; +import io.bitsquare.gui.util.Formatter; +import io.bitsquare.gui.util.Popups; +import io.bitsquare.trade.*; +import io.bitsquare.util.Utils; +import javafx.animation.AnimationTimer; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.Node; +import javafx.scene.control.*; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; +import org.controlsfx.dialog.Dialogs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.ResourceBundle; + +public class TradeController implements Initializable, ChildController, WalletFacade.WalletListener +{ + private static final Logger log = LoggerFactory.getLogger(TradeController.class); + private static final int SIM_DELAY = 1000; + + private Trading trading; + private WalletFacade walletFacade; + private BlockChainFacade blockChainFacade; + private Offer offer; + private Trade trade; + private Contract contract; + private double requestedAmount; + private boolean offererIsOnline; + private int row; + + private List processStepItems = new ArrayList(); + + private NavigationController navigationController; + private TextField amountTextField, totalToPayLabel, totalLabel; + private Label statusTextField, infoLabel; + private Button nextButton; + private ProgressBar progressBar; + + @FXML + private AnchorPane rootContainer; + @FXML + private ProcessStepBar processStepBar; + @FXML + private GridPane gridPane; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public TradeController(Trading trading, WalletFacade walletFacade, BlockChainFacade blockChainFacade) + { + this.trading = trading; + this.walletFacade = walletFacade; + this.blockChainFacade = blockChainFacade; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public methods + /////////////////////////////////////////////////////////////////////////////////////////// + + public void initWithData(Offer offer, double requestedAmount) + { + this.offer = offer; + this.requestedAmount = requestedAmount > 0 ? requestedAmount : offer.getAmount(); + + trade = trading.createNewTrade(offer); + trade.setTradeAmount(requestedAmount); + contract = trading.createNewContract(trade); + + processStepItems.add(new ProcessStepItem(takerIsSelling() ? "Sell BTC" : "Buy BTC")); + processStepItems.add(new ProcessStepItem("Bank transfer")); + processStepItems.add(new ProcessStepItem("Completed")); + processStepBar.setProcessStepItems(processStepItems); + + buildTakeOfferScreen(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: Initializable + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void initialize(URL url, ResourceBundle rb) + { + walletFacade.addRegistrationWalletListener(this); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: ChildController + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void setNavigationController(NavigationController navigationController) + { + this.navigationController = navigationController; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Interface implementation: WalletFacade.WalletListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks) + { + log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks); + } + + @Override + public void onCoinsReceived(BigInteger newBalance) + { + log.info("onCoinsReceived " + newBalance); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private methods + /////////////////////////////////////////////////////////////////////////////////////////// + + // trade process + private void buildTakeOfferScreen() + { + row = -1; + + FormBuilder.addHeaderLabel(gridPane, "Take offer:", ++row); + amountTextField = FormBuilder.addTextField(gridPane, "Amount BTC:", Formatter.formatAmount(requestedAmount), ++row, true, true); + amountTextField.textProperty().addListener(e -> { + applyVolume(); + totalToPayLabel.setText(getTotalToPay()); + + }); + Label amountRangeLabel = new Label("(" + Formatter.formatAmount(offer.getMinAmount()) + " - " + Formatter.formatAmount(offer.getAmount()) + ")"); + gridPane.add(amountRangeLabel, 2, row); + + FormBuilder.addTextField(gridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row); + totalLabel = FormBuilder.addTextField(gridPane, "Total:", Formatter.formatVolume(getVolume(), offer.getCurrency()), ++row); + FormBuilder.addTextField(gridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_TAKER_FEE, true), ++row); + totalToPayLabel = FormBuilder.addTextField(gridPane, "Total to pay:", getTotalToPay(), ++row); + + nextButton = FormBuilder.addButton(gridPane, "Take offer and pay", ++row); + nextButton.setDefaultButton(true); + nextButton.setOnAction(e -> initTrade()); + + // details + FormBuilder.addVSpacer(gridPane, ++row); + FormBuilder.addHeaderLabel(gridPane, "Offerer details:", ++row); + TextField isOnlineTextField = FormBuilder.addTextField(gridPane, "Online status:", "Checking offerers online status...", ++row); + ProgressIndicator isOnlineChecker = new ProgressIndicator(); + isOnlineChecker.setPrefSize(20, 20); + isOnlineChecker.setLayoutY(3); + Pane isOnlineCheckerHolder = new Pane(); + isOnlineCheckerHolder.getChildren().addAll(isOnlineChecker); + gridPane.add(isOnlineCheckerHolder, 2, row); + checkIfOffererIsOnline(isOnlineCheckerHolder, isOnlineTextField); + + FormBuilder.addTextField(gridPane, "Bank account type:", offer.getBankAccountTypeEnum().toString(), ++row); + FormBuilder.addTextField(gridPane, "Bank account country:", offer.getBankAccountCountryLocale().getDisplayCountry(), ++row); + FormBuilder.addTextField(gridPane, "Arbitrator:", offer.getArbitrator().getName(), ++row); + Label arbitratorLink = new Label(offer.getArbitrator().getUrl()); + arbitratorLink.setId("label-url"); + gridPane.add(arbitratorLink, 2, row); + arbitratorLink.setOnMouseClicked(e -> { + try + { + Utils.openURL(offer.getArbitrator().getUrl()); + } catch (Exception e1) + { + log.warn(e1.toString()); + } + }); + + FormBuilder.addVSpacer(gridPane, ++row); + FormBuilder.addHeaderLabel(gridPane, "More details:", ++row); + FormBuilder.addTextField(gridPane, "Offer ID:", offer.getUid().toString(), ++row); + FormBuilder.addTextField(gridPane, "Account ID:", offer.getAccountID(), ++row); + FormBuilder.addTextField(gridPane, "Messaging ID:", offer.getMessageID(), ++row); + FormBuilder.addTextField(gridPane, "Supported languages:", Formatter.languageLocalesToString(offer.getAcceptedLanguageLocales()), ++row); + FormBuilder.addTextField(gridPane, "Supported countries:", Formatter.countryLocalesToString(offer.getAcceptedCountryLocales()), ++row); + } + + private void initTrade() + { + if (!tradeAmountValid()) + { + Popups.openErrorPopup("Your input is not valid", "The requested amount you entered is outside of the range of the offered amount."); + return; + } + + if (!blockChainFacade.verifyEmbeddedData(offer.getAccountID())) + { + Popups.openErrorPopup("Offerers account ID not valid", "Offerers registration tx is not found in blockchain or does not match the requirements."); + return; + } + + if (blockChainFacade.isAccountIDBlacklisted(offer.getAccountID())) + { + Popups.openErrorPopup("Offerers account ID is blacklisted", "Offerers account ID is blacklisted."); + return; + } + + amountTextField.setEditable(false); + + gridPane.getChildren().clear(); + + row = -1; + FormBuilder.addHeaderLabel(gridPane, "Trade request inited", ++row, 0); + + statusTextField = FormBuilder.addLabel(gridPane, "Current activity:", "Request confirmation from offerer to take that offer.", ++row); + GridPane.setColumnSpan(statusTextField, 2); + FormBuilder.addLabel(gridPane, "Progress:", "", ++row); + progressBar = new ProgressBar(); + progressBar.setProgress(0.0); + progressBar.setPrefWidth(300); + GridPane.setFillWidth(progressBar, true); + gridPane.add(progressBar, 1, row); + + FormBuilder.addLabel(gridPane, "Status:", "", ++row); + ProgressIndicator progressIndicator = new ProgressIndicator(); + progressIndicator.setPrefSize(20, 20); + progressIndicator.setLayoutY(2); + Pane progressIndicatorHolder = new Pane(); + progressIndicatorHolder.getChildren().addAll(progressIndicator); + gridPane.add(progressIndicatorHolder, 1, row); + + trade.setTradeAmount(Converter.stringToDouble(amountTextField.getText())); + trading.sendTakeOfferRequest(trade); + + Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { + onTakeOfferRequestConfirmed(); + progressBar.setProgress(1.0 / 3.0); + return null; + }); + } + + private void onTakeOfferRequestConfirmed() + { + trading.payOfferFee(trade); + + statusTextField.setText("Offer fee payed. Send offerer payment transaction ID for confirmation."); + Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { + onOfferFeePaymentConfirmed(); + progressBar.setProgress(2.0 / 3.0); + return null; + }); + } + + private void onOfferFeePaymentConfirmed() + { + trading.requestOffererDetailData(); + statusTextField.setText("Request bank account details from offerer."); + Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { + onUserDetailsReceived(); + progressBar.setProgress(1.0); + return null; + }); + } + + private void onUserDetailsReceived() + { + if (!walletFacade.verifyAccountRegistration(offer.getAccountID(), null, null, null, null)) + { + Dialogs.create() + .title("Offerers bank account is blacklisted") + .message("Offerers bank account is blacklisted.") + .nativeTitleBar() + .lightweight() + .showError(); + } + + trading.signContract(contract); + trading.payToDepositTx(trade); + + buildWaitBankTransfer(); + } + + private void buildWaitBankTransfer() + { + processStepBar.next(); + + gridPane.getChildren().clear(); + + row = -1; + FormBuilder.addHeaderLabel(gridPane, "Bank transfer", ++row, 0); + infoLabel = FormBuilder.addLabel(gridPane, "Status:", "Wait for Bank transfer.", ++row); + + Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> { + onBankTransferInited(); + return null; + }); + } + + private void onBankTransferInited() + { + row = 1; + infoLabel.setText("Bank transfer has been inited."); + Label label = FormBuilder.addLabel(gridPane, "", "Check your bank account and continue when you have received the money.", ++row); + GridPane.setColumnSpan(label, 2); + + gridPane.add(nextButton, 1, ++row); + nextButton.setText("I have received the bank transfer"); + nextButton.setOnAction(e -> releaseBTC()); + } + + private void releaseBTC() + { + processStepBar.next(); + trading.releaseBTC(trade); + + nextButton.setText("Close"); + nextButton.setOnAction(e -> close()); + + gridPane.getChildren().clear(); + row = -1; + FormBuilder.addHeaderLabel(gridPane, "Trade successfully completed", ++row); + FormBuilder.addTextField(gridPane, "You have payed:", getTotalToPay(), ++row); + FormBuilder.addTextField(gridPane, "You have received:", getTotalToReceive(), ++row); + gridPane.add(nextButton, 1, ++row); + } + + private void close() + { + walletFacade.removeRegistrationWalletListener(this); + + TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent())); + tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); + + navigationController.navigateToView(NavigationController.ORDER_BOOK, "Orderbook"); + } + + // Other Private methods + private boolean tradeAmountValid() + { + double tradeAmount = Converter.stringToDouble(amountTextField.getText()); + return tradeAmount <= offer.getAmount() && tradeAmount >= offer.getMinAmount(); + } + + private boolean takerIsSelling() + { + return offer.getDirection() == Direction.BUY; + } + + + private void checkIfOffererIsOnline(Node isOnlineChecker, TextField isOnlineTextField) + { + // mock + Utils.setTimeout(3000, (AnimationTimer animationTimer) -> { + offererIsOnline = Math.random() > 0.3 ? true : false; + isOnlineTextField.setText(offererIsOnline ? "Online" : "Offline"); + gridPane.getChildren().remove(isOnlineChecker); + return null; + }); + } + + private void applyVolume() + { + totalLabel.setText(Formatter.formatVolume(getVolume(), offer.getCurrency())); + } + + private double getVolume() + { + return offer.getPrice() * Converter.stringToDouble(amountTextField.getText()); + } + + private String getTotalToPay() + { + String result = ""; + if (takerIsSelling()) + { + double btcValue = Converter.stringToDouble(amountTextField.getText()) + BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE)/* + + offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText())*/; + result = Formatter.formatAmount(btcValue, true, true); + } + else + { + double btcValue = BtcFormatter.satoshiToBTC(Fees.OFFER_CREATION_FEE) /*+ offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText())*/; + result = Formatter.formatAmount(btcValue, true, true) + "\n" + Formatter.formatVolume(getVolume(), offer.getCurrency()); + } + return result; + } + + private String getTotalToReceive() + { + if (takerIsSelling()) + return Formatter.formatVolume(getVolume(), offer.getCurrency()); + else + return Formatter.formatAmount(offer.getAmount(), true, true); + } + +} + diff --git a/src/main/java/io/bitsquare/gui/trade/tradeprocess/TradeProcessView.fxml b/src/main/java/io/bitsquare/gui/market/trade/TradeView.fxml similarity index 92% rename from src/main/java/io/bitsquare/gui/trade/tradeprocess/TradeProcessView.fxml rename to src/main/java/io/bitsquare/gui/market/trade/TradeView.fxml index 2cbe97c56e..7a45047bf4 100644 --- a/src/main/java/io/bitsquare/gui/trade/tradeprocess/TradeProcessView.fxml +++ b/src/main/java/io/bitsquare/gui/market/trade/TradeView.fxml @@ -5,7 +5,7 @@ - @@ -17,7 +17,7 @@ - + diff --git a/src/main/java/io/bitsquare/gui/setup/SetupController.java b/src/main/java/io/bitsquare/gui/setup/SetupController.java index 7110c7317c..cb801bec33 100644 --- a/src/main/java/io/bitsquare/gui/setup/SetupController.java +++ b/src/main/java/io/bitsquare/gui/setup/SetupController.java @@ -65,7 +65,7 @@ public class SetupController implements Initializable, ChildController, WalletFa /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor(s) + // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @Inject diff --git a/src/main/java/io/bitsquare/gui/util/Formatter.java b/src/main/java/io/bitsquare/gui/util/Formatter.java index df5855ec4c..f3df59f561 100644 --- a/src/main/java/io/bitsquare/gui/util/Formatter.java +++ b/src/main/java/io/bitsquare/gui/util/Formatter.java @@ -11,8 +11,6 @@ import java.util.Locale; public class Formatter { - - public static String formatPrice(double price) { return formatDouble(price); diff --git a/src/main/java/io/bitsquare/gui/util/Popups.java b/src/main/java/io/bitsquare/gui/util/Popups.java new file mode 100644 index 0000000000..ab8d60d804 --- /dev/null +++ b/src/main/java/io/bitsquare/gui/util/Popups.java @@ -0,0 +1,16 @@ +package io.bitsquare.gui.util; + +import org.controlsfx.dialog.Dialogs; + +public class Popups +{ + public static void openErrorPopup(String title, String message) + { + Dialogs.create() + .title(title) + .message(message) + .nativeTitleBar() + .lightweight() + .showError(); + } +} diff --git a/src/main/java/io/bitsquare/settings/Settings.java b/src/main/java/io/bitsquare/settings/Settings.java index dc4d7c53d6..0bb575d3c5 100644 --- a/src/main/java/io/bitsquare/settings/Settings.java +++ b/src/main/java/io/bitsquare/settings/Settings.java @@ -16,11 +16,21 @@ public class Settings implements Serializable private List acceptedCountryLocales = new ArrayList<>(); private List arbitrators = new ArrayList<>(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + @Inject public Settings() { } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// + public void updateFromStorage(Settings savedSettings) { if (savedSettings != null) @@ -49,7 +59,11 @@ public class Settings implements Serializable arbitrators.add(arbitrator); } - //getters + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + public List getArbitrators() { return arbitrators; @@ -60,7 +74,6 @@ public class Settings implements Serializable return acceptedLanguageLocales; } - public List getAcceptedCountryLocales() { return acceptedCountryLocales; diff --git a/src/main/java/io/bitsquare/storage/Storage.java b/src/main/java/io/bitsquare/storage/Storage.java index 0b565acd65..0e410ae707 100644 --- a/src/main/java/io/bitsquare/storage/Storage.java +++ b/src/main/java/io/bitsquare/storage/Storage.java @@ -1,6 +1,5 @@ package io.bitsquare.storage; -import io.bitsquare.user.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,56 +12,62 @@ import java.util.Map; */ public class Storage { - private static final Logger log = LoggerFactory.getLogger(Storage.class); + //TODO save in users preferences location private final String preferencesFileName = "preferences.ser"; private final String storageFile; - private DataVO dataVO; + private Map dict; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// public Storage() { storageFile = Storage.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/" + preferencesFileName; - dataVO = readDataVO(); - if (dataVO == null) + dict = readDataVO(); + if (dict == null) { - dataVO = new DataVO(); - dataVO.dict = new HashMap(); - writeDataVO(dataVO); + dict = new HashMap<>(); + writeDataVO(dict); } } - public void updateUserFromStorage(User user) - { - User savedUser = (User) read(user.getClass().getName()); - if (savedUser != null) - user.updateFromStorage(savedUser); - } + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// public void write(String key, Object value) { //log.info("Write object with key = " + key + " / value = " + value); - dataVO.dict.put(key, value); - writeDataVO(dataVO); + dict.put(key, value); + writeDataVO(dict); } public Object read(String key) { - dataVO = readDataVO(); - Object result = dataVO.dict.get(key); + dict = readDataVO(); + Object result = dict.get(key); //log.info("Read object with key = " + key + " result = " + result); return result; } - private void writeDataVO(DataVO dataVO) + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private methods + /////////////////////////////////////////////////////////////////////////////////////////// + + private void writeDataVO(Map dict) { try { FileOutputStream fileOut = new FileOutputStream(storageFile); ObjectOutputStream out = new ObjectOutputStream(fileOut); - out.writeObject(dataVO); + out.writeObject(dict); out.close(); fileOut.close(); } catch (IOException i) @@ -71,9 +76,9 @@ public class Storage } } - private DataVO readDataVO() + private Map readDataVO() { - DataVO dataVO = null; + Map dict = null; File file = new File(storageFile); if (file.exists()) { @@ -81,7 +86,7 @@ public class Storage { FileInputStream fileIn = new FileInputStream(file); ObjectInputStream in = new ObjectInputStream(fileIn); - dataVO = (DataVO) in.readObject(); + dict = (Map) in.readObject(); in.close(); fileIn.close(); } catch (IOException i) @@ -92,16 +97,6 @@ public class Storage c.printStackTrace(); } } - return dataVO; + return dict; } - - } - -class DataVO implements Serializable -{ - - private static final long serialVersionUID = -1127046445783201376L; - - public Map dict; -} \ No newline at end of file diff --git a/src/main/java/io/bitsquare/trade/Contract.java b/src/main/java/io/bitsquare/trade/Contract.java index 44a6fb5cf0..52913a7d6e 100644 --- a/src/main/java/io/bitsquare/trade/Contract.java +++ b/src/main/java/io/bitsquare/trade/Contract.java @@ -7,27 +7,37 @@ import java.util.UUID; public class Contract { private User taker; - private String offererPubKey; private Trade trade; private String takerPubKey; + private String offererPubKey; - - public Contract(Trade trade, String takerPubKey) + public Contract(User taker, Trade trade, String takerPubKey) { + this.taker = taker; this.trade = trade; this.takerPubKey = takerPubKey; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Setters + /////////////////////////////////////////////////////////////////////////////////////////// + + public void setOffererPubKey(String offererPubKey) + { + this.offererPubKey = offererPubKey; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + public UUID getUid() { return trade.getUid(); } - public void setTaker(User taker) - { - this.taker = taker; - } - public User getTaker() { return taker; @@ -38,9 +48,9 @@ public class Contract return takerPubKey; } - public void setTakerPubKey(String takerPubKey) + public Trade getTrade() { - this.takerPubKey = takerPubKey; + return trade; } public String getOffererPubKey() @@ -48,19 +58,4 @@ public class Contract return offererPubKey; } - public void setOffererPubKey(String offererPubKey) - { - this.offererPubKey = offererPubKey; - } - - - public Trade getTrade() - { - return trade; - } - - public void setTrade(Trade trade) - { - this.trade = trade; - } } diff --git a/src/main/java/io/bitsquare/trade/Trading.java b/src/main/java/io/bitsquare/trade/Trading.java index 853b4fb0e0..13eca8ca1d 100644 --- a/src/main/java/io/bitsquare/trade/Trading.java +++ b/src/main/java/io/bitsquare/trade/Trading.java @@ -85,8 +85,7 @@ public class Trading log.info("create new contract"); KeyPair address = walletFacade.createNewAddress(); - Contract contract = new Contract(trade, address.getPubKey()); - contract.setTaker(user); + Contract contract = new Contract(user, trade, address.getPubKey()); contracts.put(trade.getUid().toString(), contract); return contract; } diff --git a/src/main/java/io/bitsquare/trade/orderbook/MockOrderBook.java b/src/main/java/io/bitsquare/trade/orderbook/MockOrderBook.java index 0ab75f807a..129a7d02f5 100644 --- a/src/main/java/io/bitsquare/trade/orderbook/MockOrderBook.java +++ b/src/main/java/io/bitsquare/trade/orderbook/MockOrderBook.java @@ -1,7 +1,7 @@ package io.bitsquare.trade.orderbook; import com.google.inject.Inject; -import io.bitsquare.gui.trade.orderbook.OrderBookListItem; +import io.bitsquare.gui.market.orderbook.OrderBookListItem; import io.bitsquare.gui.util.Converter; import io.bitsquare.gui.util.Formatter; import io.bitsquare.settings.Settings; @@ -43,7 +43,7 @@ public class MockOrderBook extends OrderBook price = 500 - Math.random() * 50; } - Offer offer = new Offer(UUID.randomUUID().toString(), + Offer offer = new Offer("mjbxLbuVpU1cNXLJbrJZyirYwweoRPVVTj", UUID.randomUUID().toString(), direction, price, diff --git a/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java b/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java index 95baa1f74c..5ea70137b3 100644 --- a/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java +++ b/src/main/java/io/bitsquare/trade/orderbook/OrderBook.java @@ -2,8 +2,7 @@ package io.bitsquare.trade.orderbook; import com.google.inject.Inject; import io.bitsquare.bank.BankAccount; -import io.bitsquare.bank.BankAccountType; -import io.bitsquare.gui.trade.orderbook.OrderBookListItem; +import io.bitsquare.gui.market.orderbook.OrderBookListItem; import io.bitsquare.settings.Settings; import io.bitsquare.trade.Direction; import io.bitsquare.trade.Offer; @@ -23,29 +22,30 @@ public class OrderBook { private static final Logger log = LoggerFactory.getLogger(OrderBook.class); - private FilteredList filteredList; - private SortedList offerList; - - - protected ObservableList allOffers = FXCollections.observableArrayList(); private Settings settings; private User user; + protected ObservableList allOffers = FXCollections.observableArrayList(); + private FilteredList filteredList = new FilteredList<>(allOffers); + // FilteredList does not support sorting, so we need to wrap it to a SortedList + private SortedList offerList = new SortedList<>(filteredList); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + @Inject public OrderBook(Settings settings, User user) { this.settings = settings; this.user = user; - - filteredList = new FilteredList<>(allOffers); - // FilteredList does not support sorting, so we need to wrap it to a SortedList - offerList = new SortedList<>(filteredList); } - public SortedList getOfferList() - { - return offerList; - } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public API + /////////////////////////////////////////////////////////////////////////////////////////// public void updateFilter(OrderBookFilter orderBookFilter) { @@ -130,6 +130,20 @@ public class OrderBook }); } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Getter + /////////////////////////////////////////////////////////////////////////////////////////// + + public SortedList getOfferList() + { + return offerList; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private Methods + /////////////////////////////////////////////////////////////////////////////////////////// + private boolean countryInList(Locale orderBookFilterLocale, List offerConstraintsLocales) { for (Locale locale : offerConstraintsLocales) @@ -152,16 +166,4 @@ public class OrderBook } return false; } - - private boolean matchBankAccountTypeEnum(BankAccountType.BankAccountTypeEnum orderBookFilterBankAccountType, List offerConstraintsBankAccountTypes) - { - for (BankAccountType.BankAccountTypeEnum bankAccountType : offerConstraintsBankAccountTypes) - { - if (bankAccountType.equals(orderBookFilterBankAccountType)) - return true; - } - return false; - } - - } diff --git a/src/main/java/io/bitsquare/trade/orderbook/OrderBookFilter.java b/src/main/java/io/bitsquare/trade/orderbook/OrderBookFilter.java index 2305ad0e5f..46d083856b 100644 --- a/src/main/java/io/bitsquare/trade/orderbook/OrderBookFilter.java +++ b/src/main/java/io/bitsquare/trade/orderbook/OrderBookFilter.java @@ -11,7 +11,10 @@ public class OrderBookFilter private double amount; private Direction direction; - // setters + + /////////////////////////////////////////////////////////////////////////////////////////// + // Setters + /////////////////////////////////////////////////////////////////////////////////////////// public void setAmount(double amount) { @@ -32,7 +35,10 @@ public class OrderBookFilter } - // getters + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + public double getAmount() { return amount; @@ -48,12 +54,16 @@ public class OrderBookFilter return price; } - public SimpleBooleanProperty getChangedProperty() { return changedProperty; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private Methods + /////////////////////////////////////////////////////////////////////////////////////////// + private void triggerChange() { changedProperty.set(!changedProperty.get()); diff --git a/src/main/java/io/bitsquare/user/User.java b/src/main/java/io/bitsquare/user/User.java index 2f389a7b08..b3b62f6a58 100644 --- a/src/main/java/io/bitsquare/user/User.java +++ b/src/main/java/io/bitsquare/user/User.java @@ -16,7 +16,7 @@ public class User implements Serializable private String accountID; private String messageID; - private boolean online; + private boolean isOnline; private List bankAccounts = new ArrayList<>(); private BankAccount currentBankAccount = null; @@ -24,39 +24,34 @@ public class User implements Serializable { } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Public Methods + /////////////////////////////////////////////////////////////////////////////////////////// + public void updateFromStorage(User savedUser) { if (savedUser != null) { accountID = savedUser.getAccountID(); messageID = savedUser.getMessageID(); - online = savedUser.isOnline(); + isOnline = savedUser.getIsOnline(); bankAccounts = savedUser.getBankAccounts(); currentBankAccount = savedUser.getCurrentBankAccount(); } } - public String getStringifiedBankAccounts() - { - String bankAccountUIDs = ""; - for (Iterator iterator = getBankAccounts().iterator(); iterator.hasNext(); ) - { - BankAccount bankAccount = iterator.next(); - bankAccountUIDs += bankAccount.getStringifiedBankAccount(); - - if (iterator.hasNext()) - bankAccountUIDs += ", "; - } - return bankAccountUIDs; - } - public void addBankAccount(BankAccount bankAccount) { bankAccounts.add(bankAccount); currentBankAccount = bankAccount; } - // setter + + /////////////////////////////////////////////////////////////////////////////////////////// + // Setters + /////////////////////////////////////////////////////////////////////////////////////////// + public void setMessageID(String messageID) { this.messageID = messageID; @@ -78,14 +73,30 @@ public class User implements Serializable triggerChange(); } - - public void setOnline(boolean online) + public void setIsOnline(boolean isOnline) { - this.online = online; + this.isOnline = isOnline; } - // getter + /////////////////////////////////////////////////////////////////////////////////////////// + // Getters + /////////////////////////////////////////////////////////////////////////////////////////// + + public String getStringifiedBankAccounts() + { + String bankAccountUIDs = ""; + for (Iterator iterator = getBankAccounts().iterator(); iterator.hasNext(); ) + { + BankAccount bankAccount = iterator.next(); + bankAccountUIDs += bankAccount.getStringifiedBankAccount(); + + if (iterator.hasNext()) + bankAccountUIDs += ", "; + } + return bankAccountUIDs; + } + public String getMessageID() { return messageID; @@ -106,18 +117,21 @@ public class User implements Serializable return currentBankAccount; } - - public boolean isOnline() + public boolean getIsOnline() { - return online; + return isOnline; } - public SimpleBooleanProperty getChangedProperty() { return changedProperty; } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private Methods + /////////////////////////////////////////////////////////////////////////////////////////// + private void triggerChange() { changedProperty.set(!changedProperty.get());