Add payments account screen

This commit is contained in:
Manfred Karrer 2014-09-08 02:06:31 +02:00
parent 9732215c59
commit efc2100b26
49 changed files with 549 additions and 855 deletions

View file

@ -51,7 +51,7 @@ import lighthouse.files.AppDirectory;
public class BitSquare extends Application {
private static final Logger log = LoggerFactory.getLogger(BitSquare.class);
public static boolean fillFormsWithDummyData = true;
public static final boolean fillFormsWithDummyData = true;
private static String APP_NAME = "Bitsquare";
private static Stage primaryStage;

View file

@ -94,12 +94,10 @@ public class SeedNode extends Thread {
///////////////////////////////////////////////////////////////////////////////////////////
public void run() {
Peer peer = startupPeer();
startupPeer();
for (; ; ) {
try {
// ping(peer);
Thread.sleep(300);
} catch (InterruptedException e) {
log.error(e.toString());

View file

@ -39,7 +39,6 @@ public class CachedCodeBehind<T extends PresentationModel> extends CodeBehind<T>
else if (oldValue != null && newValue == null) deactivate();
});
activate();
presentationModel.initialized();
}
@ -71,7 +70,6 @@ public class CachedCodeBehind<T extends PresentationModel> extends CodeBehind<T>
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
super.terminate();
deactivate();
presentationModel.terminate();
}

View file

@ -45,7 +45,9 @@ import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@ -83,8 +85,6 @@ public class MainController extends ViewController {
private Pane ordersButtonButtonHolder;
private boolean messageFacadeInited;
private boolean walletFacadeInited;
private VBox accountComboBoxHolder;
private Pane setupView;
///////////////////////////////////////////////////////////////////////////////////////////
@ -226,7 +226,7 @@ public class MainController extends ViewController {
private void fadeOutSplash() {
Profiler.printMsgWithTime("MainController.fadeOutSplash");
Transitions.blurAndRemove(viewBuilder.splashVBox);
Transitions.blur(viewBuilder.splashVBox, 700, false, true);
Transitions.fadeIn(viewBuilder.menuBar);
Transitions.fadeIn(viewBuilder.contentScreen);
}
@ -298,13 +298,6 @@ public class MainController extends ViewController {
addAccountComboBox(viewBuilder.rightNavPane);
user.getBankAccountsSizeProperty().addListener((observableValue, oldValue, newValue) -> {
if ((int) newValue == 2)
viewBuilder.rightNavPane.getChildren().add(1, accountComboBoxHolder);
else if ((int) newValue < 2)
viewBuilder.rightNavPane.getChildren().remove(accountComboBoxHolder);
});
settingsButton = addNavButton(viewBuilder.rightNavPane, "Settings", NavigationItem.SETTINGS);
accountButton = addNavButton(viewBuilder.rightNavPane, "Account", NavigationItem.ACCOUNT);
@ -350,9 +343,6 @@ public class MainController extends ViewController {
}
private ToggleButton addNavButton(Pane parent, String title, NavigationItem navigationItem) {
// final Pane pane = new Pane();
// pane.setPrefSize(50, 50);
ImageView icon = ImageUtil.getIconImageView(navigationItem.getIcon());
icon.setFitWidth(32);
icon.setFitHeight(32);
@ -382,19 +372,7 @@ public class MainController extends ViewController {
});
toggleButton.setOnAction(e -> loadView(navigationItem));
/* final Label titleLabel = new Label(title);
titleLabel.setLayoutY(35);
titleLabel.setId("nav-button-label");
titleLabel.setMouseTransparent(true);
titleLabel.widthProperty().addListener((observableValue, number, newValue) ->
titleLabel.setLayoutX((50.0 - (double) newValue) / 2 - 1));
*/
// pane.getChildren().addAll(toggleButton);
// pane.getChildren().addAll(toggleButton, titleLabel);
// parent.getChildren().add(pane);
parent.getChildren().add(toggleButton);
return toggleButton;
}
@ -412,26 +390,26 @@ public class MainController extends ViewController {
});
final Label titleLabel = new Label("Balance");
titleLabel.prefWidthProperty().bind(balanceTextField.widthProperty());
titleLabel.setMouseTransparent(true);
titleLabel.setId("nav-button-label");
balanceTextField.widthProperty().addListener((ov, o, n) ->
titleLabel.setLayoutX(((double) n - titleLabel.getWidth()) / 2));
final VBox vBox = new VBox();
vBox.setPadding(new Insets(12, 0, 0, 0));
vBox.setPadding(new Insets(12, 5, 0, 0));
vBox.setSpacing(2);
vBox.getChildren().setAll(balanceTextField, titleLabel);
vBox.setAlignment(Pos.CENTER);
parent.getChildren().add(vBox);
}
private void addAccountComboBox(Pane parent) {
final ComboBox<BankAccount> accountComboBox =
new ComboBox<>(FXCollections.observableArrayList(user.getBankAccounts()));
accountComboBox.setId("nav-account-combo-box");
accountComboBox.setLayoutY(12);
if (user.getCurrentBankAccount() != null)
accountComboBox.getSelectionModel().select(user.getCurrentBankAccount());
accountComboBox.valueProperty().addListener((ov, oldValue, newValue) -> user.setCurrentBankAccount(newValue));
accountComboBox.setConverter(new StringConverter<BankAccount>() {
final ObservableList<BankAccount> accounts = user.getBankAccounts();
final ComboBox<BankAccount> comboBox =
new ComboBox<>(FXCollections.observableArrayList(accounts));
comboBox.setLayoutY(12);
comboBox.setVisibleRowCount(5);
comboBox.setConverter(new StringConverter<BankAccount>() {
@Override
public String toString(BankAccount bankAccount) {
return bankAccount.getAccountTitle();
@ -443,26 +421,32 @@ public class MainController extends ViewController {
}
});
user.getSelectedBankAccountIndexProperty().addListener(observable ->
accountComboBox.getSelectionModel().select(user.getCurrentBankAccount()));
user.getBankAccountsSizeProperty().addListener(observable -> {
accountComboBox.setItems(FXCollections.observableArrayList(user.getBankAccounts()));
// need to delay it a bit otherwise it will not be set
Platform.runLater(() -> accountComboBox.getSelectionModel().select(user.getCurrentBankAccount()));
comboBox.setItems(accounts);
comboBox.valueProperty().addListener((ov, oldValue, newValue) -> user.setCurrentBankAccount(newValue));
accounts.addListener((Observable observable) -> {
comboBox.setPromptText((accounts.size() == 0) ? "No accounts" : "");
comboBox.setDisable((accounts.isEmpty()));
});
comboBox.setPromptText((accounts.isEmpty()) ? "No accounts" : "");
comboBox.setDisable((accounts.isEmpty()));
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null)
comboBox.getSelectionModel().select(newValue);
});
comboBox.getSelectionModel().select(user.getCurrentBankAccount());
final Label titleLabel = new Label("Bank account");
titleLabel.prefWidthProperty().bind(accountComboBox.widthProperty());
titleLabel.setMouseTransparent(true);
titleLabel.setId("nav-button-label");
comboBox.widthProperty().addListener((ov, o, n) ->
titleLabel.setLayoutX(((double) n - titleLabel.getWidth()) / 2));
accountComboBoxHolder = new VBox();
accountComboBoxHolder.setPadding(new Insets(12, 0, 0, 0));
accountComboBoxHolder.setSpacing(2);
accountComboBoxHolder.getChildren().setAll(accountComboBox, titleLabel);
if (user.getBankAccounts().size() > 1)
parent.getChildren().add(accountComboBoxHolder);
VBox vBox = new VBox();
vBox.setPadding(new Insets(12, 8, 0, 5));
vBox.setSpacing(2);
vBox.setAlignment(Pos.CENTER);
vBox.getChildren().setAll(comboBox, titleLabel);
parent.getChildren().add(vBox);
}
}
@ -510,13 +494,13 @@ class ViewBuilder {
anchorPane.setId("content-pane");
leftNavPane = new HBox();
leftNavPane.setAlignment(Pos.CENTER);
// leftNavPane.setAlignment(Pos.CENTER);
leftNavPane.setSpacing(10);
AnchorPane.setLeftAnchor(leftNavPane, 10d);
AnchorPane.setTopAnchor(leftNavPane, 0d);
rightNavPane = new HBox();
rightNavPane.setAlignment(Pos.CENTER);
// rightNavPane.setAlignment(Pos.CENTER);
rightNavPane.setSpacing(10);
AnchorPane.setRightAnchor(rightNavPane, 10d);
AnchorPane.setTopAnchor(rightNavPane, 0d);

View file

@ -32,7 +32,6 @@ import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.layout.*;
@ -46,7 +45,6 @@ public class AccountCB extends CachedCodeBehind<SetupPM> {
public Label headLineLabel;
public Label titleLabel;
public Tab setupTab;
private Pane setupView;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@ -66,6 +64,7 @@ public class AccountCB extends CachedCodeBehind<SetupPM> {
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
loadViewAndGetChildController(NavigationItem.SETUP);
}
@Override
@ -83,7 +82,7 @@ public class AccountCB extends CachedCodeBehind<SetupPM> {
super.terminate();
}
public void onRegister(ActionEvent actionEvent) {
public void onRegister() {
loadViewAndGetChildController(NavigationItem.SETUP);
}
@ -98,7 +97,7 @@ public class AccountCB extends CachedCodeBehind<SetupPM> {
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
try {
setupView = loader.load();
Pane setupView = loader.load();
setupTab.setContent(setupView);
childController = loader.getController();
@ -111,7 +110,7 @@ public class AccountCB extends CachedCodeBehind<SetupPM> {
log.error(e.getStackTrace().toString());
}
return null;
return (CodeBehind) childController;
}
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -21,6 +21,7 @@ import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.CachedCodeBehind;
import io.bitsquare.gui.account.setup.SetupCB;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.help.Help;
import io.bitsquare.gui.help.HelpId;
@ -47,14 +48,16 @@ import org.controlsfx.dialog.Dialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static javafx.beans.binding.Bindings.createBooleanBinding;
public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
private static final Logger log = LoggerFactory.getLogger(FiatAccountCB.class);
@FXML private ComboBox<Region> regionComboBox;
@FXML private ComboBox<Country> countryComboBox;
@FXML private TextField titleTextField, holderNameTextField, primaryIDTextField, secondaryIDTextField;
@FXML private Button saveButton, addBankAccountButton, changeBankAccountButton, removeBankAccountButton;
@FXML private InputTextField titleTextField, holderNameTextField, primaryIDTextField, secondaryIDTextField;
@FXML private Button saveButton, doneButton, removeBankAccountButton;
@FXML private ComboBox<BankAccount> selectionComboBox;
@FXML private ComboBox<BankAccountType> typesComboBox;
@FXML private ComboBox<Currency> currencyComboBox;
@ -86,6 +89,11 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
regionComboBox.setItems(presentationModel.getAllRegions());
regionComboBox.setConverter(presentationModel.getRegionConverter());
countryComboBox.setConverter(presentationModel.getCountryConverter());
titleTextField.setValidator(presentationModel.getValidator());
holderNameTextField.setValidator(presentationModel.getValidator());
primaryIDTextField.setValidator(presentationModel.getValidator());
secondaryIDTextField.setValidator(presentationModel.getValidator());
}
@Override
@ -115,7 +123,8 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
@FXML
public void onSelectAccount() {
presentationModel.setCurrentBankAccount(selectionComboBox.getSelectionModel().getSelectedItem());
if (selectionComboBox.getSelectionModel().getSelectedItem() != null)
presentationModel.selectBankAccount(selectionComboBox.getSelectionModel().getSelectedItem());
}
@FXML
@ -143,30 +152,35 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
@FXML
private void onSave() {
InputValidator.ValidationResult result = presentationModel.saveBankAccount();
if (result.isValid)
((SetupCB) parentController).onCompleted(this);
if (result.isValid) {
selectionComboBox.getSelectionModel().select(null);
Popups.openInfo("You can add more accounts or continue to the next step.",
"Your payments account has been saved.");
}
}
@FXML
private void onAddAccount() {
log.error("onAddAccount");
private void onDone() {
if (parentController != null)
((SetupCB) parentController).onCompleted(this);
}
@FXML
private void onRemoveAccount() {
presentationModel.removeBankAccount();
selectionComboBox.getSelectionModel().select(null);
}
@FXML
private void onChangeAccount() {
log.error("onChangeAccount");
}
@FXML
private void onOpenHelp() {
private void onOpenSetupHelp() {
Help.openWindow(HelpId.SETUP_FIAT_ACCOUNT);
}
@FXML
private void onOpenManageAccountsHelp() {
Help.openWindow(HelpId.MANAGE_FIAT_ACCOUNT);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
@ -187,13 +201,6 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
currencyComboBox.getSelectionModel().clearSelection();
});
presentationModel.getCurrentBankAccount().addListener((ov, oldValue, newValue) -> {
if (newValue != null)
selectionComboBox.getSelectionModel().select(selectionComboBox.getItems().indexOf(newValue));
else
selectionComboBox.getSelectionModel().clearSelection();
});
presentationModel.country.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
regionComboBox.getSelectionModel().select(regionComboBox.getItems().indexOf(newValue.getRegion()));
@ -205,26 +212,15 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
}
});
presentationModel.getAllBankAccounts().addListener((ListChangeListener<BankAccount>) change -> {
Object a = presentationModel.getAllBankAccounts();
Object a2 = change.getList();
if (presentationModel.getCurrentBankAccount() != null)
selectionComboBox.getSelectionModel().select(selectionComboBox.getItems()
.indexOf(presentationModel.getCurrentBankAccount()));
else
selectionComboBox.getSelectionModel().clearSelection();
});
presentationModel.countryNotInAcceptedCountriesList.addListener((ov, oldValue, newValue) -> {
presentationModel.getCountryNotInAcceptedCountriesList().addListener((ov, oldValue, newValue) -> {
if (newValue) {
List<Action> actions = new ArrayList<>();
actions.add(Dialog.Actions.YES);
actions.add(Dialog.Actions.NO);
Action response = Popups.openConfirmPopup("Warning",
"The country of your bank account is not included in the accepted countries in the general " +
"settings.\n\nDo you want to add it automatically?",
"The country of your bank account is not included in the accepted countries in the " +
"general settings.\n\nDo you want to add it automatically?",
null,
actions);
@ -232,6 +228,9 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
presentationModel.addCountryToAcceptedCountriesList();
}
});
presentationModel.getAllBankAccounts().addListener((ListChangeListener<BankAccount>) change ->
doneButton.setDisable(change.getList().isEmpty()));
}
private void setupBindings() {
@ -247,9 +246,10 @@ public class FiatAccountCB extends CachedCodeBehind<FiatAccountPm> {
selectionComboBox.disableProperty().bind(presentationModel.selectionDisable);
saveButton.disableProperty().bind(presentationModel.saveButtonDisable);
addBankAccountButton.disableProperty().bind(presentationModel.addBankAccountButtonDisable);
changeBankAccountButton.disableProperty().bind(presentationModel.changeBankAccountButtonDisable);
removeBankAccountButton.disableProperty().bind(presentationModel.removeBankAccountButtonDisable);
removeBankAccountButton.disableProperty().bind(createBooleanBinding(() ->
(selectionComboBox.getSelectionModel().selectedIndexProperty().get() == -1),
selectionComboBox.getSelectionModel().selectedIndexProperty()));
}
}

View file

@ -47,26 +47,26 @@ import org.slf4j.LoggerFactory;
public class FiatAccountModel extends UIModel {
private static final Logger log = LoggerFactory.getLogger(FiatAccountModel.class);
private User user;
private Settings settings;
private Persistence persistence;
private final User user;
private final Settings settings;
private final Persistence persistence;
StringProperty title = new SimpleStringProperty();
StringProperty holderName = new SimpleStringProperty();
StringProperty primaryID = new SimpleStringProperty();
StringProperty secondaryID = new SimpleStringProperty();
StringProperty primaryIDPrompt = new SimpleStringProperty();
StringProperty secondaryIDPrompt = new SimpleStringProperty();
BooleanProperty countryNotInAcceptedCountriesList = new SimpleBooleanProperty();
ObjectProperty<BankAccountType> type = new SimpleObjectProperty<>();
ObjectProperty<Country> country = new SimpleObjectProperty<>();
ObjectProperty<Currency> currency = new SimpleObjectProperty<>();
ObjectProperty<BankAccount> currentBankAccount = new SimpleObjectProperty<>();
ObservableList<BankAccountType> allTypes = FXCollections.observableArrayList(BankAccountType
final StringProperty title = new SimpleStringProperty();
final StringProperty holderName = new SimpleStringProperty();
final StringProperty primaryID = new SimpleStringProperty();
final StringProperty secondaryID = new SimpleStringProperty();
final StringProperty primaryIDPrompt = new SimpleStringProperty();
final StringProperty secondaryIDPrompt = new SimpleStringProperty();
final BooleanProperty countryNotInAcceptedCountriesList = new SimpleBooleanProperty();
final ObjectProperty<BankAccountType> type = new SimpleObjectProperty<>();
final ObjectProperty<Country> country = new SimpleObjectProperty<>();
final ObjectProperty<Currency> currency = new SimpleObjectProperty<>();
final ObjectProperty<BankAccount> currentBankAccount = new SimpleObjectProperty<>();
final ObservableList<BankAccountType> allTypes = FXCollections.observableArrayList(BankAccountType
.getAllBankAccountTypes());
ObservableList<BankAccount> allBankAccounts = FXCollections.observableArrayList();
ObservableList<Currency> allCurrencies = FXCollections.observableArrayList(CurrencyUtil.getAllCurrencies());
ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions());
final ObservableList<BankAccount> allBankAccounts = FXCollections.observableArrayList();
final ObservableList<Currency> allCurrencies = FXCollections.observableArrayList(CurrencyUtil.getAllCurrencies());
final ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions());
///////////////////////////////////////////////////////////////////////////////////////////
@ -121,16 +121,18 @@ public class FiatAccountModel extends UIModel {
holderName.get(),
primaryID.get(),
secondaryID.get());
user.addBankAccount(bankAccount);
user.setBankAccount(bankAccount);
saveUser();
allBankAccounts.setAll(user.getBankAccounts());
countryNotInAcceptedCountriesList.set(!settings.getAcceptedCountries().contains(country.get()));
reset();
}
void removeBankAccount() {
user.removeCurrentBankAccount();
saveUser();
allBankAccounts.setAll(user.getBankAccounts());
reset();
}
// We ask the user if he likes to add his own bank account country to the accepted country list if he has not
@ -138,23 +140,10 @@ public class FiatAccountModel extends UIModel {
void addCountryToAcceptedCountriesList() {
settings.addAcceptedCountry(country.get());
saveSettings();
countryNotInAcceptedCountriesList.set(false);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion));
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setCurrentBankAccount(BankAccount bankAccount) {
void selectBankAccount(BankAccount bankAccount) {
currentBankAccount.set(bankAccount);
user.setCurrentBankAccount(bankAccount);
@ -173,19 +162,24 @@ public class FiatAccountModel extends UIModel {
currency.set(bankAccount.getCurrency());
}
else {
title.set(null);
holderName.set(null);
primaryID.set(null);
secondaryID.set(null);
primaryIDPrompt.set(null);
secondaryIDPrompt.set(null);
type.set(null);
country.set(null);
currency.set(null);
reset();
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion));
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setType(BankAccountType type) {
this.type.set(type);
@ -212,6 +206,19 @@ public class FiatAccountModel extends UIModel {
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void reset() {
title.set(null);
holderName.set(null);
primaryID.set(null);
secondaryID.set(null);
primaryIDPrompt.set(null);
secondaryIDPrompt.set(null);
type.set(null);
country.set(null);
currency.set(null);
}
private void saveUser() {
persistence.write(user);
}

View file

@ -20,7 +20,7 @@ package io.bitsquare.gui.account.fiataccount;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.util.validation.BankAccountValidator;
import io.bitsquare.gui.util.validation.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources;
import io.bitsquare.locale.Country;
@ -46,25 +46,21 @@ import org.slf4j.LoggerFactory;
public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
private static final Logger log = LoggerFactory.getLogger(FiatAccountPm.class);
private BankAccountValidator bankAccountValidator = new BankAccountValidator();
private final BankAccountNumberValidator validator = new BankAccountNumberValidator();
StringProperty title = new SimpleStringProperty();
StringProperty holderName = new SimpleStringProperty();
StringProperty primaryID = new SimpleStringProperty();
StringProperty secondaryID = new SimpleStringProperty();
StringProperty primaryIDPrompt = new SimpleStringProperty();
StringProperty secondaryIDPrompt = new SimpleStringProperty();
StringProperty selectionPrompt = new SimpleStringProperty();
BooleanProperty selectionDisable = new SimpleBooleanProperty();
BooleanProperty saveButtonDisable = new SimpleBooleanProperty(true);
BooleanProperty addBankAccountButtonDisable = new SimpleBooleanProperty(true);
BooleanProperty changeBankAccountButtonDisable = new SimpleBooleanProperty(true);
BooleanProperty removeBankAccountButtonDisable = new SimpleBooleanProperty(true);
final StringProperty title = new SimpleStringProperty();
final StringProperty holderName = new SimpleStringProperty();
final StringProperty primaryID = new SimpleStringProperty();
final StringProperty secondaryID = new SimpleStringProperty();
final StringProperty primaryIDPrompt = new SimpleStringProperty();
final StringProperty secondaryIDPrompt = new SimpleStringProperty();
final StringProperty selectionPrompt = new SimpleStringProperty();
final BooleanProperty selectionDisable = new SimpleBooleanProperty();
final BooleanProperty saveButtonDisable = new SimpleBooleanProperty(true);
BooleanProperty countryNotInAcceptedCountriesList = new SimpleBooleanProperty();
ObjectProperty<BankAccountType> type = new SimpleObjectProperty<>();
ObjectProperty<Country> country = new SimpleObjectProperty<>();
ObjectProperty<Currency> currency = new SimpleObjectProperty<>();
final ObjectProperty<BankAccountType> type = new SimpleObjectProperty<>();
final ObjectProperty<Country> country = new SimpleObjectProperty<>();
final ObjectProperty<Currency> currency = new SimpleObjectProperty<>();
///////////////////////////////////////////////////////////////////////////////////////////
@ -96,20 +92,11 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
primaryIDPrompt.bind(model.primaryIDPrompt);
secondaryIDPrompt.bind(model.secondaryIDPrompt);
countryNotInAcceptedCountriesList.bind(model.countryNotInAcceptedCountriesList);
selectionPrompt.set("No bank account available");
selectionDisable.set(true);
model.title.addListener((ov, oldValue, newValue) -> {
validateInput();
/*
InputValidator.ValidationResult result = validateInput();
if (result.isValid) {
result = bankAccountValidator.validate(newValue);
saveButtonDisable.set(!result.isValid);
}*/
});
model.title.addListener((ov, oldValue, newValue) -> validateInput());
holderName.addListener((ov, oldValue, newValue) -> validateInput());
primaryID.addListener((ov, oldValue, newValue) -> validateInput());
secondaryID.addListener((ov, oldValue, newValue) -> validateInput());
@ -119,7 +106,6 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
public void activate() {
super.activate();
model.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> {
if (model.allBankAccounts.isEmpty()) {
selectionPrompt.set("No bank account available");
@ -151,10 +137,6 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
InputValidator.ValidationResult result = validateInput();
if (result.isValid) {
model.saveBankAccount();
addBankAccountButtonDisable.set(false);
changeBankAccountButtonDisable.set(false);
removeBankAccountButtonDisable.set(false);
}
return result;
}
@ -163,18 +145,14 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
model.removeBankAccount();
}
void updateDoneButtonDisabled() {
/* boolean isValid = model.languageList != null && model.languageList.size() > 0 &&
model.countryList != null && model.countryList.size() > 0 &&
model.arbitratorList != null && model.arbitratorList.size() > -1;
doneButtonDisabled.set(!isValid);*/
}
void addCountryToAcceptedCountriesList() {
model.addCountryToAcceptedCountriesList();
}
void selectBankAccount(BankAccount bankAccount) {
model.selectBankAccount(bankAccount);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Converters
@ -281,16 +259,15 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
return model.getAllCountriesFor(selectedRegion);
}
BooleanProperty getCountryNotInAcceptedCountriesList() {
return model.countryNotInAcceptedCountriesList;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
void setCurrentBankAccount(BankAccount bankAccount) {
model.setCurrentBankAccount(bankAccount);
validateInput();
}
void setType(BankAccountType type) {
model.setType(type);
validateInput();
@ -312,13 +289,13 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = bankAccountValidator.validate(model.title.get());
InputValidator.ValidationResult result = validator.validate(model.title.get());
if (result.isValid) {
result = bankAccountValidator.validate(model.holderName.get());
result = validator.validate(model.holderName.get());
if (result.isValid) {
result = bankAccountValidator.validate(model.primaryID.get());
result = validator.validate(model.primaryID.get());
if (result.isValid) {
result = bankAccountValidator.validate(model.secondaryID.get());
result = validator.validate(model.secondaryID.get());
if (result.isValid) {
if (model.currency.get() == null)
result = new InputValidator.ValidationResult(false,
@ -342,4 +319,10 @@ public class FiatAccountPm extends PresentationModel<FiatAccountModel> {
return result;
}
public InputValidator getValidator() {
return validator;
}
}

View file

@ -19,6 +19,7 @@
<?import io.bitsquare.gui.components.InfoDisplay?>
<?import io.bitsquare.gui.components.InputTextField?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
@ -57,16 +58,16 @@
</ComboBox>
<Label text="Title:" GridPane.rowIndex="1"/>
<TextField fx:id="titleTextField" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<InputTextField fx:id="titleTextField" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Label text="Holder name:" GridPane.rowIndex="2"/>
<TextField fx:id="holderNameTextField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<InputTextField fx:id="holderNameTextField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Label text="Primary ID:" GridPane.rowIndex="3"/>
<TextField fx:id="primaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<InputTextField fx:id="primaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
<Label text="Secondary ID:" GridPane.rowIndex="4"/>
<TextField fx:id="secondaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<InputTextField fx:id="secondaryIDTextField" GridPane.columnIndex="1" GridPane.rowIndex="4"/>
<Label text="Currency:" GridPane.rowIndex="5"/>
<ComboBox fx:id="currencyComboBox" promptText="Select currency"
@ -83,16 +84,16 @@
</children>
</HBox>
<InfoDisplay gridPane="$root" onAction="#onOpenHelp" rowIndex="7"
<InfoDisplay gridPane="$root" onAction="#onOpenSetupHelp" rowIndex="7"
text="The payments account data will be saved in a encrypted form to the Bitcoin block chain and will be used in the trade process for account verification."/>
<Button fx:id="saveButton" text="Save bank account" onAction="#onSave" GridPane.columnIndex="1"
GridPane.rowIndex="8" defaultButton="true" disable="true">
<HBox GridPane.columnIndex="1" GridPane.rowIndex="8" spacing="10">
<Button fx:id="saveButton" text="Save" onAction="#onSave" defaultButton="true" disable="true"/>
<Button fx:id="doneButton" text="Continue to the next step" onAction="#onDone" disable="true"/>
<GridPane.margin>
<Insets top="15.0" bottom="5.0"/>
</GridPane.margin>
</Button>
</HBox>
<!--
Manage
@ -113,31 +114,24 @@
</padding>
</Pane>
<Label text="Add new account:" GridPane.rowIndex="9">
<Label text="Select payments account:" GridPane.rowIndex="9">
<GridPane.margin>
<Insets top="40"/>
</GridPane.margin>
</Label>
<Button fx:id="addBankAccountButton" text="Add payments account" onAction="#onAddAccount"
GridPane.columnIndex="1" GridPane.rowIndex="9" disable="true">
<ComboBox fx:id="selectionComboBox" onAction="#onSelectAccount" GridPane.rowIndex="9"
GridPane.columnIndex="1">
<GridPane.margin>
<Insets top="40"/>
</GridPane.margin>
</Button>
</ComboBox>
<Label text="Select payments account:" GridPane.rowIndex="10"/>
<ComboBox fx:id="selectionComboBox" onAction="#onSelectAccount" GridPane.rowIndex="10"
GridPane.columnIndex="1"/>
<Label text="Change selected account:" GridPane.rowIndex="11"/>
<Button fx:id="changeBankAccountButton" text="Change selected payments account" onAction="#onChangeAccount"
GridPane.columnIndex="1"
GridPane.rowIndex="11" disable="true"/>
<Label text="Remove selected account:" GridPane.rowIndex="12"/>
<Label text="Remove selected account:" GridPane.rowIndex="10"/>
<Button fx:id="removeBankAccountButton" text="Remove selected payments account" onAction="#onRemoveAccount"
GridPane.columnIndex="1"
GridPane.rowIndex="12" disable="true"/>
GridPane.columnIndex="1" GridPane.rowIndex="10" disable="true"/>
<InfoDisplay gridPane="$root" onAction="#onOpenManageAccountsHelp" rowIndex="11"
text="When you change your payments accounts later you need to do the renew the registration and pay the small registration fee."/>
</children>
@ -159,6 +153,5 @@
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
</rowConstraints>
</GridPane>

View file

@ -17,13 +17,14 @@
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.account.registration.RegistrationCB" hgap="5.0" vgap="5.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
xmlns:fx="http://javafx.com/fxml">
<children>
<Label text="REG"/>
</children>

View file

@ -57,8 +57,8 @@ public class RestrictionsModel extends UIModel {
ObservableList<Country> countryList = FXCollections.observableArrayList();
ObservableList<Arbitrator> arbitratorList = FXCollections.observableArrayList();
ObservableList<Locale> allLanguages = FXCollections.observableArrayList(LanguageUtil.getAllLanguageLocales());
ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions());
final ObservableList<Locale> allLanguages = FXCollections.observableArrayList(LanguageUtil.getAllLanguageLocales());
final ObservableList<Region> allRegions = FXCollections.observableArrayList(CountryUtil.getAllRegions());
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -157,8 +157,8 @@ class WizardItem extends HBox {
private final ImageView imageView;
private final Label titleLabel;
private final Label subTitleLabel;
private SetupCB parentCB;
private Parent content;
private final SetupCB parentCB;
private final Parent content;
private CodeBehind<? extends PresentationModel> childController;

View file

@ -61,7 +61,6 @@ public class ArbitratorBrowserController extends CachedViewController implements
private final Settings settings;
private final Persistence persistence;
private final MessageFacade messageFacade;
private final List<Arbitrator> allArbitrators = new ArrayList<>();
private Arbitrator currentArbitrator;
private ArbitratorProfileController arbitratorProfileController;
@ -79,7 +78,6 @@ public class ArbitratorBrowserController extends CachedViewController implements
this.settings = settings;
this.persistence = persistence;
this.messageFacade = messageFacade;
messageFacade.addArbitratorListener(this);
messageFacade.getArbitrators(LanguageUtil.getDefaultLanguageLocale());

View file

@ -73,7 +73,7 @@ public class ArbitratorRegistrationController extends CachedViewController {
private final Persistence persistence;
private final WalletFacade walletFacade;
private final MessageFacade messageFacade;
private User user;
private final User user;
private Arbitrator arbitrator = new Arbitrator();
private ArbitratorProfileController arbitratorProfileController;
private boolean isEditMode;

View file

@ -186,10 +186,6 @@ tab pane upper bg gradient color mid dark grey to bright grey: cfcfcf -> dddddd
-fx-alignment: center;
}
#nav-account-combo-box .list-cell {
-fx-alignment: center;
}
.text-field:readonly {
-fx-text-fill: #000000;
-fx-background-color: #FAFAFA;

View file

@ -39,12 +39,12 @@ import org.slf4j.LoggerFactory;
public class ConfidenceDisplay {
private static final Logger log = LoggerFactory.getLogger(ConfidenceDisplay.class);
private WalletEventListener walletEventListener;
private Wallet wallet;
private Label confirmationLabel;
private final WalletEventListener walletEventListener;
private final Wallet wallet;
private final Label confirmationLabel;
private TextField balanceTextField;
private Transaction transaction;
private ConfidenceProgressIndicator progressIndicator;
private final ConfidenceProgressIndicator progressIndicator;
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, TextField balanceTextField,
ConfidenceProgressIndicator progressIndicator) {

View file

@ -36,7 +36,9 @@ import org.slf4j.LoggerFactory;
/**
* TextField with validation support.
* In case the isValid property in amountValidationResultProperty get set to false we display a red border and an error
* If validator is set it supports on focus out validation with that validator. If a more sophisticated validation is
* needed the validationResultProperty can be used for applying validation result done by external validation.
* In case the isValid property in validationResultProperty get set to false we display a red border and an error
* message within the errorMessageDisplay placed on the right of the text field.
* The errorMessageDisplay gets closed when the ValidatingTextField instance gets removed from the scene graph or when
* hideErrorMessageDisplay() is called.
@ -50,13 +52,21 @@ public class InputTextField extends TextField {
private final Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
private final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>
(new
InputValidator.ValidationResult(true));
private final ObjectProperty<InputValidator.ValidationResult> validationResult = new SimpleObjectProperty<>
(new InputValidator.ValidationResult(true));
private static PopOver errorMessageDisplay;
private Region layoutReference = this;
public InputValidator getValidator() {
return validator;
}
public void setValidator(InputValidator validator) {
this.validator = validator;
}
private InputValidator validator;
///////////////////////////////////////////////////////////////////////////////////////////
// Static
@ -73,7 +83,7 @@ public class InputTextField extends TextField {
public InputTextField() {
super();
amountValidationResult.addListener((ov, oldValue, newValue) -> {
validationResult.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
setEffect(newValue.isValid ? null : invalidEffect);
@ -90,6 +100,10 @@ public class InputTextField extends TextField {
hideErrorMessageDisplay();
});
focusedProperty().addListener((o, oldValue, newValue) -> {
if (oldValue && !newValue && validator != null)
validationResult.set(validator.validate(getText()));
});
}
@ -115,8 +129,8 @@ public class InputTextField extends TextField {
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public ObjectProperty<InputValidator.ValidationResult> amountValidationResultProperty() {
return amountValidationResult;
public ObjectProperty<InputValidator.ValidationResult> validationResultProperty() {
return validationResult;
}

View file

@ -18,6 +18,8 @@
package io.bitsquare.gui.components;
import io.bitsquare.BitSquare;
import io.bitsquare.gui.MainController;
import io.bitsquare.locale.BSResources;
import com.google.bitcoin.store.BlockStoreException;
@ -27,7 +29,9 @@ import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogStyle;
@ -43,20 +47,31 @@ public class Popups {
private static final Logger log = LoggerFactory.getLogger(Popups.class);
// Information
public static void openInformationPopup(String title, String message) {
openInformationPopup(title, message, null, null);
public static void openInfo(String message) {
openInfo(message, null, null);
}
public static void openInformationPopup(String title, String message, String masthead) {
// Supports blurring the content background
public static void openInfo(String message, String masthead) {
MainController.GET_INSTANCE().blurContentScreen();
List<Action> actions = new ArrayList<>();
actions.add(Dialog.Actions.CLOSE);
openInformationPopup(title, message, masthead, actions);
// Dialogs are a bit limited. There is no callback for the InformationDialog button click, so we added
// our own actions.
actions.add(new AbstractAction(BSResources.get("shared.close")) {
@Override
public void handle(ActionEvent actionEvent) {
Dialog.Actions.CLOSE.handle(actionEvent);
MainController.GET_INSTANCE().removeContentScreenBlur();
}
});
openInfo(message, masthead, actions);
}
public static void openInformationPopup(String title, String message, String masthead, List<Action> actions) {
public static void openInfo(String message, String masthead, List<Action> actions) {
Dialogs.create()
.owner(BitSquare.getPrimaryStage())
.title(title)
.message(message)
.masthead(masthead)
.actions(actions)

View file

@ -27,8 +27,6 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.*;
import javafx.scene.effect.*;
import javafx.scene.paint.*;
@ -136,30 +134,24 @@ public class ValidatedTextField extends TextField {
private void bind() {
this.invalid.bind(maskCheck().or(minLengthCheck()));
this.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> ov, String t, String t1) {
if (textProperty().get() != null && textProperty().get().length() > maxLength.get()) {
setText(t);
}
this.textProperty().addListener((ov, t, t1) -> {
if (textProperty().get() != null && textProperty().get().length() > maxLength.get()) {
setText(t);
}
});
this.invalid.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if (t ^ t1) {
if (t1) {
// setStyle("-fx-font-weight: bold; -fx-text-fill: red;");
setEffect(invalidEffect);
}
else {
// setStyle("-fx-font-weight: normal; -fx-text-fill: inherit;");
setEffect(null);
}
this.invalid.addListener((ov, t, t1) -> {
if (t ^ t1) {
if (t1) {
// setStyle("-fx-font-weight: bold; -fx-text-fill: red;");
setEffect(invalidEffect);
}
else {
// setStyle("-fx-font-weight: normal; -fx-text-fill: inherit;");
setEffect(null);
}
}
});
}

View file

@ -73,8 +73,7 @@ public class AddressTextField extends AnchorPane {
addressLabel.textProperty().bind(address);
addressLabel.setOnMouseClicked(mouseEvent -> {
try {
if (address != null)
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
} catch (IOException e) {
log.warn(e.getMessage());
Popups.openWarningPopup("Information", "Opening a system Bitcoin wallet application has failed. " +

View file

@ -127,7 +127,7 @@ public class BalanceTextField extends AnchorPane {
}
private void updateBalance(Coin balance) {
balanceTextField.setText(BSFormatter.formatCoin(balance));
balanceTextField.setText(BSFormatter.formatCoinWithCode(balance));
if (balance.isPositive())
balanceTextField.setEffect(fundedEffect);
else

View file

@ -27,6 +27,8 @@ public enum HelpId {
SETUP_RESTRICTION_COUNTRIES,
SETUP_RESTRICTION_ARBITRATORS,
SETUP_REGISTRATION,
SETUP_FIAT_ACCOUNT
SETUP_FIAT_ACCOUNT,
MANAGE_FIAT_ACCOUNT
}

View file

@ -73,13 +73,13 @@ import org.slf4j.LoggerFactory;
public class PendingTradeController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(PendingTradeController.class);
private TradeManager tradeManager;
private WalletFacade walletFacade;
private final TradeManager tradeManager;
private final WalletFacade walletFacade;
private Trade currentTrade;
private Image buyIcon = ImageUtil.getIconImage(ImageUtil.BUY);
private Image sellIcon = ImageUtil.getIconImage(ImageUtil.SELL);
private final Image buyIcon = ImageUtil.getIconImage(ImageUtil.BUY);
private final Image sellIcon = ImageUtil.getIconImage(ImageUtil.SELL);
private ConfidenceDisplay confidenceDisplay;
@FXML private TableView openTradesTable;

View file

@ -697,7 +697,7 @@ public class SettingsController extends CachedViewController {
bankAccountHolderNameTextField.getText(),
bankAccountPrimaryIDTextField.getText(),
bankAccountSecondaryIDTextField.getText());
user.addBankAccount(bankAccount);
user.setBankAccount(bankAccount);
saveUser();

View file

@ -323,8 +323,8 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
}
});
Popups.openInformationPopup(BSResources.get("createOffer.success.title"),
BSResources.get("createOffer.success.info", presentationModel.transactionId.get()),
Popups.openInfo(BSResources.get("createOffer.success.info",
presentationModel.transactionId.get()),
BSResources.get("createOffer.success.headline"),
actions);
}
@ -366,10 +366,10 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
acceptedArbitratorsTextField.textProperty().bind(presentationModel.acceptedArbitrators);
// Validation
amountTextField.amountValidationResultProperty().bind(presentationModel.amountValidationResult);
minAmountTextField.amountValidationResultProperty().bind(presentationModel.minAmountValidationResult);
priceTextField.amountValidationResultProperty().bind(presentationModel.priceValidationResult);
volumeTextField.amountValidationResultProperty().bind(presentationModel.volumeValidationResult);
amountTextField.validationResultProperty().bind(presentationModel.amountValidationResult);
minAmountTextField.validationResultProperty().bind(presentationModel.minAmountValidationResult);
priceTextField.validationResultProperty().bind(presentationModel.priceValidationResult);
volumeTextField.validationResultProperty().bind(presentationModel.volumeValidationResult);
// buttons
placeOfferButton.visibleProperty().bind(presentationModel.isPlaceOfferButtonVisible);

View file

@ -18,7 +18,6 @@
package io.bitsquare.gui.trade.orderbook;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.CachedViewController;
import io.bitsquare.gui.CodeBehind;
@ -55,7 +54,7 @@ import java.net.URL;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
@ -65,6 +64,7 @@ import javax.inject.Inject;
import javafx.animation.AnimationTimer;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.transformation.SortedList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
@ -73,9 +73,11 @@ import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.util.Callback;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.Dialogs;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -201,7 +203,7 @@ public class OrderBookController extends CachedViewController {
orderBookFilter.getDirectionChangedProperty().addListener((observable) -> applyOffers());
user.getSelectedBankAccountIndexProperty().addListener((observable) -> orderBook.loadOffers());
user.currentBankAccountProperty().addListener((ov) -> orderBook.loadOffers());
createOfferButton.setOnAction(e -> createOffer());
@ -246,7 +248,7 @@ public class OrderBookController extends CachedViewController {
((CreateOfferCB) nextController).setOrderBookFilter(orderBookFilter);
}
else {
showRegistrationDialog();
openSetupScreen();
}
}
@ -265,67 +267,22 @@ public class OrderBookController extends CachedViewController {
user.getCurrentBankAccount() != null;
}
private void showRegistrationDialog() {
int selectedIndex = -1;
if (areSettingsValid()) {
if (walletFacade.isRegistrationFeeBalanceNonZero()) {
if (walletFacade.isRegistrationFeeBalanceSufficient()) {
if (walletFacade.isRegistrationFeeConfirmed()) {
selectedIndex = 2;
}
else {
Action response = Popups.openErrorPopup("Registration fee not confirmed yet",
"The registration fee transaction has not been confirmed yet in the blockchain. " +
"Please wait until it has at least 1 confirmation.");
if (response == Dialog.Actions.OK) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
}
}
}
else {
Action response = Popups.openErrorPopup("Missing registration fee",
"You have not funded the full registration fee of " + BSFormatter
.formatCoinWithCode(FeePolicy.ACCOUNT_REGISTRATION_FEE) + " BTC.");
if (response == Dialog.Actions.OK) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
}
}
}
else {
selectedIndex = 1;
}
}
else {
selectedIndex = 0;
}
if (selectedIndex >= 0) {
Dialogs.CommandLink settingsCommandLink = new Dialogs.CommandLink("Open settings",
"You need to configure your settings before you can actively trade.");
Dialogs.CommandLink depositFeeCommandLink = new Dialogs.CommandLink("Deposit funds",
"You need to pay the registration fee before you can actively trade. That is needed as prevention" +
" against fraud.");
Dialogs.CommandLink sendRegistrationCommandLink = new Dialogs.CommandLink("Publish registration",
"When settings are configured and the fee deposit is done your registration transaction will be " +
"published to "
+ "the Bitcoin \nnetwork.");
List<Dialogs.CommandLink> commandLinks = Arrays.asList(settingsCommandLink, depositFeeCommandLink,
sendRegistrationCommandLink);
Action registrationMissingAction = Popups.openRegistrationMissingPopup("Not registered yet",
"Please follow these steps:",
"You need to register before you can place an offer.",
commandLinks,
selectedIndex);
if (registrationMissingAction == settingsCommandLink) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.SETTINGS);
private void openSetupScreen() {
MainController.GET_INSTANCE().blurContentScreen();
List<Action> actions = new ArrayList<>();
actions.add(new AbstractAction(BSResources.get("shared.ok")) {
@Override
public void handle(ActionEvent actionEvent) {
Dialog.Actions.OK.handle(actionEvent);
MainController.GET_INSTANCE().removeContentScreenBlur();
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.ACCOUNT);
}
else if (registrationMissingAction == depositFeeCommandLink) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
}
else if (registrationMissingAction == sendRegistrationCommandLink) {
payRegistrationFee();
}
}
});
Popups.openInfo("You need to setup your trading account before you can trade.",
"You don't have a trading account.", actions);
}
private void payRegistrationFee() {
@ -339,7 +296,7 @@ public class OrderBookController extends CachedViewController {
}
@Override
public void onFailure(Throwable t) {
public void onFailure(@NotNull Throwable t) {
log.debug("payRegistrationFee onFailure");
}
};
@ -364,11 +321,11 @@ public class OrderBookController extends CachedViewController {
if (parentController instanceof ViewController)
takeOfferController = (TakeOfferController) ((ViewController) parentController)
.loadViewAndGetChildController(NavigationItem
.TAKE_OFFER);
.TAKE_OFFER);
else if (parentController instanceof CodeBehind)
takeOfferController = (TakeOfferController) ((CodeBehind) parentController)
.loadViewAndGetChildController(NavigationItem
.TAKE_OFFER);
.TAKE_OFFER);
}
Coin requestedAmount;
@ -384,7 +341,7 @@ public class OrderBookController extends CachedViewController {
}
}
else {
showRegistrationDialog();
openSetupScreen();
}
}

View file

@ -67,7 +67,7 @@ public class BSFormatter {
private static CoinFormat coinFormat = CoinFormat.BTC.repeatOptionalDecimals(2, 1);
// format is like: 1,00 never more then 2 decimals
private static CoinFormat fiatFormat = CoinFormat.FIAT.repeatOptionalDecimals(0, 0);
private static final CoinFormat fiatFormat = CoinFormat.FIAT.repeatOptionalDecimals(0, 0);
private static String currencyCode = Currency.getInstance(Locale.getDefault()).getCurrencyCode();

View file

@ -22,7 +22,6 @@ import javafx.animation.FadeTransition;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.layout.*;
@ -31,15 +30,13 @@ import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkState;
public class Transitions {
private static final Logger log = LoggerFactory.getLogger(Transitions.class);
public static final int UI_ANIMATION_TIME = 800;
public static final int DURATION = 400;
public static void fadeIn(Node node) {
fadeIn(node, UI_ANIMATION_TIME);
fadeIn(node, DURATION);
}
public static void fadeIn(Node node, int duration) {
@ -50,7 +47,7 @@ public class Transitions {
}
public static Animation fadeOut(Node node) {
return fadeOut(node, UI_ANIMATION_TIME);
return fadeOut(node, DURATION);
}
public static Animation fadeOut(Node node, int duration) {
@ -62,7 +59,7 @@ public class Transitions {
}
public static Animation fadeOutAndRemove(Node node) {
return fadeOutAndRemove(node, UI_ANIMATION_TIME);
return fadeOutAndRemove(node, DURATION);
}
public static Animation fadeOutAndRemove(Node node, int duration) {
@ -74,45 +71,58 @@ public class Transitions {
return animation;
}
public static Timeline blurAndRemove(Node node) {
return blurAndRemove(node, UI_ANIMATION_TIME);
}
public static Timeline blurAndRemove(Node node, int duration) {
Timeline timeline = blur(node, duration);
timeline.setOnFinished(actionEvent -> {
((Pane) (node.getParent())).getChildren().remove(node);
Profiler.printMsgWithTime("blurOutAndRemove");
});
return timeline;
}
public static void blur(Node node) {
blur(node, UI_ANIMATION_TIME);
blur(node, DURATION, true, false);
}
public static Timeline blur(Node node, int duration) {
public static Timeline blur(Node node, int duration, boolean useDarken, boolean removeNode) {
GaussianBlur blur = new GaussianBlur(0.0);
node.setEffect(blur);
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 10.0);
KeyFrame kf = new KeyFrame(Duration.millis(duration), kv);
timeline.getKeyFrames().add(kf);
KeyValue kv1 = new KeyValue(blur.radiusProperty(), 15.0);
KeyFrame kf1 = new KeyFrame(Duration.millis(duration), kv1);
if (useDarken) {
ColorAdjust darken = new ColorAdjust();
darken.setBrightness(0.0);
blur.setInput(darken);
KeyValue kv2 = new KeyValue(darken.brightnessProperty(), -0.3);
KeyFrame kf2 = new KeyFrame(Duration.millis(duration), kv2);
timeline.getKeyFrames().addAll(kf1, kf2);
}
else {
timeline.getKeyFrames().addAll(kf1);
}
node.setEffect(blur);
if (removeNode) timeline.setOnFinished(actionEvent -> ((Pane) (node.getParent())).getChildren().remove(node));
timeline.play();
return timeline;
}
public static void removeBlur(Node node) {
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline durationline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME), kv);
durationline.getKeyFrames().add(kf);
durationline.setOnFinished(actionEvent -> node.setEffect(null));
durationline.play();
removeBlur(node, DURATION, false);
}
public static void checkGuiThread() {
checkState(Platform.isFxApplicationThread());
public static void removeBlur(Node node, int duration, boolean useDarken) {
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline timeline = new Timeline();
KeyValue kv1 = new KeyValue(blur.radiusProperty(), 0.0);
KeyFrame kf1 = new KeyFrame(Duration.millis(DURATION), kv1);
if (useDarken) {
ColorAdjust darken = (ColorAdjust) blur.getInput();
KeyValue kv2 = new KeyValue(darken.brightnessProperty(), 0.0);
KeyFrame kf2 = new KeyFrame(Duration.millis(duration), kv2);
timeline.getKeyFrames().addAll(kf1, kf2);
}
else {
timeline.getKeyFrames().addAll(kf1);
}
timeline.setOnFinished(actionEvent -> node.setEffect(null));
timeline.play();
}
}

View file

@ -17,23 +17,12 @@
package io.bitsquare.gui.util.validation;
import io.bitsquare.locale.BSResources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* NumberValidator for validating basic number values.
* Localisation not supported at the moment
* The decimal mark can be either "." or ",". Thousand separators are not supported yet,
* but might be added alter with Local support.
* <p>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
// TODO Add validation for primary and secondary IDs according to the selected type
public class BankAccountValidator extends InputValidator {
private static final Logger log = LoggerFactory.getLogger(BankAccountValidator.class);
public final class BankAccountNumberValidator extends InputValidator {
private static final Logger log = LoggerFactory.getLogger(BankAccountNumberValidator.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
@ -41,22 +30,14 @@ public class BankAccountValidator extends InputValidator {
@Override
public ValidationResult validate(String input) {
ValidationResult result = validateIfNotEmpty(input);
if (result.isValid)
result = validateMinLength(input);
return result;
// TODO Add validation for primary and secondary IDs according to the selected type
return super.validate(input);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected methods
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateMinLength(String input) {
if (input.length() > 3)
return new ValidationResult(true);
else
return new ValidationResult(false, BSResources.get("validation.inputTooShort"));
}
}

View file

@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
* <p>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
public class BtcValidator extends NumberValidator {
public final class BtcValidator extends NumberValidator {
private static final Logger log = LoggerFactory.getLogger(BtcValidator.class);
private ValidationResult externalValidationResult;
@ -73,10 +73,10 @@ public class BtcValidator extends NumberValidator {
///////////////////////////////////////////////////////////////////////////////////////////
// Protected methods
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateIfNotFractionalBtcValue(String input) {
private ValidationResult validateIfNotFractionalBtcValue(String input) {
BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.scale() > 0)
@ -85,7 +85,7 @@ public class BtcValidator extends NumberValidator {
return new ValidationResult(true);
}
protected ValidationResult validateIfNotExceedsMaxBtcValue(String input) {
private ValidationResult validateIfNotExceedsMaxBtcValue(String input) {
BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.longValue() > NetworkParameters.MAX_MONEY.longValue())

View file

@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
* <p>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
public class FiatValidator extends NumberValidator {
public final class FiatValidator extends NumberValidator {
private static final Logger log = LoggerFactory.getLogger(FiatValidator.class);
//TODO Find appropriate values - depends on currencies
@ -39,7 +39,7 @@ public class FiatValidator extends NumberValidator {
public static void setFiatCurrencyCode(String currencyCode) {
FiatValidator.currencyCode = currencyCode;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
@ -64,10 +64,10 @@ public class FiatValidator extends NumberValidator {
///////////////////////////////////////////////////////////////////////////////////////////
// Protected methods
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateIfNotExceedsMinFiatValue(String input) {
private ValidationResult validateIfNotExceedsMinFiatValue(String input) {
double d = Double.parseDouble(input);
if (d < MIN_FIAT_VALUE)
return new ValidationResult(false, BSResources.get("validation.fiat.toSmall", currencyCode));
@ -75,7 +75,7 @@ public class FiatValidator extends NumberValidator {
return new ValidationResult(true);
}
protected ValidationResult validateIfNotExceedsMaxFiatValue(String input) {
private ValidationResult validateIfNotExceedsMaxFiatValue(String input) {
double d = Double.parseDouble(input);
if (d > MAX_FIAT_VALUE)
return new ValidationResult(false, BSResources.get("validation.fiat.toLarge", currencyCode));

View file

@ -23,10 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* BaseValidator for validating basic number values.
* Localisation not supported at the moment
* The decimal mark can be either "." or ",". Thousand separators are not supported yet,
* but might be added alter with Local support.
* Base class for other specialized validators.
* <p>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
@ -52,11 +49,6 @@ public class InputValidator {
return new ValidationResult(true);
}
protected String cleanInput(String input) {
return input.replace(",", ".").trim();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ValidationResult
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -22,15 +22,7 @@ import io.bitsquare.locale.BSResources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* NumberValidator for validating basic number values.
* Localisation not supported at the moment
* The decimal mark can be either "." or ",". Thousand separators are not supported yet,
* but might be added alter with Local support.
* <p>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
public class PasswordValidator extends InputValidator {
public final class PasswordValidator extends InputValidator {
private static final Logger log = LoggerFactory.getLogger(PasswordValidator.class);
///////////////////////////////////////////////////////////////////////////////////////////
@ -47,10 +39,10 @@ public class PasswordValidator extends InputValidator {
///////////////////////////////////////////////////////////////////////////////////////////
// Protected methods
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateMinLength(String input) {
private ValidationResult validateMinLength(String input) {
if (input.length() > 7)
return new ValidationResult(true);
else

View file

@ -73,7 +73,7 @@ public class BootstrappedPeerFactory {
private KeyPair keyPair;
private Storage storage;
private final SeedNodeAddress seedNodeAddress;
private Persistence persistence;
private final Persistence persistence;
private final SettableFuture<PeerDHT> settableFuture = SettableFuture.create();

View file

@ -86,12 +86,12 @@ public class MessageFacade implements MessageBroker {
return p2pNode;
}
private P2PNode p2pNode;
private final P2PNode p2pNode;
private final List<OrderBookListener> orderBookListeners = new ArrayList<>();
private final List<ArbitratorListener> arbitratorListeners = new ArrayList<>();
private final List<IncomingTradeMessageListener> incomingTradeMessageListeners = new ArrayList<>();
private User user;
private final User user;
private SeedNodeAddress.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses;
@ -174,7 +174,7 @@ public class MessageFacade implements MessageBroker {
final Data offerData = new Data(offer);
// the offer is default 30 days valid
int defaultOfferTTL = 30 * 24 * 60 * 60 * 1000;
int defaultOfferTTL = 30 * 24 * 60 * 60;
offerData.ttlSeconds(defaultOfferTTL);
FuturePut futurePut = p2pNode.addProtectedData(locationKey, offerData);
@ -263,8 +263,8 @@ public class MessageFacade implements MessageBroker {
Platform.runLater(() -> orderBookListeners.stream().forEach(orderBookListener -> orderBookListener
.onOffersReceived(futureGet.dataMap(), baseFuture.isSuccess())));
if (baseFuture.isSuccess()) {
//log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey + ",
// values: " + futureGet.dataMap() + "]");
log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey
+ ", values: " + futureGet.dataMap() + "]");
}
else {
log.error("Get offers from DHT failed with reason:" + baseFuture.failedReason());

View file

@ -76,7 +76,7 @@ public class TradeManager {
private static final Logger log = LoggerFactory.getLogger(TradeManager.class);
private final User user;
private Settings settings;
private final Settings settings;
private final Persistence persistence;
private final MessageFacade messageFacade;
private final BlockChainFacade blockChainFacade;
@ -463,7 +463,7 @@ public class TradeManager {
@Nullable
public Trade getTrade(String tradeId) {
if (trades.containsKey(tradeId)) {
return trades.get(trades);
return trades.get(tradeId);
}
else {
return null;

View file

@ -27,12 +27,12 @@ public class BankTransferInitedMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = -3479634129543632523L;
private final String tradeId;
private String depositTxAsHex;
private String offererSignatureR;
private String offererSignatureS;
private Coin offererPaybackAmount;
private Coin takerPaybackAmount;
private String offererPayoutAddress;
private final String depositTxAsHex;
private final String offererSignatureR;
private final String offererSignatureS;
private final Coin offererPaybackAmount;
private final Coin takerPaybackAmount;
private final String offererPayoutAddress;
public BankTransferInitedMessage(String tradeId,
String depositTxAsHex,

View file

@ -26,7 +26,7 @@ public class DepositTxPublishedMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = -1532231540167406581L;
private final String tradeId;
private String depositTxAsHex;
private final String depositTxAsHex;
public DepositTxPublishedMessage(String tradeId, String depositTxAsHex) {
this.tradeId = tradeId;

View file

@ -26,11 +26,11 @@ public class RequestTakerDepositPaymentMessage implements Serializable, TradeMes
private static final long serialVersionUID = -3988720410493712913L;
private final String tradeId;
private BankAccount bankAccount;
private String accountID;
private String offererPubKey;
private String preparedOffererDepositTxAsHex;
private long offererTxOutIndex;
private final BankAccount bankAccount;
private final String accountID;
private final String offererPubKey;
private final String preparedOffererDepositTxAsHex;
private final long offererTxOutIndex;
public RequestTakerDepositPaymentMessage(String tradeId, BankAccount bankAccount, String accountID,
String offererPubKey, String preparedOffererDepositTxAsHex,

View file

@ -24,7 +24,7 @@ import java.io.Serializable;
public class RespondToTakeOfferRequestMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = 6177387534087739018L;
private final String tradeId;
private boolean takeOfferRequestAccepted;
private final boolean takeOfferRequestAccepted;
public RespondToTakeOfferRequestMessage(String tradeId, boolean takeOfferRequestAccepted) {
this.tradeId = tradeId;

View file

@ -24,7 +24,7 @@ import java.io.Serializable;
public class PayoutTxPublishedMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = 1288653559218403873L;
private final String tradeId;
private String payoutTxAsHex;
private final String payoutTxAsHex;
public PayoutTxPublishedMessage(String tradeId, String payoutTxAsHex) {
this.tradeId = tradeId;

View file

@ -27,19 +27,19 @@ import java.security.PublicKey;
public class RequestOffererPublishDepositTxMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = 2179683654379803071L;
private final String tradeId;
private BankAccount bankAccount;
private String accountID;
private PublicKey takerMessagePublicKey;
private String signedTakerDepositTxAsHex;
private String txScriptSigAsHex;
private String txConnOutAsHex;
private String contractAsJson;
private String takerContractSignature;
private String takerPayoutAddress;
private long takerTxOutIndex;
private final BankAccount bankAccount;
private final String accountID;
private final PublicKey takerMessagePublicKey;
private final String signedTakerDepositTxAsHex;
private final String txScriptSigAsHex;
private final String txConnOutAsHex;
private final String contractAsJson;
private final String takerContractSignature;
private final String takerPayoutAddress;
private final long takerTxOutIndex;
private long offererTxOutIndex;
private final long offererTxOutIndex;
public RequestOffererPublishDepositTxMessage(String tradeId,
BankAccount bankAccount,

View file

@ -27,9 +27,9 @@ public class TakeOfferFeePayedMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = -5057935061275354312L;
private final String tradeId;
private Coin tradeAmount;
private String takeOfferFeeTxID;
private String takerPubKey;
private final Coin tradeAmount;
private final String takeOfferFeeTxID;
private final String takerPubKey;
public TakeOfferFeePayedMessage(String tradeId, String takeOfferFeeTxID, Coin tradeAmount, String takerPubKey) {
this.tradeId = tradeId;

View file

@ -34,8 +34,11 @@ import java.util.Locale;
import javax.annotation.Nullable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,16 +51,24 @@ public class User implements Serializable {
private static final Logger log = LoggerFactory.getLogger(User.class);
private static final long serialVersionUID = 7409078808248518638L;
transient private final IntegerProperty selectedBankAccountIndexProperty = new SimpleIntegerProperty();
transient private final IntegerProperty bankAccountsSizeProperty = new SimpleIntegerProperty();
private KeyPair messageKeyPair;
private String accountID;
// TODO make it thread safe
private List<BankAccount> bankAccounts = new ArrayList<>();
private BankAccount currentBankAccount;
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
// only temporary
private List<BankAccount> _bankAccounts = new ArrayList<>();
private BankAccount _currentBankAccount;
private final transient ObservableList<BankAccount> bankAccounts = FXCollections.observableArrayList();
private final transient ObjectProperty<BankAccount> currentBankAccount = new SimpleObjectProperty<>();
public User() {
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
// only temporary
bankAccounts.addListener((ListChangeListener<BankAccount>) change ->
_bankAccounts = new ArrayList<>(bankAccounts));
currentBankAccount.addListener((ov) -> _currentBankAccount = currentBankAccount.get());
}
@ -67,35 +78,33 @@ public class User implements Serializable {
public void applyPersistedUser(User persistedUser) {
if (persistedUser != null) {
bankAccounts = persistedUser.getBankAccounts();
bankAccounts.setAll(persistedUser.getSerializedBankAccounts());
setCurrentBankAccount(persistedUser.getSerializedCurrentBankAccount());
messageKeyPair = persistedUser.getMessageKeyPair();
accountID = persistedUser.getAccountId();
setCurrentBankAccount(persistedUser.getCurrentBankAccount());
}
else {
// First time
bankAccounts = new ArrayList<>();
messageKeyPair = DSAKeyUtil.generateKeyPair(); // DSAKeyUtil.getKeyPair() runs in same thread now
// TODO use separate thread. DSAKeyUtil.getKeyPair() runs in same thread now
messageKeyPair = DSAKeyUtil.generateKeyPair();
}
bankAccountsSizeProperty.set(bankAccounts.size());
BSFormatter.setFiatCurrencyCode(Currency.getInstance(Locale.getDefault()).getCurrencyCode());
}
public void addBankAccount(BankAccount bankAccount) {
if (!bankAccounts.contains(bankAccount)) {
bankAccounts.add(bankAccount);
bankAccountsSizeProperty.set(bankAccounts.size());
}
public void setBankAccount(BankAccount bankAccount) {
// We use the account title as hashCode
// In case we edit an existing we replace it in the list
if (bankAccounts.contains(bankAccount))
bankAccounts.remove(bankAccount);
bankAccounts.add(bankAccount);
setCurrentBankAccount(bankAccount);
}
public void removeCurrentBankAccount() {
if (currentBankAccount != null) {
bankAccounts.remove(currentBankAccount);
bankAccountsSizeProperty.set(bankAccounts.size());
}
if (currentBankAccount.get() != null)
bankAccounts.remove(currentBankAccount.get());
if (bankAccounts.isEmpty())
setCurrentBankAccount(null);
@ -115,23 +124,21 @@ public class User implements Serializable {
}
public void setCurrentBankAccount(@Nullable BankAccount bankAccount) {
currentBankAccount = bankAccount;
currentBankAccount.set(bankAccount);
if (currentBankAccount != null) {
BSFormatter.setFiatCurrencyCode(currentBankAccount.getCurrency().getCurrencyCode());
FiatValidator.setFiatCurrencyCode(currentBankAccount.getCurrency().getCurrencyCode());
selectedBankAccountIndexProperty.set(bankAccounts.indexOf(currentBankAccount));
if (currentBankAccount.get() != null) {
BSFormatter.setFiatCurrencyCode(currentBankAccount.get().getCurrency().getCurrencyCode());
FiatValidator.setFiatCurrencyCode(currentBankAccount.get().getCurrency().getCurrencyCode());
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
// TODO just a first attempt, refine when working on the embedded data for the reg. tx
public String getStringifiedBankAccounts() {
// TODO use steam API
String bankAccountUIDs = "";
for (int i = 0; i < bankAccounts.size(); i++) {
BankAccount bankAccount = bankAccounts.get(i);
@ -148,15 +155,16 @@ public class User implements Serializable {
return accountID;
}
public List<BankAccount> getBankAccounts() {
public ObservableList<BankAccount> getBankAccounts() {
return bankAccounts;
}
public BankAccount getCurrentBankAccount() {
return currentBankAccount;
return currentBankAccount.get();
}
public BankAccount getBankAccount(String bankAccountId) {
// TODO use steam API
for (final BankAccount bankAccount : bankAccounts) {
if (bankAccount.getUid().equals(bankAccountId)) {
return bankAccount;
@ -165,10 +173,6 @@ public class User implements Serializable {
return null;
}
public IntegerProperty getSelectedBankAccountIndexProperty() {
return selectedBankAccountIndexProperty;
}
public KeyPair getMessageKeyPair() {
return messageKeyPair;
}
@ -181,7 +185,18 @@ public class User implements Serializable {
return DSAKeyUtil.getHexStringFromPublicKey(getMessagePublicKey());
}
public IntegerProperty getBankAccountsSizeProperty() {
return bankAccountsSizeProperty;
public ObjectProperty<BankAccount> currentBankAccountProperty() {
return currentBankAccount;
}
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
// only temporary
List<BankAccount> getSerializedBankAccounts() {
return _bankAccounts;
}
BankAccount getSerializedCurrentBankAccount() {
return _currentBankAccount;
}
}

View file

@ -3,6 +3,9 @@ shared.readMore=Read more...
shared.warning=Warning
shared.error=Error
shared.close=Close
shared.cancel=Cancel
shared.ok=OK
shared.openSettings=Open settings for editing
shared.buy=Buy Bitcoin
shared.sell=Sell Bitcoin
@ -18,7 +21,6 @@ validation.fiat.toLarge=Input larger as maximum possible {0} value is not allowe
validation.btc.toSmall=Input results in a Bitcoin value with a fraction of the smallest unit (Satoshi).
validation.btc.toLarge=Input larger as maximum possible Bitcoin value is not allowed..
validation.passwordTooShort=The password you entered is too short. It needs to have min. 8 characters.
validation.inputTooShort=Your input is too short.
# Create offer
createOffer.amount.prompt=Enter amount in BTC
@ -53,19 +55,17 @@ createOffer.fundsBox.networkFee=Bitcoin network fee:
createOffer.fundsBox.total=Total:
createOffer.fundsBox.showAdvanced=Show advanced settings
createOffer.fundsBox.hideAdvanced=Hide advanced settings
createOffer.fundsBox.placeOffer=Place offer
createOffer.fundsBox.placeOffer=Place offer
createOffer.fundsBox.paymentLabel=Bitsquare trade ({0})
createOffer.advancedBox.title=Advanced settings
createOffer.advancedBox.countries=Accepted countries:
createOffer.advancedBox.languages=Accepted languages:
createOffer.advancedBox.arbitrators=Accepted arbitrators:
createOffer.advancedBox.txType=Payments method:
createOffer.advancedBox.currency=Currency:
createOffer.advancedBox.txType=Payments method: createOffer.advancedBox.currency=Currency:
createOffer.advancedBox.county=Payments account country:
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
createOffer.success.title=Offer published
createOffer.success.headline=Your offer has been successfully published to the distributed orderbook.
createOffer.success.info=The Bitcoin network transaction ID for the offer payment is: {0}
createOffer.success.copyTxId=Copy transaction ID

View file

@ -1,111 +0,0 @@
# shared
shared.readMore=Read more...
shared.warning=Warning
shared.error=Error
shared.close=Close
shared.openSettings=Open settings for editing
shared.buy=Buy Bitcoin
shared.sell=Sell Bitcoin
# validation
validation.empty=Empty input is not allowed.
validation.NaN=Input is not a valid number.
validation.zero=Input of 0 is not allowed.
validation.negative=A negative value is not allowed.
validation.fiat.toSmall=Input smaller as minimum possible {0} value is not allowed.
validation.fiat.toLarge=Input larger as maximum possible {0} value is not allowed.
validation.btc.toSmall=Input results in a Bitcoin value with a fraction of the smallest unit (Satoshi).
validation.btc.toLarge=Input larger as maximum possible Bitcoin value is not allowed..
validation.passwordTooShort=The password you entered is too short. It needs to have min. 8 characters.
validation.inputTooShort=Your input is too short.
# Create offer
createOffer.amount.prompt=Enter amount in BTC
createOffer.price.prompt=Enter price
createOffer.volume.prompt=Enter amount in {0}
createOffer.minAmount.prompt=Enter min. amount
createOffer.amountPriceBox.title=Create your offer
createOffer.amountPriceBox.subTitle=Buy Bitcoin
createOffer.amountPriceBox.amountDescr=Amount of Bitcoin to buy
createOffer.amountPriceBox.priceDescr=Price per Bitcoin in {0}
createOffer.amountPriceBox.volumeDescr=Amount in {0} to spend
createOffer.amountPriceBox.minAmountDescr=Minimum amount of Bitcoin
createOffer.amountPriceBox.info=Define a price for which you want to byu Bitcoin and either enter the amount or the trade volume. With the minimum amount you can attract more potential traders with giving them more flexibility. But note that there is no automatic creation of a new offer for the remaining amount in the case that a trader takes your offer with a lower amount as defined in the amount field. Your offer will be removed from the orderbook once a trader has taken your offer.
createOffer.amountPriceBox.next=Next step
createOffer.amountPriceBox.warning.invalidBtcDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places.\nThe amount has been adjusted to 4 decimal places.
createOffer.amountPriceBox.warning.invalidFiatDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places. The amount has been adjusted to 2 decimal places.
createOffer.amountPriceBox.warning.adjustedVolume=The total volume you have entered leads to invalid fractional Bitcoin amounts. The amount has been adjusted and a new total volume be calculated from it.
createOffer.amountPriceBox.error.message=An error occurred when placing the offer:\n\n {0}
createOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount.
createOffer.validation.minAmountLargerThanAmount=Minimum amount cannot be larger than amount.
createOffer.fundsBox.title=Fund your trade wallet
createOffer.fundsBox.totalsNeeded=Funds needed for that trade:
createOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the Bitcoin amount entered above
createOffer.fundsBox.address=Trade wallet address:
createOffer.fundsBox.balance=Trade wallet balance:
createOffer.fundsBox.info=For every offer there is a dedicated trade wallet. You need to fund that trade wallet with the necessary Bitcoin amount. Those funds are reserved and will be used in the case that your offer gets executed. If you cancel your offer you can withdraw your funds from that trading wallet. The only payment which will be done now when placing the offer is the offer fee payment.
createOffer.fundsBox.collateral=Refundable collateral ({0}):
createOffer.fundsBox.offerFee=Offer fee:
createOffer.fundsBox.networkFee=Bitcoin network fee:
createOffer.fundsBox.total=Total:
createOffer.fundsBox.showAdvanced=Show advanced settings
createOffer.fundsBox.hideAdvanced=Hide advanced settings
createOffer.fundsBox.placeOffer=Place offer
createOffer.fundsBox.paymentLabel=Bitsquare trade ({0})
createOffer.advancedBox.title=Advanced settings
createOffer.advancedBox.countries=Accepted countries:
createOffer.advancedBox.languages=Accepted languages:
createOffer.advancedBox.arbitrators=Accepted arbitrators:
createOffer.advancedBox.txType=Payments method:
createOffer.advancedBox.currency=Currency:
createOffer.advancedBox.county=Payments account country:
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
createOffer.success.title=Offer published
createOffer.success.headline=Your offer has been successfully published to the distributed orderbook.
createOffer.success.info=The Bitcoin network transaction ID for the offer payment is: {0}
createOffer.success.copyTxId=Copy transaction ID
createOffer.error.message=An error occurred when placing the offer.\n{0}
# TODO Update the following string when doing the UI (old stuff...)
# generic
OTHER=Other
# BankAccountTypeInfo.BankAccountType
SEPA=Sepa
WIRE=Wire
INTERNATIONAL=International
OK_PAY=OK Pay
NET_TELLER=Netteller
PERFECT_MONEY=Perfect Money
# Arbitrator.ID_TYPE
REAL_LIFE_ID=Real life ID
NICKNAME=Nickname
COMPANY=Company
# Arbitrator.METHODS
TLS_NOTARY=TLS Notary
SKYPE_SCREEN_SHARING=Skype screen sharing
SMART_PHONE_VIDEO_CHAT=Smart phone video chat
REQUIRE_REAL_ID=Require real life Identification
BANK_STATEMENT=Bank statement
# Arbitrator.ID_VERIFICATIONS
PASSPORT=Passport
GOV_ID=Government issued ID
UTILITY_BILLS=Utility bills
FACEBOOK=Facebook account
GOOGLE_PLUS=Google+ account
TWITTER=Twitter account
PGP=PGP
BTC_OTC=BTC OTC

View file

@ -1,111 +0,0 @@
# shared
shared.readMore=Read more...
shared.warning=Warning
shared.error=Error
shared.close=Close
shared.openSettings=Open settings for editing
shared.buy=Buy Bitcoin
shared.sell=Sell Bitcoin
# validation
validation.empty=Empty input is not allowed.
validation.NaN=Input is not a valid number.
validation.zero=Input of 0 is not allowed.
validation.negative=A negative value is not allowed.
validation.fiat.toSmall=Input smaller as minimum possible {0} value is not allowed.
validation.fiat.toLarge=Input larger as maximum possible {0} value is not allowed.
validation.btc.toSmall=Input results in a Bitcoin value with a fraction of the smallest unit (Satoshi).
validation.btc.toLarge=Input larger as maximum possible Bitcoin value is not allowed..
validation.passwordTooShort=The password you entered is too short. It needs to have min. 8 characters.
validation.inputTooShort=Your input is too short.
# Create offer
createOffer.amount.prompt=Enter amount in BTC
createOffer.price.prompt=Enter price
createOffer.volume.prompt=Enter amount in {0}
createOffer.minAmount.prompt=Enter min. amount
createOffer.amountPriceBox.title=Create your offer
createOffer.amountPriceBox.subTitle=Buy Bitcoin
createOffer.amountPriceBox.amountDescr=Amount of Bitcoin to buy
createOffer.amountPriceBox.priceDescr=Price per Bitcoin in {0}
createOffer.amountPriceBox.volumeDescr=Amount in {0} to spend
createOffer.amountPriceBox.minAmountDescr=Minimum amount of Bitcoin
createOffer.amountPriceBox.info=Define a price for which you want to byu Bitcoin and either enter the amount or the trade volume. With the minimum amount you can attract more potential traders with giving them more flexibility. But note that there is no automatic creation of a new offer for the remaining amount in the case that a trader takes your offer with a lower amount as defined in the amount field. Your offer will be removed from the orderbook once a trader has taken your offer.
createOffer.amountPriceBox.next=Next step
createOffer.amountPriceBox.warning.invalidBtcDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places.\nThe amount has been adjusted to 4 decimal places.
createOffer.amountPriceBox.warning.invalidFiatDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places. The amount has been adjusted to 2 decimal places.
createOffer.amountPriceBox.warning.adjustedVolume=The total volume you have entered leads to invalid fractional Bitcoin amounts. The amount has been adjusted and a new total volume be calculated from it.
createOffer.amountPriceBox.error.message=An error occurred when placing the offer:\n\n {0}
createOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount.
createOffer.validation.minAmountLargerThanAmount=Minimum amount cannot be larger than amount.
createOffer.fundsBox.title=Fund your trade wallet
createOffer.fundsBox.totalsNeeded=Funds needed for that trade:
createOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the Bitcoin amount entered above
createOffer.fundsBox.address=Trade wallet address:
createOffer.fundsBox.balance=Trade wallet balance:
createOffer.fundsBox.info=For every offer there is a dedicated trade wallet. You need to fund that trade wallet with the necessary Bitcoin amount. Those funds are reserved and will be used in the case that your offer gets executed. If you cancel your offer you can withdraw your funds from that trading wallet. The only payment which will be done now when placing the offer is the offer fee payment.
createOffer.fundsBox.collateral=Refundable collateral ({0}):
createOffer.fundsBox.offerFee=Offer fee:
createOffer.fundsBox.networkFee=Bitcoin network fee:
createOffer.fundsBox.total=Total:
createOffer.fundsBox.showAdvanced=Show advanced settings
createOffer.fundsBox.hideAdvanced=Hide advanced settings
createOffer.fundsBox.placeOffer=Place offer
createOffer.fundsBox.paymentLabel=Bitsquare trade ({0})
createOffer.advancedBox.title=Advanced settings
createOffer.advancedBox.countries=Accepted countries:
createOffer.advancedBox.languages=Accepted languages:
createOffer.advancedBox.arbitrators=Accepted arbitrators:
createOffer.advancedBox.txType=Payments method:
createOffer.advancedBox.currency=Currency:
createOffer.advancedBox.county=Payments account country:
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
createOffer.success.title=Offer published
createOffer.success.headline=Your offer has been successfully published to the distributed orderbook.
createOffer.success.info=The Bitcoin network transaction ID for the offer payment is: {0}
createOffer.success.copyTxId=Copy transaction ID
createOffer.error.message=An error occurred when placing the offer.\n{0}
# TODO Update the following string when doing the UI (old stuff...)
# generic
OTHER=Other
# BankAccountTypeInfo.BankAccountType
SEPA=Sepa
WIRE=Wire
INTERNATIONAL=International
OK_PAY=OK Pay
NET_TELLER=Netteller
PERFECT_MONEY=Perfect Money
# Arbitrator.ID_TYPE
REAL_LIFE_ID=Real life ID
NICKNAME=Nickname
COMPANY=Company
# Arbitrator.METHODS
TLS_NOTARY=TLS Notary
SKYPE_SCREEN_SHARING=Skype screen sharing
SMART_PHONE_VIDEO_CHAT=Smart phone video chat
REQUIRE_REAL_ID=Require real life Identification
BANK_STATEMENT=Bank statement
# Arbitrator.ID_VERIFICATIONS
PASSPORT=Passport
GOV_ID=Government issued ID
UTILITY_BILLS=Utility bills
FACEBOOK=Facebook account
GOOGLE_PLUS=Google+ account
TWITTER=Twitter account
PGP=PGP
BTC_OTC=BTC OTC

View file

@ -1,111 +0,0 @@
# shared
shared.readMore=Read more...
shared.warning=Warning
shared.error=Error
shared.close=Close
shared.openSettings=Open settings for editing
shared.buy=Buy Bitcoin
shared.sell=Sell Bitcoin
# validation
validation.empty=Empty input is not allowed.
validation.NaN=Input is not a valid number.
validation.zero=Input of 0 is not allowed.
validation.negative=A negative value is not allowed.
validation.fiat.toSmall=Input smaller as minimum possible {0} value is not allowed.
validation.fiat.toLarge=Input larger as maximum possible {0} value is not allowed.
validation.btc.toSmall=Input results in a Bitcoin value with a fraction of the smallest unit (Satoshi).
validation.btc.toLarge=Input larger as maximum possible Bitcoin value is not allowed..
validation.passwordTooShort=The password you entered is too short. It needs to have min. 8 characters.
validation.inputTooShort=Your input is too short.
# Create offer
createOffer.amount.prompt=Enter amount in BTC
createOffer.price.prompt=Enter price
createOffer.volume.prompt=Enter amount in {0}
createOffer.minAmount.prompt=Enter min. amount
createOffer.amountPriceBox.title=Create your offer
createOffer.amountPriceBox.subTitle=Buy Bitcoin
createOffer.amountPriceBox.amountDescr=Amount of Bitcoin to buy
createOffer.amountPriceBox.priceDescr=Price per Bitcoin in {0}
createOffer.amountPriceBox.volumeDescr=Amount in {0} to spend
createOffer.amountPriceBox.minAmountDescr=Minimum amount of Bitcoin
createOffer.amountPriceBox.info=Define a price for which you want to byu Bitcoin and either enter the amount or the trade volume. With the minimum amount you can attract more potential traders with giving them more flexibility. But note that there is no automatic creation of a new offer for the remaining amount in the case that a trader takes your offer with a lower amount as defined in the amount field. Your offer will be removed from the orderbook once a trader has taken your offer.
createOffer.amountPriceBox.next=Next step
createOffer.amountPriceBox.warning.invalidBtcDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places.\nThe amount has been adjusted to 4 decimal places.
createOffer.amountPriceBox.warning.invalidFiatDecimalPlaces=The amount you have entered exceeds the number of allowed decimal places. The amount has been adjusted to 2 decimal places.
createOffer.amountPriceBox.warning.adjustedVolume=The total volume you have entered leads to invalid fractional Bitcoin amounts. The amount has been adjusted and a new total volume be calculated from it.
createOffer.amountPriceBox.error.message=An error occurred when placing the offer:\n\n {0}
createOffer.validation.amountSmallerThanMinAmount=Amount cannot be smaller than minimum amount.
createOffer.validation.minAmountLargerThanAmount=Minimum amount cannot be larger than amount.
createOffer.fundsBox.title=Fund your trade wallet
createOffer.fundsBox.totalsNeeded=Funds needed for that trade:
createOffer.fundsBox.totalsNeeded.prompt=Will be calculated from the Bitcoin amount entered above
createOffer.fundsBox.address=Trade wallet address:
createOffer.fundsBox.balance=Trade wallet balance:
createOffer.fundsBox.info=For every offer there is a dedicated trade wallet. You need to fund that trade wallet with the necessary Bitcoin amount. Those funds are reserved and will be used in the case that your offer gets executed. If you cancel your offer you can withdraw your funds from that trading wallet. The only payment which will be done now when placing the offer is the offer fee payment.
createOffer.fundsBox.collateral=Refundable collateral ({0}):
createOffer.fundsBox.offerFee=Offer fee:
createOffer.fundsBox.networkFee=Bitcoin network fee:
createOffer.fundsBox.total=Total:
createOffer.fundsBox.showAdvanced=Show advanced settings
createOffer.fundsBox.hideAdvanced=Hide advanced settings
createOffer.fundsBox.placeOffer=Place offer
createOffer.fundsBox.paymentLabel=Bitsquare trade ({0})
createOffer.advancedBox.title=Advanced settings
createOffer.advancedBox.countries=Accepted countries:
createOffer.advancedBox.languages=Accepted languages:
createOffer.advancedBox.arbitrators=Accepted arbitrators:
createOffer.advancedBox.txType=Payments method:
createOffer.advancedBox.currency=Currency:
createOffer.advancedBox.county=Payments account country:
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
createOffer.success.title=Offer published
createOffer.success.headline=Your offer has been successfully published to the distributed orderbook.
createOffer.success.info=The Bitcoin network transaction ID for the offer payment is: {0}
createOffer.success.copyTxId=Copy transaction ID
createOffer.error.message=An error occurred when placing the offer.\n{0}
# TODO Update the following string when doing the UI (old stuff...)
# generic
OTHER=Other
# BankAccountTypeInfo.BankAccountType
SEPA=Sepa
WIRE=Wire
INTERNATIONAL=International
OK_PAY=OK Pay
NET_TELLER=Netteller
PERFECT_MONEY=Perfect Money
# Arbitrator.ID_TYPE
REAL_LIFE_ID=Real life ID
NICKNAME=Nickname
COMPANY=Company
# Arbitrator.METHODS
TLS_NOTARY=TLS Notary
SKYPE_SCREEN_SHARING=Skype screen sharing
SMART_PHONE_VIDEO_CHAT=Smart phone video chat
REQUIRE_REAL_ID=Require real life Identification
BANK_STATEMENT=Bank statement
# Arbitrator.ID_VERIFICATIONS
PASSPORT=Passport
GOV_ID=Government issued ID
UTILITY_BILLS=Utility bills
FACEBOOK=Facebook account
GOOGLE_PLUS=Google+ account
TWITTER=Twitter account
PGP=PGP
BTC_OTC=BTC OTC

View file

@ -0,0 +1,101 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.settings;
import io.bitsquare.di.BitSquareModule;
import io.bitsquare.di.GuiceFXMLLoader;
import com.google.inject.Guice;
import com.google.inject.Injector;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* For testing single isolated UI screens
*/
public class RegistrationUITestRunner extends Application {
private static final Logger log = LoggerFactory.getLogger(RegistrationUITestRunner.class);
private Scene scene;
private Pane view;
private Pane pane;
private boolean devTest = true;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws IOException {
Injector injector = Guice.createInjector(new BitSquareModule());
GuiceFXMLLoader.setInjector(injector);
pane = new StackPane();
scene = new Scene(pane, 1000, 530);
scene.getAccelerators().put(KeyCombination.valueOf("Shortcut+S"), this::loadMainWindow);
loadMainWindow();
primaryStage.setScene(scene);
primaryStage.show();
}
public void loadMainWindow() {
log.debug("re load");
pane.getChildren().removeAll();
GuiceFXMLLoader loader = new GuiceFXMLLoader(
getUrl("/io/bitsquare/gui/account/registration/RegistrationView.fxml"), false);
try {
view = loader.load();
pane.getChildren().setAll(view);
refreshStylesheets();
} catch (IOException e) {
e.printStackTrace();
log.error(e.getStackTrace().toString());
}
}
private void refreshStylesheets() {
scene.getStylesheets().clear();
scene.getStylesheets().setAll(getUrl("/io/bitsquare/gui/bitsquare.css").toExternalForm());
}
private URL getUrl(String subPath) {
if (devTest) {
try {
// load from file system location to make a reload possible. makes dev process easier with hot reload
return new URL("file:///Users/mk/Documents/_intellij/bitsquare/src/main/java" + subPath);
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
else {
return getClass().getResource(subPath);
}
}
}