payment process update to model changes

This commit is contained in:
Manfred Karrer 2014-04-30 23:04:10 +02:00
parent 604e9beca9
commit 256388e4e3
29 changed files with 784 additions and 650 deletions

View File

@ -5,9 +5,12 @@
Messaging!
low prio:
- tx confirm. not working correct and reliable
- add settings after setup
- settings screen
- return to setup when unregistered, change/add bank accounts from settings
- warning popups
-

View File

@ -8,6 +8,7 @@ import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.util.Localisation;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Storage;
import io.bitsquare.user.Arbitrator;
import io.bitsquare.user.User;
import javafx.application.Application;
import javafx.scene.Parent;
@ -17,6 +18,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale;
import java.util.UUID;
public class BitSquare extends Application
{
@ -41,7 +43,7 @@ public class BitSquare extends Application
user.updateFromStorage((User) storage.read(user.getClass().getName()));
settings.updateFromStorage((Settings) storage.read(settings.getClass().getName()));
initSettings(settings, storage);
initSettings(settings, storage, user);
stage.setTitle("BitSquare");
@ -71,11 +73,12 @@ public class BitSquare extends Application
super.stop();
}
private void initSettings(Settings settings, Storage storage)
private void initSettings(Settings settings, Storage storage, User user)
{
Settings savedSettings = (Settings) storage.read(settings.getClass().getName());
if (savedSettings == null)
{
// write default settings
settings.getAcceptedCountryLocales().clear();
settings.getAcceptedLanguageLocales().clear();
@ -90,7 +93,35 @@ public class BitSquare extends Application
settings.addAcceptedCountryLocale(new Locale("en", "US"));
settings.addAcceptedCountryLocale(new Locale("es", "ES"));
settings.addArbitrator(new Arbitrator("Charly Boom", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Charly_Boom"));
settings.addArbitrator(new Arbitrator("Tom Shang", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Tom_Shang"));
settings.addArbitrator(new Arbitrator("Edward Snow", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Edward_Swow"));
settings.addArbitrator(new Arbitrator("Julian Sander", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Julian_Sander"));
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);
*/
}
else
{

View File

@ -1,6 +1,7 @@
package io.bitsquare.btc;
import com.google.inject.Inject;
import io.bitsquare.bank.BankAccount;
/**
* That facade delivers blockchain functionality from the bitcoinJ library
@ -15,11 +16,14 @@ public class BlockChainFacade
}
public boolean verifyAddressInBlockChain(String hashAsHexStringToVerify, String address)
public boolean verifyEmbeddedData(String address)
{
return findAddressInBlockChain(address)
&& getDataForTxWithAddress(hashAsHexStringToVerify, address)
&& isFeePayed(address);
return true;
/*
if (findAddressInBlockChain(address) && isFeePayed(address))
return getDataForTxWithAddress(address) != null;
else
return true; */
}
private boolean findAddressInBlockChain(String address)
@ -29,11 +33,11 @@ public class BlockChainFacade
return true;
}
private boolean getDataForTxWithAddress(String hashToVerify, String address)
private byte[] getDataForTxWithAddress(String address)
{
// TODO
// check if data after OP_RETURN match hashToVerify
return true;
// return data after OP_RETURN
return null;
}
private boolean isFeePayed(String address)
@ -43,4 +47,17 @@ public class BlockChainFacade
return true;
}
public boolean isAccountIDBlacklisted(String accountID)
{
// TODO
// check if accountID is on blacklist
return false;
}
public boolean isBankAccountBlacklisted(BankAccount bankAccount)
{
// TODO
// check if accountID is on blacklist
return false;
}
}

View File

@ -171,9 +171,11 @@ public class WalletFacade implements WalletEventListener
public boolean verifyAccountRegistration(String address, String hashAsHexStringToVerify, byte[] pubKey, String bankAccountIDs, String signatureBankAccountIDs)
{
return true;
/*
return cryptoFacade.verifySignature(pubKey, bankAccountIDs, signatureBankAccountIDs)
&& cryptoFacade.verifyHash(hashAsHexStringToVerify, bankAccountIDs, signatureBankAccountIDs)
&& blockChainFacade.verifyAddressInBlockChain(hashAsHexStringToVerify, address);
&& blockChainFacade.verifyEmbeddedData(address); */
}
public int getRegConfNumBroadcastPeers()

View File

@ -14,7 +14,6 @@ import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.OrderBookFilterSettings;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.Trading;
@ -36,7 +35,6 @@ public class BitSquareModule extends AbstractModule
bind(Storage.class).asEagerSingleton();
bind(Settings.class).asEagerSingleton();
bind(OrderBookFilter.class).asEagerSingleton();
bind(OrderBookFilterSettings.class).asEagerSingleton();
bind(CryptoFacade.class).asEagerSingleton();
bind(WalletFacade.class).asEagerSingleton();

View File

@ -33,7 +33,7 @@ public class ConfirmationComponent implements WalletFacade.WalletListener
{
confirmIconImageView.setImage(getConfirmIconImage(numBroadcastPeers, depthInBlocks));
confirmationsLabel.setText(getConfirmationsText(numBroadcastPeers, depthInBlocks));
if (depthInBlocks == 0)
if (depthInBlocks == 0 && numBroadcastPeers > 0)
confirmSpinner.setProgress(-1);
else
confirmSpinner.setOpacity(0);

View File

@ -1,5 +1,6 @@
package io.bitsquare.gui.components.processbar;
import io.bitsquare.gui.util.Colors;
import javafx.scene.paint.Paint;
public class ProcessStepItem
@ -10,7 +11,7 @@ public class ProcessStepItem
public ProcessStepItem(String label)
{
this(label, Paint.valueOf("#000000"), false);
this(label, Colors.BLUE, false);
}
public ProcessStepItem(String label, Paint color)

View File

@ -1,6 +1,6 @@
package io.bitsquare.gui.components.processbar;
import io.bitsquare.gui.util.GUIUtils;
import io.bitsquare.util.Utils;
import javafx.animation.AnimationTimer;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
@ -65,7 +65,7 @@ public class ProcessStepsBuilder
// TODO
// mock simulate network delay
GUIUtils.setTimeout(100, (AnimationTimer animationTimer) -> {
Utils.setTimeout(100, (AnimationTimer animationTimer) -> {
next();
return null;
});

View File

@ -45,6 +45,21 @@
-fx-text-fill: #0096c9;
}
.text-field:readonly {
-fx-text-fill: #000000;
-fx-background-color: #ffffff;
}
#feedback-text {
-fx-font-size: 10;
}
#label-url {
-fx-cursor: hand;
-fx-text-fill: blue;
-fx-underline: true;
}
/* table */
#orderbook-table .table-cell {
@ -59,10 +74,6 @@
-fx-alignment: center;
}
#feedback-text {
-fx-font-size: 10;
}
/* forms */
#form-header-text {
-fx-font-weight: bold;

View File

@ -7,16 +7,16 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.components.ConfirmationComponent;
import io.bitsquare.gui.components.NetworkSyncPane;
import io.bitsquare.gui.components.processbar.ProcessStepBar;
import io.bitsquare.gui.components.processbar.ProcessStepItem;
import io.bitsquare.gui.util.*;
import io.bitsquare.gui.util.FormBuilder;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.settings.Settings;
import io.bitsquare.gui.util.Localisation;
import io.bitsquare.gui.util.Verification;
import io.bitsquare.storage.Storage;
import io.bitsquare.user.User;
import io.bitsquare.util.Utils;
@ -27,7 +27,9 @@ import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;
import org.controlsfx.dialog.Dialogs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,12 +43,8 @@ public class SetupController implements Initializable, ChildController, WalletFa
private User user;
private final WalletFacade walletFacade;
private CryptoFacade cryptoFacade;
private Settings settings;
private Storage storage;
private List<ProcessStepItem> processStepItems = new ArrayList();
private NavigationController navigationController;
private TextField balanceLabel, accountTitle, accountHolderName, accountPrimaryID, accountSecondaryID;
private ComboBox countryComboBox, bankTransferTypeComboBox, currencyComboBox;
@ -59,32 +57,29 @@ public class SetupController implements Initializable, ChildController, WalletFa
@FXML
private ProcessStepBar<String> processStepBar;
@FXML
private GridPane formGridPane;
private GridPane gridPane;
@FXML
private Button nextButton, skipButton;
@FXML
private VBox vBox;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor(s)
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public SetupController(User user, WalletFacade walletFacade, CryptoFacade cryptoFacade, Settings settings, Storage storage)
public SetupController(User user, WalletFacade walletFacade, Storage storage)
{
this.user = user;
this.walletFacade = walletFacade;
this.cryptoFacade = cryptoFacade;
this.settings = settings;
this.storage = storage;
}
public void initialize(URL url, ResourceBundle rb)
{
processStepItems.add(new ProcessStepItem("Fund registration fee", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Add Bank account", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Complete", Colors.BLUE));
processStepBar.setProcessStepItems(processStepItems);
walletFacade.addRegistrationWalletListener(this);
buildStep0();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
// pass in NetworkSyncPane from parent view
public void setNetworkSyncPane(NetworkSyncPane networkSyncPane)
@ -92,12 +87,40 @@ public class SetupController implements Initializable, ChildController, WalletFa
rootContainer.getChildren().add(networkSyncPane);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: Initializable
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
processStepItems.add(new ProcessStepItem("Fund registration fee"));
processStepItems.add(new ProcessStepItem("Add Bank account"));
processStepItems.add(new ProcessStepItem("Complete"));
processStepBar.setProcessStepItems(processStepItems);
walletFacade.addRegistrationWalletListener(this);
buildStep0();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: ChildController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: WalletFacade.WalletListener
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks)
{
@ -115,40 +138,9 @@ public class SetupController implements Initializable, ChildController, WalletFa
}
private void close()
{
walletFacade.removeRegistrationWalletListener(this);
navigationController.navigateToView(NavigationController.HOME, "");
}
// TODO need checks per bankTransferType
private boolean verifyBankAccountData()
{
boolean accountIDsByBankTransferTypeValid = Verification.verifyAccountIDsByBankTransferType(bankTransferTypeComboBox.getSelectionModel().getSelectedItem(),
accountPrimaryID.getText(),
accountSecondaryID.getText());
return bankTransferTypeComboBox.getSelectionModel().getSelectedItem() != null
&& countryComboBox.getSelectionModel().getSelectedItem() != null
&& currencyComboBox.getSelectionModel().getSelectedItem() != null
&& accountTitle.getText().length() > 0
&& accountHolderName.getText().length() > 0
&& accountPrimaryID.getText().length() > 0
&& accountSecondaryID.getText().length() > 0
&& accountIDsByBankTransferTypeValid;
}
private void updateCreateAccountButton()
{
boolean funded = walletFacade.getAccountRegistrationBalance().compareTo(BigInteger.ZERO) > 0;
nextButton.setDisable(!funded || walletFacade.getRegConfDepthInBlocks() == 0);
}
///////////////////////////////////////////////////////////////////////////////////
// GUI BUILDER
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void buildStep0()
{
@ -159,19 +151,19 @@ public class SetupController implements Initializable, ChildController, WalletFa
"Your trading account will be the source for your reputation in the trading platform.\n\n" +
"You need at least 1 confirmation for doing the registration payment.");
int gridRow = -1;
int row = -1;
TextField addressLabel = FormBuilder.addTextField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++gridRow, false, true);
TextField addressLabel = FormBuilder.addTextField(gridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++row, false, true);
Label copyIcon = new Label("");
formGridPane.add(copyIcon, 2, gridRow);
gridPane.add(copyIcon, 2, row);
copyIcon.setId("copy-icon");
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
balanceLabel = FormBuilder.addTextField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++gridRow);
balanceLabel = FormBuilder.addTextField(gridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++row);
ConfirmationComponent confirmationComponent = new ConfirmationComponent(walletFacade, formGridPane, ++gridRow);
new ConfirmationComponent(walletFacade, gridPane, ++row);
nextButton.setText("Payment done");
updateCreateAccountButton();
@ -200,9 +192,9 @@ public class SetupController implements Initializable, ChildController, WalletFa
"That data will be stored in the blockchain in a way that your privacy is protected.\n" +
"Only your trading partners will be able to read those data, so your privacy will be protected.");
formGridPane.getChildren().clear();
int gridRow = -1;
bankTransferTypeComboBox = FormBuilder.addComboBox(formGridPane, "Bank account type:", Utils.getAllBankAccountTypes(), ++gridRow);
gridPane.getChildren().clear();
int row = -1;
bankTransferTypeComboBox = FormBuilder.addComboBox(gridPane, "Bank account type:", Utils.getAllBankAccountTypes(), ++row);
bankTransferTypeComboBox.setConverter(new StringConverter<BankAccountType>()
{
@Override
@ -219,12 +211,12 @@ public class SetupController implements Initializable, ChildController, WalletFa
});
bankTransferTypeComboBox.setPromptText("Select bank account type");
accountTitle = FormBuilder.addInputField(formGridPane, "Bank account title:", "", ++gridRow);
accountHolderName = FormBuilder.addInputField(formGridPane, "Bank account holder name:", "", ++gridRow);
accountPrimaryID = FormBuilder.addInputField(formGridPane, "Bank account primary ID", "", ++gridRow);
accountSecondaryID = FormBuilder.addInputField(formGridPane, "Bank account secondary ID:", "", ++gridRow);
accountTitle = FormBuilder.addInputField(gridPane, "Bank account title:", "", ++row);
accountHolderName = FormBuilder.addInputField(gridPane, "Bank account holder name:", "", ++row);
accountPrimaryID = FormBuilder.addInputField(gridPane, "Bank account primary ID", "", ++row);
accountSecondaryID = FormBuilder.addInputField(gridPane, "Bank account secondary ID:", "", ++row);
currencyComboBox = FormBuilder.addComboBox(formGridPane, "Currency used for bank account:", Utils.getAllCurrencies(), ++gridRow);
currencyComboBox = FormBuilder.addComboBox(gridPane, "Currency used for bank account:", Utils.getAllCurrencies(), ++row);
currencyComboBox.setPromptText("Select currency");
currencyComboBox.setConverter(new StringConverter<Currency>()
{
@ -241,7 +233,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
}
});
countryComboBox = FormBuilder.addComboBox(formGridPane, "Country of bank account:", Utils.getAllLocales(), ++gridRow);
countryComboBox = FormBuilder.addComboBox(gridPane, "Country of bank account:", Utils.getAllLocales(), ++row);
countryComboBox.setPromptText("Select country");
countryComboBox.setConverter(new StringConverter<Locale>()
{
@ -260,7 +252,7 @@ public class SetupController implements Initializable, ChildController, WalletFa
addBankAccountButton = new Button("Add other Bank account");
formGridPane.add(addBankAccountButton, 1, ++gridRow);
gridPane.add(addBankAccountButton, 1, ++row);
nextButton.setText("Create account");
checkCreateAccountButtonState();
@ -318,22 +310,100 @@ public class SetupController implements Initializable, ChildController, WalletFa
buildStep2();
} catch (InsufficientMoneyException e1)
{
log.warn(e1.toString());
// TODO
processStepBar.next();
buildStep2();
Dialogs.create()
.title("Not enough money available")
.message("There is not enough money available. Please pay in first to your wallet.")
.nativeTitleBar()
.lightweight()
.showError();
}
}
else
{
log.warn("You need to add a bank account first!");
//TODO warning popup
}
});
skipButton.setOnAction(e -> close());
}
private void buildStep2()
{
vBox.getChildren().remove(infoLabel);
vBox.getChildren().remove(nextButton);
vBox.getChildren().remove(skipButton);
gridPane.getChildren().clear();
int row = -1;
FormBuilder.addHeaderLabel(gridPane, "Registration complete", ++row);
FormBuilder.addTextField(gridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++row);
FormBuilder.addTextField(gridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++row);
Button closeButton = FormBuilder.addButton(gridPane, "Close", ++row);
closeButton.setDefaultButton(true);
closeButton.setOnAction(e -> close());
FormBuilder.addVSpacer(gridPane, ++row);
FormBuilder.addHeaderLabel(gridPane, "Summary", ++row);
Label info = new Label("You have saved following bank accounts with your trading account to the blockchain:");
gridPane.add(info, 0, ++row);
GridPane.setColumnSpan(info, 3);
FormBuilder.addVSpacer(gridPane, ++row);
List<BankAccount> bankAccounts = user.getBankAccounts();
Iterator<BankAccount> iterator = bankAccounts.iterator();
int index = 0;
while (iterator.hasNext())
{
FormBuilder.addHeaderLabel(gridPane, "Bank account " + (index + 1), ++row);
BankAccount bankAccount = iterator.next();
// need to get updated row from subroutine
row = buildBankAccountDetails(bankAccount, ++row);
FormBuilder.addVSpacer(gridPane, ++row);
index++;
}
}
private void close()
{
walletFacade.removeRegistrationWalletListener(this);
navigationController.navigateToView(NavigationController.HOME, "");
}
// util
private int buildBankAccountDetails(BankAccount bankAccount, int row)
{
FormBuilder.addTextField(gridPane, "Bank account holder name:", bankAccount.getAccountHolderName(), ++row);
FormBuilder.addTextField(gridPane, "Bank account type", bankAccount.getBankAccountType().toString(), ++row);
FormBuilder.addTextField(gridPane, "Bank account primary ID", bankAccount.getAccountPrimaryID(), ++row);
FormBuilder.addTextField(gridPane, "Bank account secondary ID:", bankAccount.getAccountSecondaryID(), ++row);
return row;
}
// TODO need checks per bankTransferType
private boolean verifyBankAccountData()
{
boolean accountIDsByBankTransferTypeValid = Verification.verifyAccountIDsByBankTransferType(bankTransferTypeComboBox.getSelectionModel().getSelectedItem(),
accountPrimaryID.getText(),
accountSecondaryID.getText());
return bankTransferTypeComboBox.getSelectionModel().getSelectedItem() != null
&& countryComboBox.getSelectionModel().getSelectedItem() != null
&& currencyComboBox.getSelectionModel().getSelectedItem() != null
&& accountTitle.getText().length() > 0
&& accountHolderName.getText().length() > 0
&& accountPrimaryID.getText().length() > 0
&& accountSecondaryID.getText().length() > 0
&& accountIDsByBankTransferTypeValid;
}
private void updateCreateAccountButton()
{
boolean funded = walletFacade.getAccountRegistrationBalance().compareTo(BigInteger.ZERO) > 0;
nextButton.setDisable(!funded || walletFacade.getRegConfDepthInBlocks() == 0);
}
private void addBankAccount()
{
if (verifyBankAccountData())
@ -355,47 +425,5 @@ public class SetupController implements Initializable, ChildController, WalletFa
nextButton.setDisable(!verifyBankAccountData());
addBankAccountButton.setDisable(!verifyBankAccountData());
}
private void buildStep2()
{
infoLabel.setText("Summary:\n" +
"You have saved following bank accounts with your trading account to the blockchain:");
formGridPane.getChildren().clear();
int gridRow = -1;
List<BankAccount> bankAccounts = user.getBankAccounts();
Iterator<BankAccount> iterator = bankAccounts.iterator();
int index = 0;
while (iterator.hasNext())
{
FormBuilder.addHeaderLabel(formGridPane, "Bank account " + (index + 1), ++gridRow);
BankAccount bankAccount = iterator.next();
// need to get updated gridRow from subroutine
gridRow = buildBankAccountDetails(bankAccount, ++gridRow);
FormBuilder.addVSpacer(formGridPane, ++gridRow);
index++;
}
FormBuilder.addVSpacer(formGridPane, ++gridRow);
FormBuilder.addTextField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++gridRow);
FormBuilder.addTextField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++gridRow);
nextButton.setText("Done");
skipButton.setOpacity(0);
// handlers
nextButton.setOnAction(e -> close());
}
// util
private int buildBankAccountDetails(BankAccount bankAccount, int row)
{
FormBuilder.addTextField(formGridPane, "Bank account holder name:", bankAccount.getAccountHolderName(), ++row);
FormBuilder.addTextField(formGridPane, "Bank account type", bankAccount.getBankAccountType().toString(), ++row);
FormBuilder.addTextField(formGridPane, "Bank account primary ID", bankAccount.getAccountPrimaryID(), ++row);
FormBuilder.addTextField(formGridPane, "Bank account secondary ID:", bankAccount.getAccountSecondaryID(), ++row);
return row;
}
}

View File

@ -8,12 +8,12 @@
<ScrollPane fitToWidth="true" AnchorPane.leftAnchor="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="10"
AnchorPane.bottomAnchor="30">
<content>
<VBox spacing="10">
<VBox fx:id="vBox" spacing="10">
<Label text="Setup trading account" id="headline-label"/>
<ProcessStepBar fx:id="processStepBar"/>
<VSpacer prefHeight="10"/>
<Label fx:id="infoLabel"/>
<GridPane fx:id="formGridPane" vgap="5" hgap="5">
<GridPane fx:id="gridPane" vgap="5" hgap="5">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>

View File

@ -25,6 +25,7 @@ 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;
@ -120,6 +121,7 @@ public class CreateOfferController implements Initializable, ChildController, Wa
user.getCurrentBankAccount().getBankAccountType().getType(),
user.getCurrentBankAccount().getCurrency(),
user.getCurrentBankAccount().getCountryLocale(),
settings.getRandomArbitrator(),
settings.getAcceptedCountryLocales(),
settings.getAcceptedLanguageLocales());
@ -131,8 +133,12 @@ public class CreateOfferController implements Initializable, ChildController, Wa
buildConfirmationView(txID);
} catch (InsufficientMoneyException e1)
{
//TODO popup
log.error(e.toString());
Dialogs.create()
.title("Not enough money available")
.message("There is not enough money available. Please pay in first to your wallet.")
.nativeTitleBar()
.lightweight()
.showError();
}
}
});

View File

@ -159,7 +159,7 @@ public class OrderBookController implements Initializable, ChildController
if (!amount.getText().equals(""))
requestedAmount = Converter.stringToDouble(amount.getText());
tradeProcessController.initView(orderBookListItem.getOffer(), requestedAmount);
tradeProcessController.initWithData(orderBookListItem.getOffer(), requestedAmount);
}
private void updateOfferList()

View File

@ -1,125 +1,296 @@
package io.bitsquare.gui.trade.tradeprocess;
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.VSpacer;
import io.bitsquare.gui.components.processbar.ProcessStepBar;
import io.bitsquare.gui.components.processbar.ProcessStepItem;
import io.bitsquare.gui.util.*;
import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.FormBuilder;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.*;
import io.bitsquare.user.User;
import io.bitsquare.util.Utils;
import javafx.animation.AnimationTimer;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
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 TradeProcessController implements Initializable, ChildController
public class TradeProcessController implements Initializable, ChildController, WalletFacade.WalletListener
{
private static final Logger log = LoggerFactory.getLogger(TradeProcessController.class);
private static final int SIM_DELAY = 1000;
private Trading trading;
private User user;
private WalletFacade walletFacade;
private BlockChainFacade blockChainFacade;
private Settings settings;
private Storage storage;
private Offer offer;
private Trade trade;
private Contract contract;
private double requestedAmount;
private boolean offererIsOnline;
private List<ProcessStepItem> processStepItems = new ArrayList();
private NavigationController navigationController;
private List<ProcessStepItem> processStepItems = new ArrayList();
private double requestedAmount;
private VBox vBox;
private TitledPane offerDetailsTitlePane, contractTitlePane;
private ProcessStepBar<String> processStepBar;
private TextField amountTextField, totalToPayLabel, totalLabel;
private Label statusTextField;
private Button nextButton;
private TextField amountTextField;
private Label offererPubKeyLabel, offererAccountPrimaryID, offererAccountSecondaryIDLabel,
offererAccountHolderNameLabel, feedbackLabel, infoLabel, totalLabel, volumeLabel, totalToPayLabel,
/*totalToReceiveLabel,*/ amountLabel;
private Pane progressPane;
private ProgressBar progressBar;
private ProgressIndicator progressIndicator;
@FXML
public AnchorPane rootContainer;
private AnchorPane rootContainer;
@FXML
private ProcessStepBar<String> processStepBar;
@FXML
private GridPane formGridPane;
@FXML
private VBox vBox;
private Label infoLabel;
private int gridRow;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor(s)
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TradeProcessController(Trading trading)
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 initialize(URL url, ResourceBundle rb)
public void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks)
{
log.info("onConfidenceChanged " + numBroadcastPeers + " / " + depthInBlocks);
}
public void initView(Offer offer, double requestedAmount)
@Override
public void onCoinsReceived(BigInteger newBalance)
{
this.offer = offer;
this.requestedAmount = requestedAmount;
trade = trading.createNewTrade(offer);
trade.setRequestedAmount(requestedAmount);
contract = trading.createNewContract(trade);
processStepItems.add(new ProcessStepItem(takerIsSelling() ? "Sell BTC" : "Buy BTC", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Bank transfer", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Completed", Colors.BLUE));
processStepBar = new ProcessStepBar(processStepItems);
buildStep1();
log.info("onCoinsReceived " + newBalance);
}
private void trade()
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
// trade process
///////////////////////////////////////////////////////////////////////////////////////////
private void buildTakeOfferScreen()
{
double requestedAmount = Converter.stringToDouble(amountTextField.getText());
if (requestedAmount <= offer.getAmount() && requestedAmount >= offer.getMinAmount())
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())
{
amountTextField.setEditable(false);
trade.setRequestedAmount(requestedAmount);
if (blockChainFacade.verifyEmbeddedData(offer.getAccountID()))
{
if (!blockChainFacade.isAccountIDBlacklisted(offer.getAccountID()))
{
amountTextField.setEditable(false);
vBox.getChildren().remove(nextButton);
AnchorPane.setTopAnchor(contractTitlePane, 350.0);
formGridPane.getChildren().clear();
progressBar = new ProgressBar();
progressBar.setProgress(0.0);
progressBar.setPrefWidth(200);
progressBar.relocate(10, 10);
int gridRow = -1;
FormBuilder.addHeaderLabel(formGridPane, "Trade request inited", ++gridRow, 0);
progressIndicator = new ProgressIndicator();
progressIndicator.setProgress(-1.0);
progressIndicator.setPrefSize(20, 20);
progressIndicator.relocate(220, 10);
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);
feedbackLabel = new Label();
feedbackLabel.setPadding(new Insets(-10, 0, 0, 0));
feedbackLabel.setId("feedback-text");
feedbackLabel.relocate(10, 50);
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);
progressPane = new Pane();
progressPane.getChildren().addAll(progressBar, progressIndicator, feedbackLabel);
trade.setTradeAmount(Converter.stringToDouble(amountTextField.getText()));
trading.sendTakeOfferRequest(trade);
vBox.getChildren().add(progressPane);
sendTakeOfferRequest();
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
{
@ -132,24 +303,12 @@ public class TradeProcessController implements Initializable, ChildController
}
}
// Payment Process
private void sendTakeOfferRequest()
{
trading.sendTakeOfferRequest(trade);
feedbackLabel.setText("Request take offer confirmation from peer.");
GUIUtils.setTimeout(500, (AnimationTimer animationTimer) -> {
onTakeOfferRequestConfirmed();
progressBar.setProgress(1.0 / 3.0);
return null;
});
}
private void onTakeOfferRequestConfirmed()
{
trading.payOfferFee(trade);
feedbackLabel.setText("Request offer fee payment confirmation from peer.");
GUIUtils.setTimeout(500, (AnimationTimer animationTimer) -> {
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;
@ -159,8 +318,8 @@ public class TradeProcessController implements Initializable, ChildController
private void onOfferFeePaymentConfirmed()
{
trading.requestOffererDetailData();
feedbackLabel.setText("Request detail data from peer.");
GUIUtils.setTimeout(500, (AnimationTimer animationTimer) -> {
statusTextField.setText("Request bank account details from offerer.");
Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> {
onUserDetailsReceived();
progressBar.setProgress(1.0);
return null;
@ -169,6 +328,16 @@ public class TradeProcessController implements Initializable, ChildController
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);
@ -179,15 +348,13 @@ public class TradeProcessController implements Initializable, ChildController
{
processStepBar.next();
vBox.getChildren().remove(progressPane);
vBox.getChildren().remove(offerDetailsTitlePane);
vBox.getChildren().remove(nextButton);
rootContainer.getChildren().remove(contractTitlePane);
formGridPane.getChildren().clear();
infoLabel = new Label("Wait for Bank transfer.");
vBox.getChildren().addAll(infoLabel);
gridRow = -1;
FormBuilder.addHeaderLabel(formGridPane, "Bank transfer", ++gridRow, 0);
infoLabel = FormBuilder.addLabel(formGridPane, "Status:", "Wait for Bank transfer.", ++gridRow);
GUIUtils.setTimeout(2000, (AnimationTimer animationTimer) -> {
Utils.setTimeout(SIM_DELAY, (AnimationTimer animationTimer) -> {
onBankTransferInited();
return null;
});
@ -195,10 +362,14 @@ public class TradeProcessController implements Initializable, ChildController
private void onBankTransferInited()
{
infoLabel.setText("Bank transfer has been inited.\nCheck your bank account and continue when you have received the money.\n");
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());
vBox.getChildren().add(nextButton);
}
private void releaseBTC()
@ -206,157 +377,68 @@ public class TradeProcessController implements Initializable, ChildController
processStepBar.next();
trading.releaseBTC(trade);
vBox.getChildren().remove(infoLabel);
nextButton.setText("Close");
nextButton.setOnAction(e -> close());
GridPane summaryGridPane = new GridPane();
int row = 0;
summaryGridPane.setVgap(5);
summaryGridPane.setHgap(5);
summaryGridPane.setPadding(new Insets(5, 5, 5, 5));
FormBuilder.addLabel(summaryGridPane, "You have payed:", getTotalToPay(), ++row);
// FormBuilder.addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row);
TitledPane summaryTitlePane = new TitledPane("Trade summary:", summaryGridPane);
summaryTitlePane.setCollapsible(false);
vBox.getChildren().add(2, summaryTitlePane);
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 void buildStep1()
{
User taker = contract.getTaker();
User offerer = contract.getOfferer();
GridPane offerDetailsGridPane = new GridPane();
int row = 0;
offerDetailsGridPane.setVgap(5);
offerDetailsGridPane.setHgap(5);
offerDetailsGridPane.setPadding(new Insets(5, 5, 5, 5));
amountTextField = FormBuilder.addTextField(offerDetailsGridPane, "Amount (BTC):", Formatter.formatAmount(getAmount()), ++row);
amountTextField.textProperty().addListener(e -> {
setTotal();
setVolume();
//setCollateral();
totalToPayLabel.setText(getTotalToPay());
// totalToReceiveLabel.setText(getTotalToReceive());
amountLabel.setText(amountTextField.getText());
});
offerDetailsGridPane.add(new Label("(" + offer.getAmount() + "BTC - " + offer.getMinAmount() + "BTC)"), 2, row);
FormBuilder.addLabel(offerDetailsGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
totalLabel = FormBuilder.addLabel(offerDetailsGridPane, "Total:", "", ++row);
setTotal();
FormBuilder.addLabel(offerDetailsGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++row);
FormBuilder.addVSpacer(offerDetailsGridPane, ++row);
totalToPayLabel = FormBuilder.addLabel(offerDetailsGridPane, "You pay:", getTotalToPay(), ++row);
// totalToReceiveLabel = FormBuilder.addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row);
offerDetailsTitlePane = new TitledPane(takerIsSelling() ? "Sell Bitcoin" : "Buy Bitcoin", offerDetailsGridPane);
offerDetailsTitlePane.setCollapsible(false);
nextButton = new Button(processStepItems.get(0).getLabel());
nextButton.setDefaultButton(true);
nextButton.setOnAction(e -> trade());
GridPane contractGridPane = new GridPane();
contractGridPane.setVgap(5);
contractGridPane.setHgap(5);
contractGridPane.setPadding(new Insets(5, 5, 5, 5));
row = 0;
FormBuilder.addHeaderLabel(contractGridPane, "Offer details:", row);
FormBuilder.addLabel(contractGridPane, "Offer ID:", offer.getUid().toString(), ++row);
FormBuilder.addLabel(contractGridPane, "Offer type:", Formatter.formatDirection((offer.getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY), false), ++row);
amountLabel = FormBuilder.addLabel(contractGridPane, "Amount:", Formatter.formatAmount(getAmount()), ++row);
volumeLabel = FormBuilder.addLabel(contractGridPane, "Volume:", "", ++row);
setVolume();
FormBuilder.addLabel(contractGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
//setCollateral();
// FormBuilder.addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getAcceptedLanguageLocales()), ++row);
// FormBuilder.addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row);
// FormBuilder.addLabel(contractGridPane, "Identity verification:", Formatter.formatList(offerConstraints.getIdentityVerifications()), ++row);
FormBuilder.addLabel(contractGridPane, "Bank transfer reference ID:", "Purchase xyz 01.04.2014", ++row);
FormBuilder.addVSpacer(contractGridPane, ++row);
FormBuilder.addHeaderLabel(contractGridPane, "Offerer data:", ++row);
FormBuilder.addLabel(contractGridPane, "Account ID:", offerer.getAccountID(), ++row);
FormBuilder.addLabel(contractGridPane, "Messaging ID:", offerer.getMessageID(), ++row);
//FormBuilder.addLabel(contractGridPane, "Country:", offerer.getCountry(), ++row);
offererPubKeyLabel = FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getOffererPubKey(), ++row);
// FormBuilder.addLabel(contractGridPane, "Bank transfer type:", offerer.getCurrentBankAccount().getBankAccountType().toString(), ++row);
// offererAccountPrimaryID = FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", offerer.getCurrentBankAccount().getAccountPrimaryID(), ++row);
offererAccountSecondaryIDLabel = FormBuilder.addLabel(contractGridPane, "Bank account BIC:", offerer.getCurrentBankAccount().getAccountSecondaryID(), ++row);
offererAccountHolderNameLabel = FormBuilder.addLabel(contractGridPane, "Bank account holder:", offerer.getCurrentBankAccount().getAccountHolderName(), ++row);
FormBuilder.addVSpacer(contractGridPane, ++row);
FormBuilder.addHeaderLabel(contractGridPane, "Offer taker data:", ++row);
FormBuilder.addLabel(contractGridPane, "Account ID:", taker.getAccountID(), ++row);
FormBuilder.addLabel(contractGridPane, "Messaging ID:", taker.getMessageID(), ++row);
// FormBuilder.addLabel(contractGridPane, "Country:", taker.getCountry(), ++row);
FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getTakerPubKey(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank transfer type:", taker.getCurrentBankAccount().getBankAccountType().toString(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", taker.getCurrentBankAccount().getAccountPrimaryID(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank account BIC:", taker.getCurrentBankAccount().getAccountSecondaryID(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank account holder:", taker.getCurrentBankAccount().getAccountHolderName(), ++row);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(contractGridPane);
contractTitlePane = new TitledPane("Contract", scrollPane);
contractTitlePane.setCollapsible(false);
AnchorPane.setLeftAnchor(contractTitlePane, 10.0);
AnchorPane.setRightAnchor(contractTitlePane, 10.0);
AnchorPane.setTopAnchor(contractTitlePane, 324.0);
AnchorPane.setBottomAnchor(contractTitlePane, 10.0);
vBox = new VBox();
AnchorPane.setLeftAnchor(vBox, 10.0);
AnchorPane.setRightAnchor(vBox, 10.0);
AnchorPane.setTopAnchor(vBox, 10.0);
vBox.setSpacing(10);
vBox.getChildren().addAll(processStepBar, new VSpacer(5), offerDetailsTitlePane, nextButton);
rootContainer.getChildren().addAll(vBox, contractTitlePane);
}
private void setTotal()
{
totalLabel.setText(Formatter.formatVolume(getVolume()));
}
private void setVolume()
{
totalLabel.setText(Formatter.formatVolume(getVolume(), offer.getCurrency()));
}
///////////////////////////////////////////////////////////////////////////////////////////
// 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 double getAmount()
{
return requestedAmount > 0 ? requestedAmount : offer.getAmount();
}
private String getTotalToPay()
{
String result = "";
@ -374,28 +456,5 @@ public class TradeProcessController implements Initializable, ChildController
return result;
}
/*private String getTotalToReceive()
{
String result = "";
if (takerIsSelling())
{
double btcValue = offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText());
result = Formatter.formatAmount(btcValue, true, true) + "\n" + Formatter.formatVolume(getVolume(), offer.getCurrency());
}
else
{
double btcValue = Converter.stringToDouble(amountTextField.getText()) +
offer.getConstraints().getCollateral() * Converter.stringToDouble(amountTextField.getText());
result = Formatter.formatAmount(btcValue, true, true);
}
return result;
} */
/*public void setCollateral()
{
String value = Formatter.formatCollateral(offer.getConstraints().getCollateral(), Converter.stringToDouble(amountTextField.getText()));
collateralLabel1.setText(value);
collateralLabel2.setText(value);
}*/
}

View File

@ -1,10 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import io.bitsquare.gui.components.processbar.ProcessStepBar?>
<?import io.bitsquare.gui.components.VSpacer?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="rootContainer"
AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"
AnchorPane.bottomAnchor="0.0"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="io.bitsquare.gui.trade.tradeprocess.TradeProcessController"/>
<AnchorPane fx:id="rootContainer" fx:controller="io.bitsquare.gui.trade.tradeprocess.TradeProcessController"
xmlns:fx="http://javafx.com/fxml">
<ScrollPane fitToWidth="true" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0"
AnchorPane.bottomAnchor="0">
<content>
<VBox fx:id="vBox" spacing="10">
<padding>
<Insets left="10" right="10" top="10" bottom="10"/>
</padding>
<ProcessStepBar fx:id="processStepBar"/>
<VSpacer prefHeight="5"/>
<GridPane fx:id="formGridPane" vgap="5" hgap="5">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
<columnConstraints>
<ColumnConstraints halignment="RIGHT"/>
<ColumnConstraints halignment="LEFT" prefWidth="400"/>
<ColumnConstraints halignment="LEFT"/>
</columnConstraints>
</GridPane>
</VBox>
</content>
</ScrollPane>
</AnchorPane>

View File

@ -20,14 +20,19 @@ public class FormBuilder
return valueLabel;
}
public static Label addHeaderLabel(GridPane gridPane, String title, int row)
public static Label addHeaderLabel(GridPane gridPane, String title, int row, int column)
{
Label headerLabel = new Label(title);
headerLabel.setId("form-header-text");
gridPane.add(headerLabel, 0, row);
gridPane.add(headerLabel, column, row);
return headerLabel;
}
public static Label addHeaderLabel(GridPane gridPane, String title, int row)
{
return addHeaderLabel(gridPane, title, row, 0);
}
public static TextField addInputField(GridPane gridPane, String title, String value, int row)
{
return addTextField(gridPane, title, value, row, true, true);
@ -46,6 +51,7 @@ public class FormBuilder
gridPane.add(textField, 1, row);
textField.setMouseTransparent(!selectable && !editable);
textField.setEditable(editable);
return textField;
}
@ -57,7 +63,7 @@ public class FormBuilder
public static Button addButton(GridPane gridPane, String title, int row)
{
Button button = new Button(title);
gridPane.add(button, 0, row);
gridPane.add(button, 1, row);
return button;
}
@ -80,7 +86,7 @@ public class FormBuilder
ProgressIndicator progressIndicator = new ProgressIndicator();
gridPane.add(progressIndicator, 3, row);
progressIndicator.setPrefSize(18, 18);
if (walletFacade.getRegConfDepthInBlocks() == 0)
if (walletFacade.getRegConfDepthInBlocks() == 0 && walletFacade.getRegConfNumBroadcastPeers() > 0)
progressIndicator.setProgress(-1);
else
progressIndicator.setOpacity(0);

View File

@ -1,35 +0,0 @@
package io.bitsquare.gui.util;
import javafx.animation.AnimationTimer;
import java.util.function.Function;
public class GUIUtils
{
/**
* @param delay in milliseconds
* @param callback
* @usage Utils.setTimeout(1000, (AnimationTimer animationTimer) -> {
* doSomething();
* return null;
* });
*/
public static void setTimeout(int delay, Function<AnimationTimer, Void> callback)
{
long startTime = System.currentTimeMillis();
AnimationTimer animationTimer = new AnimationTimer()
{
@Override
public void handle(long arg0)
{
if (System.currentTimeMillis() > delay + startTime)
{
callback.apply(this);
this.stop();
}
}
};
animationTimer.start();
}
}

View File

@ -1,89 +0,0 @@
package io.bitsquare.settings;
import com.google.inject.Inject;
import io.bitsquare.storage.Storage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class OrderBookFilterSettings
{
private static final Logger log = LoggerFactory.getLogger(OrderBookFilterSettings.class);
private Storage storage;
private Currency currency;
private ArrayList<Currency> currencies;
@Inject
public OrderBookFilterSettings(Storage storage)
{
this.storage = storage;
currencies = getCurrencies();
currency = (Currency) storage.read("OrderBookFilterSettings.currency");
if (currency == null)
setCurrency(currencies.get(0));
}
public enum BankTransferTypes
{
SEPA, OKPAY, WIRE, PERFECT_MONEY, OTHER, ANY
}
public enum Arbitrators
{
PAYSTY, TLS_NOTARY, BIT_RATED, OTHER, ANY, NONE
}
public enum IdVerifications
{
PGP, BTC_OTC, OPEN_ID, NAME_COIN, NAME_ID, PASSPORT, SKYPE, FACEBOOK, GOOGLE_PLUS, TWITTER, OTHER, ANY, NONE
}
//TODO remove duplicated entries, insert separators
public ArrayList<Currency> getCurrencies()
{
ArrayList<Currency> currencies = new ArrayList<>();
currencies.add(Currency.getInstance("USD"));
currencies.add(Currency.getInstance("EUR"));
currencies.add(Currency.getInstance("CNY"));
currencies.add(Currency.getInstance("RUB"));
currencies.add(Currency.getInstance("JPY"));
currencies.add(Currency.getInstance("GBP"));
currencies.add(Currency.getInstance("CAD"));
currencies.add(Currency.getInstance("AUD"));
currencies.add(Currency.getInstance("CHF"));
currencies.add(Currency.getInstance("CNY"));
Set<Currency> otherCurrenciesSet = Currency.getAvailableCurrencies();
ArrayList<Currency> otherCurrenciesList = new ArrayList<>();
otherCurrenciesList.addAll(otherCurrenciesSet);
Collections.sort(otherCurrenciesList, new CurrencyComparator());
currencies.addAll(otherCurrenciesList);
return currencies;
}
public Currency getCurrency()
{
return currency;
}
public void setCurrency(Currency currency)
{
this.currency = currency;
storage.write("OrderBookFilterSettings.currency", currency);
}
}
class CurrencyComparator implements Comparator<Currency>
{
@Override
public int compare(Currency a, Currency b)
{
return a.getCurrencyCode().compareTo(b.getCurrencyCode());
}
}

View File

@ -1,6 +1,7 @@
package io.bitsquare.settings;
import com.google.inject.Inject;
import io.bitsquare.user.Arbitrator;
import java.io.Serializable;
import java.util.ArrayList;
@ -13,6 +14,7 @@ public class Settings implements Serializable
private List<Locale> acceptedLanguageLocales = new ArrayList<>();
private List<Locale> acceptedCountryLocales = new ArrayList<>();
private List<Arbitrator> arbitrators = new ArrayList<>();
@Inject
public Settings()
@ -24,33 +26,35 @@ public class Settings implements Serializable
if (savedSettings != null)
{
acceptedLanguageLocales = savedSettings.getAcceptedLanguageLocales();
acceptedCountryLocales = savedSettings.getAcceptedCountryLocales();
arbitrators = savedSettings.getArbitrators();
}
}
public void addAcceptedLanguageLocale(Locale locale)
{
acceptedLanguageLocales.add(locale);
if (!acceptedLanguageLocales.contains(locale))
acceptedLanguageLocales.add(locale);
}
public void addAcceptedCountryLocale(Locale locale)
{
acceptedCountryLocales.add(locale);
if (!acceptedCountryLocales.contains(locale))
acceptedCountryLocales.add(locale);
}
//setters
public void setAcceptedLanguageLocales(List<Locale> acceptedLanguageLocales)
public void addArbitrator(Arbitrator arbitrator)
{
this.acceptedLanguageLocales = acceptedLanguageLocales;
}
public void setAcceptedCountryLocales(List<Locale> acceptedCountryLocales)
{
this.acceptedCountryLocales = acceptedCountryLocales;
if (!arbitrators.contains(arbitrator))
arbitrators.add(arbitrator);
}
//getters
public List<Arbitrator> getArbitrators()
{
return arbitrators;
}
public List<Locale> getAcceptedLanguageLocales()
{
return acceptedLanguageLocales;
@ -62,5 +66,8 @@ public class Settings implements Serializable
return acceptedCountryLocales;
}
public Arbitrator getRandomArbitrator()
{
return arbitrators.size() > 0 ? arbitrators.get((int) (Math.random() * arbitrators.size())) : null;
}
}

View File

@ -7,7 +7,6 @@ import java.util.UUID;
public class Contract
{
private User taker;
private User offerer;
private String offererPubKey;
private Trade trade;
private String takerPubKey;
@ -34,17 +33,6 @@ public class Contract
return taker;
}
public User getOfferer()
{
return offerer;
}
public void setOfferer(User offerer)
{
this.offerer = offerer;
}
public String getTakerPubKey()
{
return takerPubKey;

View File

@ -1,6 +1,7 @@
package io.bitsquare.trade;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.user.Arbitrator;
import java.util.Currency;
import java.util.List;
@ -13,8 +14,6 @@ public class Offer
private double price;
private double amount;
private double minAmount;
private String accountID;
private String messageID;
private Direction direction;
@ -24,6 +23,7 @@ public class Offer
private List<Locale> acceptedCountryLocales;
private List<Locale> acceptedLanguageLocales;
private String offerPaymentTxID;
private Arbitrator arbitrator;
public Offer(String accountID,
String messageID,
@ -34,6 +34,7 @@ public class Offer
BankAccountType.BankAccountTypeEnum bankAccountTypeEnum,
Currency currency,
Locale bankAccountCountryLocale,
Arbitrator arbitrator,
List<Locale> acceptedCountryLocales,
List<Locale> acceptedLanguageLocales)
{
@ -46,19 +47,28 @@ public class Offer
this.bankAccountTypeEnum = bankAccountTypeEnum;
this.currency = currency;
this.bankAccountCountryLocale = bankAccountCountryLocale;
this.arbitrator = arbitrator;
this.acceptedCountryLocales = acceptedCountryLocales;
this.acceptedLanguageLocales = acceptedLanguageLocales;
uid = UUID.randomUUID();
}
// setter
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setOfferPaymentTxID(String offerPaymentTxID)
{
this.offerPaymentTxID = offerPaymentTxID;
}
// getters
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public String getAccountID()
{
return accountID;
@ -134,4 +144,8 @@ public class Offer
return offerPaymentTxID;
}
public Arbitrator getArbitrator()
{
return arbitrator;
}
}

View File

@ -1,29 +0,0 @@
package io.bitsquare.trade;
import io.bitsquare.bank.BankAccountType;
import java.util.List;
import java.util.Locale;
public class OfferConstraint
{
private List<Locale> languageLocales;
private List<BankAccountType.BankAccountTypeEnum> bankAccountTypes;
public OfferConstraint(List<Locale> languageLocales,
List<BankAccountType.BankAccountTypeEnum> bankAccountTypes)
{
this.languageLocales = languageLocales;
this.bankAccountTypes = bankAccountTypes;
}
public List<Locale> getLanguageLocales()
{
return languageLocales;
}
public List<BankAccountType.BankAccountTypeEnum> getBankAccountTypes()
{
return bankAccountTypes;
}
}

View File

@ -64,7 +64,7 @@ public class Trade
return requestedAmount;
}
public void setRequestedAmount(double requestedAmount)
public void setTradeAmount(double requestedAmount)
{
this.requestedAmount = requestedAmount;
}

View File

@ -86,7 +86,6 @@ public class Trading
KeyPair address = walletFacade.createNewAddress();
Contract contract = new Contract(trade, address.getPubKey());
//contract.setOfferer(trade.getOffer().getOfferer());
contract.setTaker(user);
contracts.put(trade.getUid().toString(), contract);
return contract;

View File

@ -1,7 +1,6 @@
package io.bitsquare.trade.orderbook;
import com.google.inject.Inject;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.trade.orderbook.OrderBookListItem;
import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.Formatter;
@ -9,11 +8,11 @@ import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.Offer;
import io.bitsquare.user.User;
import io.bitsquare.util.Utils;
import io.bitsquare.util.MockData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.UUID;
public class MockOrderBook extends OrderBook
{
@ -50,69 +49,13 @@ public class MockOrderBook extends OrderBook
price,
amount,
minAmount,
getBankTransferTypeEnums().get(0),
getCurrencies().get(0),
getLocales().get(0),
getLocales(),
getLocales());
MockData.getBankTransferTypeEnums().get(0),
MockData.getCurrencies().get(0),
MockData.getLocales().get(0),
MockData.getArbitrators().get(0),
MockData.getLocales(),
MockData.getLocales());
return offer;
}
private List<Currency> getCurrencies()
{
List<Currency> list = new ArrayList<>();
list.add(Currency.getInstance("EUR"));
list.add(Currency.getInstance("USD"));
list.add(Currency.getInstance("GBP"));
list.add(Currency.getInstance("RUB"));
list.add(Currency.getInstance("CAD"));
list.add(Currency.getInstance("AUD"));
list.add(Currency.getInstance("JPY"));
list.add(Currency.getInstance("CNY"));
list.add(Currency.getInstance("CHF"));
return randomizeList(list);
}
private List<Locale> getLocales()
{
List<Locale> list = new ArrayList<>();
list.add(new Locale("de", "AT"));
list.add(new Locale("de", "DE"));
list.add(new Locale("en", "US"));
list.add(new Locale("en", "UK"));
list.add(new Locale("es", "ES"));
list.add(new Locale("ru", "RU"));
list.add(new Locale("zh", "CN"));
list.add(new Locale("en", "AU"));
list.add(new Locale("it", "IT"));
list.add(new Locale("en", "CA"));
return randomizeList(list);
}
private List<BankAccountType.BankAccountTypeEnum> getBankTransferTypeEnums()
{
return randomizeList(Utils.getAllBankAccountTypeEnums());
}
private List randomizeList(List list)
{
int e = new Random().nextInt(list.size());
if (list.size() > 0)
e = Math.max(e, 1);
int s = (e == 0) ? 0 : new Random().nextInt(e);
list = list.subList(s, e);
return list;
}
private List reduce(List list, int count)
{
List result = new ArrayList();
for (int i = 0; i < count && i < list.size(); i++)
{
result.add(list.get(i));
}
return result;
}
}

View File

@ -0,0 +1,48 @@
package io.bitsquare.user;
import java.io.Serializable;
public class Arbitrator implements Serializable
{
private static final long serialVersionUID = -2625059604136756635L;
private String name;
private String pubKey;
private String messageID;
private String url;
public Arbitrator(String name, String pubKey, String messageID, String url)
{
this.name = name;
this.pubKey = pubKey;
this.messageID = messageID;
this.url = url;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public String getName()
{
return name;
}
public String getPubKey()
{
return pubKey;
}
public String getMessageID()
{
return messageID;
}
public String getUrl()
{
return url;
}
}

View File

@ -1,7 +1,6 @@
package io.bitsquare.user;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.trade.OfferConstraint;
import javafx.beans.property.SimpleBooleanProperty;
import java.io.Serializable;
@ -21,8 +20,6 @@ public class User implements Serializable
private List<BankAccount> bankAccounts = new ArrayList<>();
private BankAccount currentBankAccount = null;
private OfferConstraint offerConstraint;
public User()
{
}
@ -34,8 +31,8 @@ public class User implements Serializable
accountID = savedUser.getAccountID();
messageID = savedUser.getMessageID();
online = savedUser.isOnline();
currentBankAccount = savedUser.getCurrentBankAccount();
bankAccounts = savedUser.getBankAccounts();
currentBankAccount = savedUser.getCurrentBankAccount();
}
}
@ -87,10 +84,6 @@ public class User implements Serializable
this.online = online;
}
public void setOfferConstraint(OfferConstraint offerConstraint)
{
this.offerConstraint = offerConstraint;
}
// getter
public String getMessageID()
@ -119,10 +112,6 @@ public class User implements Serializable
return online;
}
public OfferConstraint getOfferConstraint()
{
return offerConstraint;
}
public SimpleBooleanProperty getChangedProperty()
{

View File

@ -0,0 +1,78 @@
package io.bitsquare.util;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.user.Arbitrator;
import java.util.*;
public class MockData
{
public static List<Currency> getCurrencies()
{
List<Currency> list = new ArrayList<>();
list.add(Currency.getInstance("EUR"));
list.add(Currency.getInstance("USD"));
list.add(Currency.getInstance("GBP"));
list.add(Currency.getInstance("RUB"));
list.add(Currency.getInstance("CAD"));
list.add(Currency.getInstance("AUD"));
list.add(Currency.getInstance("JPY"));
list.add(Currency.getInstance("CNY"));
list.add(Currency.getInstance("CHF"));
return randomizeList(list);
}
public static List<Locale> getLocales()
{
List<Locale> list = new ArrayList<>();
list.add(new Locale("de", "AT"));
list.add(new Locale("de", "DE"));
list.add(new Locale("en", "US"));
list.add(new Locale("en", "UK"));
list.add(new Locale("es", "ES"));
list.add(new Locale("ru", "RU"));
list.add(new Locale("zh", "CN"));
list.add(new Locale("en", "AU"));
list.add(new Locale("it", "IT"));
list.add(new Locale("en", "CA"));
return randomizeList(list);
}
public static List<Arbitrator> getArbitrators()
{
List<Arbitrator> list = new ArrayList<>();
list.add(new Arbitrator("Charly Shen", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Charly_Shen"));
list.add(new Arbitrator("Tom Shang", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Tom_Shang"));
list.add(new Arbitrator("Edward Swow", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Edward_Swow"));
list.add(new Arbitrator("Julian Sangre", UUID.randomUUID().toString(), UUID.randomUUID().toString(), "http://www.arbit.io/Julian_Sangre"));
return randomizeList(list);
}
public static List<BankAccountType.BankAccountTypeEnum> getBankTransferTypeEnums()
{
return randomizeList(Utils.getAllBankAccountTypeEnums());
}
public static List randomizeList(List list)
{
int e = new Random().nextInt(list.size());
if (list.size() > 0)
e = Math.max(e, 1);
int s = (e == 0) ? 0 : new Random().nextInt(e);
list = list.subList(s, e);
return list;
}
public static List reduce(List list, int count)
{
List result = new ArrayList();
for (int i = 0; i < count && i < list.size(); i++)
{
result.add(list.get(i));
}
return result;
}
}

View File

@ -4,11 +4,16 @@ import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.bitsquare.bank.BankAccountType;
import javafx.animation.AnimationTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.io.*;
import java.net.URI;
import java.util.*;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class Utils
@ -37,6 +42,13 @@ public class Utils
printElapsedTime("");
}
public static void openURL(String url) throws Exception
{
Desktop.getDesktop().browse(new URI(url));
}
public static Object copy(Object orig)
{
Object obj = null;
@ -155,5 +167,29 @@ public class Utils
return bankTransferTypes;
}
/**
* @param delay in milliseconds
* @param callback
* @usage Utils.setTimeout(1000, (AnimationTimer animationTimer) -> {
* doSomething();
* return null;
* });
*/
public static void setTimeout(int delay, Function<AnimationTimer, Void> callback)
{
long startTime = System.currentTimeMillis();
AnimationTimer animationTimer = new AnimationTimer()
{
@Override
public void handle(long arg0)
{
if (System.currentTimeMillis() > delay + startTime)
{
callback.apply(this);
this.stop();
}
}
};
animationTimer.start();
}
}