Apply formatting to Java sources

This is essentially the default IDEA formatting settings, with one tweak
made to allow same-line field annotations (useful particularly in the
case of the @FXML annotation)
This commit is contained in:
Chris Beams 2014-08-26 09:20:10 +02:00
parent 9c3df7375a
commit 7d6ca37d06
No known key found for this signature in database
GPG Key ID: 3D214F8F5BC5ED73
168 changed files with 3005 additions and 5439 deletions

View File

@ -32,9 +32,11 @@ import io.bitsquare.storage.Persistence;
import io.bitsquare.user.User;
import io.bitsquare.util.AWTSystemTray;
import io.bitsquare.util.StorageDirectory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
@ -46,8 +48,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BitSquare extends Application
{
public class BitSquare extends Application {
private static final Logger log = LoggerFactory.getLogger(BitSquare.class);
public static boolean fillFormsWithDummyData = true;
@ -57,8 +58,7 @@ public class BitSquare extends Application
private WalletFacade walletFacade;
private MessageFacade messageFacade;
public static void main(String[] args)
{
public static void main(String[] args) {
Profiler.init();
Profiler.printMsgWithTime("BitSquare.main called with args " + Arrays.asList(args).toString());
if (args != null && args.length > 0) APP_NAME = args[0];
@ -66,19 +66,16 @@ public class BitSquare extends Application
launch(args);
}
public static Stage getPrimaryStage()
{
public static Stage getPrimaryStage() {
return primaryStage;
}
public static String getAppName()
{
public static String getAppName() {
return APP_NAME;
}
@Override
public void start(Stage primaryStage) throws IOException
{
public void start(Stage primaryStage) throws IOException {
Profiler.printMsgWithTime("BitSquare.start called");
BitSquare.primaryStage = primaryStage;
@ -127,8 +124,7 @@ public class BitSquare extends Application
Profiler.printMsgWithTime("BitSquare: start finished");
}
private void setupCloseHandlers(Stage primaryStage, Scene scene)
{
private void setupCloseHandlers(Stage primaryStage, Scene scene) {
primaryStage.setOnCloseRequest(e -> AWTSystemTray.setStageHidden());
KeyCodeCombination keyCodeCombination = new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN);
@ -138,8 +134,7 @@ public class BitSquare extends Application
}
@Override
public void stop() throws Exception
{
public void stop() throws Exception {
walletFacade.shutDown();
messageFacade.shutDown();

View File

@ -18,8 +18,10 @@
package io.bitsquare;
import io.bitsquare.msg.SeedNodeAddress;
import java.io.IOException;
import java.util.List;
import net.tomp2p.dht.PeerBuilderDHT;
import net.tomp2p.futures.BaseFuture;
import net.tomp2p.futures.BaseFutureListener;
@ -39,22 +41,19 @@ import org.slf4j.LoggerFactory;
/**
* Well known node which is reachable for all peers for bootstrapping.
* There will be several SeedNodes running on several servers.
* <p>
* <p/>
* TODO: Alternative bootstrap methods will follow later (save locally list of known nodes reported form other peers,...)
*/
public class SeedNode extends Thread
{
public class SeedNode extends Thread {
private static final Logger log = LoggerFactory.getLogger(SeedNode.class);
private static final List<SeedNodeAddress.StaticSeedNodeAddresses> staticSedNodeAddresses = SeedNodeAddress.StaticSeedNodeAddresses.getAllSeedNodeAddresses();
/**
* @param args If no args passed we use localhost, otherwise the param is used as index for selecting an address from seedNodeAddresses
*/
public static void main(String[] args)
{
public static void main(String[] args) {
int index = 0;
if (args.length > 0)
{
if (args.length > 0) {
// use host index passes as param
int param = Integer.valueOf(args[0]);
if (param < staticSedNodeAddresses.size())
@ -65,12 +64,10 @@ public class SeedNode extends Thread
seedNode.setDaemon(true);
seedNode.start();
try
{
try {
// keep main thread up
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e)
{
} catch (InterruptedException e) {
log.error(e.toString());
}
}
@ -83,8 +80,7 @@ public class SeedNode extends Thread
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public SeedNode(SeedNodeAddress seedNodeAddress)
{
public SeedNode(SeedNodeAddress seedNodeAddress) {
this.seedNodeAddress = seedNodeAddress;
}
@ -93,29 +89,23 @@ public class SeedNode extends Thread
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void run()
{
public void run() {
Peer peer = startupPeer();
for (; ; )
{
try
{
for (; ; ) {
try {
// ping(peer);
Thread.sleep(300);
} catch (InterruptedException e)
{
} catch (InterruptedException e) {
log.error(e.toString());
}
}
}
public Peer startupPeer()
{
public Peer startupPeer() {
Peer peer = null;
try
{
try {
peer = new PeerBuilder(Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort()).start();
// Need to add all features the clients will use (otherwise msg type is UNKNOWN_ID)
@ -127,92 +117,71 @@ public class SeedNode extends Thread
log.debug("Peer started. " + peer.peerAddress());
peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener()
{
peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() {
@Override
public void peerInserted(PeerAddress peerAddress, boolean verified)
{
public void peerInserted(PeerAddress peerAddress, boolean verified) {
log.debug("Peer inserted: peerAddress=" + peerAddress + ", verified=" + verified);
}
@Override
public void peerRemoved(PeerAddress peerAddress, PeerStatatistic peerStatistics)
{
public void peerRemoved(PeerAddress peerAddress, PeerStatatistic peerStatistics) {
log.debug("Peer removed: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
}
@Override
public void peerUpdated(PeerAddress peerAddress, PeerStatatistic peerStatistics)
{
public void peerUpdated(PeerAddress peerAddress, PeerStatatistic peerStatistics) {
log.debug("Peer updated: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
}
});
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return peer;
}
private void ping(Peer peer)
{
private void ping(Peer peer) {
if (peer != null)
return;
try
{
try {
// Optional pinging
for (PeerAddress peerAddress : peer.peerBean().peerMap().all())
{
for (PeerAddress peerAddress : peer.peerBean().peerMap().all()) {
BaseFuture future = peer.ping().peerAddress(peerAddress).tcpPing().start();
future.addListener(new BaseFutureListener<BaseFuture>()
{
future.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
log.debug("peer online (TCP):" + peerAddress);
}
else
{
} else {
log.debug("offline " + peerAddress);
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("exceptionCaught " + t);
}
});
future = peer.ping().peerAddress(peerAddress).start();
future.addListener(new BaseFutureListener<BaseFuture>()
{
future.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
log.debug("peer online (UDP):" + peerAddress);
}
else
{
} else {
log.debug("offline " + peerAddress);
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("exceptionCaught " + t);
}
});
Thread.sleep(1500);
}
} catch (Exception e)
{
} catch (Exception e) {
log.error("Exception: " + e);
}
}

View File

@ -18,14 +18,14 @@
package io.bitsquare.bank;
import io.bitsquare.locale.Country;
import java.io.Serializable;
import java.util.Currency;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;
@Immutable
public class BankAccount implements Serializable
{
public class BankAccount implements Serializable {
private static final long serialVersionUID = 1792577576443221268L;
private final BankAccountType bankAccountType;
@ -38,8 +38,7 @@ public class BankAccount implements Serializable
private final Currency currency;
private final String accountTitle;
public BankAccount(BankAccountType bankAccountType, Currency currency, Country country, String accountTitle, String accountHolderName, String accountPrimaryID, String accountSecondaryID)
{
public BankAccount(BankAccountType bankAccountType, Currency currency, Country country, String accountTitle, String accountHolderName, String accountPrimaryID, String accountSecondaryID) {
this.bankAccountType = bankAccountType;
this.currency = currency;
this.country = country;
@ -49,13 +48,11 @@ public class BankAccount implements Serializable
this.accountSecondaryID = accountSecondaryID;
}
public int hashCode()
{
public int hashCode() {
return Objects.hashCode(accountTitle);
}
public boolean equals(Object obj)
{
public boolean equals(Object obj) {
if (!(obj instanceof BankAccount)) return false;
if (obj == this) return true;
@ -64,50 +61,41 @@ public class BankAccount implements Serializable
}
public String getAccountPrimaryID()
{
public String getAccountPrimaryID() {
return accountPrimaryID;
}
public String getAccountSecondaryID()
{
public String getAccountSecondaryID() {
return accountSecondaryID;
}
public String getAccountHolderName()
{
public String getAccountHolderName() {
return accountHolderName;
}
public BankAccountType getBankAccountType()
{
public BankAccountType getBankAccountType() {
return bankAccountType;
}
public Currency getCurrency()
{
public Currency getCurrency() {
return currency;
}
public Country getCountry()
{
public Country getCountry() {
return country;
}
// we use the accountTitle as unique id
public String getUid()
{
public String getUid() {
return accountTitle;
}
public String getAccountTitle()
{
public String getAccountTitle() {
return accountTitle;
}
@Override
public String toString()
{
public String toString() {
return "BankAccount{" +
"bankAccountType=" + bankAccountType +
", accountPrimaryID='" + accountPrimaryID + '\'' +

View File

@ -20,8 +20,7 @@ package io.bitsquare.bank;
import java.util.ArrayList;
import java.util.Arrays;
public enum BankAccountType
{
public enum BankAccountType {
SEPA("IBAN", "BIC"),
WIRE("primary ID", "secondary ID"),
INTERNATIONAL("primary ID", "secondary ID"),
@ -33,24 +32,20 @@ public enum BankAccountType
private final String primaryId;
private final String secondaryId;
BankAccountType(String primaryId, String secondaryId)
{
BankAccountType(String primaryId, String secondaryId) {
this.primaryId = primaryId;
this.secondaryId = secondaryId;
}
public static ArrayList<BankAccountType> getAllBankAccountTypes()
{
public static ArrayList<BankAccountType> getAllBankAccountTypes() {
return new ArrayList<>(Arrays.asList(BankAccountType.values()));
}
public String getPrimaryId()
{
public String getPrimaryId() {
return primaryId;
}
public String getSecondaryId()
{
public String getSecondaryId() {
return secondaryId;
}
}

View File

@ -22,8 +22,10 @@ import com.google.bitcoin.params.RegTestParams;
import com.google.bitcoin.wallet.CoinSelection;
import com.google.bitcoin.wallet.DefaultCoinSelector;
import com.google.common.annotations.VisibleForTesting;
import java.math.BigInteger;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,8 +34,7 @@ import org.slf4j.LoggerFactory;
* possible. This means that the transaction is the most likely to get confirmed. Note that this means we may end up
* "spending" more priority than would be required to get the transaction we are creating confirmed.
*/
public class AddressBasedCoinSelector extends DefaultCoinSelector
{
public class AddressBasedCoinSelector extends DefaultCoinSelector {
private static final Logger log = LoggerFactory.getLogger(AddressBasedCoinSelector.class);
private final NetworkParameters params;
private final AddressEntry addressEntry;
@ -48,8 +49,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
this(params, addressInfo, false);
} */
public AddressBasedCoinSelector(NetworkParameters params, AddressEntry addressEntry, boolean includePending)
{
public AddressBasedCoinSelector(NetworkParameters params, AddressEntry addressEntry, boolean includePending) {
this.params = params;
this.addressEntry = addressEntry;
this.includePending = includePending;
@ -57,13 +57,10 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static void sortOutputs(ArrayList<TransactionOutput> outputs)
{
Collections.sort(outputs, new Comparator<TransactionOutput>()
{
static void sortOutputs(ArrayList<TransactionOutput> outputs) {
Collections.sort(outputs, new Comparator<TransactionOutput>() {
@Override
public int compare(TransactionOutput a, TransactionOutput b)
{
public int compare(TransactionOutput a, TransactionOutput b) {
int depth1 = 0;
int depth2 = 0;
TransactionConfidence conf1 = a.getParentTransaction().getConfidence();
@ -89,8 +86,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
});
}
private static boolean isInBlockChainOrPending(Transaction tx)
{
private static boolean isInBlockChainOrPending(Transaction tx) {
// Pick chain-included transactions and transactions that are pending.
TransactionConfidence confidence = tx.getConfidence();
TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
@ -100,8 +96,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
(confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get());
}
private static boolean isInBlockChain(Transaction tx)
{
private static boolean isInBlockChain(Transaction tx) {
// Only pick chain-included transactions.
TransactionConfidence confidence = tx.getConfidence();
TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
@ -111,26 +106,19 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
/**
* Sub-classes can override this to just customize whether transactions are usable, but keep age sorting.
*/
protected boolean shouldSelect(Transaction tx)
{
if (includePending)
{
protected boolean shouldSelect(Transaction tx) {
if (includePending) {
return isInBlockChainOrPending(tx);
}
else
{
} else {
return isInBlockChain(tx);
}
}
@SuppressWarnings("WeakerAccess")
protected boolean matchesRequiredAddress(TransactionOutput transactionOutput)
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
protected boolean matchesRequiredAddress(TransactionOutput transactionOutput) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) {
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
if (addressEntry != null && addressOutput.equals(addressEntry.getAddress()))
{
if (addressEntry != null && addressOutput.equals(addressEntry.getAddress())) {
return true;
}
}
@ -138,8 +126,7 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
}
@Override
public CoinSelection select(Coin target, List<TransactionOutput> candidates)
{
public CoinSelection select(Coin target, List<TransactionOutput> candidates) {
long targetAsLong = target.longValue();
HashSet<TransactionOutput> selected = new HashSet<>();
// Sort the inputs by age*value so we get the highest "coindays" spent.
@ -147,23 +134,19 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<>(candidates);
// When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
// them in order to improve performance.
if (!target.equals(NetworkParameters.MAX_MONEY))
{
if (!target.equals(NetworkParameters.MAX_MONEY)) {
sortOutputs(sortedOutputs);
}
// Now iterate over the sorted outputs until we have got as close to the target as possible or a little
// bit over (excessive value will be change).
long total = 0;
for (TransactionOutput output : sortedOutputs)
{
if (total >= targetAsLong)
{
for (TransactionOutput output : sortedOutputs) {
if (total >= targetAsLong) {
break;
}
// Only pick chain-included transactions, or transactions that are ours and pending.
// Only select outputs from our defined address(es)
if (!shouldSelect(output.getParentTransaction()) || !matchesRequiredAddress(output))
{
if (!shouldSelect(output.getParentTransaction()) || !matchesRequiredAddress(output)) {
continue;
}

View File

@ -21,10 +21,10 @@ import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.core.Utils;
import com.google.bitcoin.crypto.DeterministicKey;
import java.io.Serializable;
public class AddressEntry implements Serializable
{
public class AddressEntry implements Serializable {
private static final long serialVersionUID = 5501603992599920416L;
private transient DeterministicKey key;
private final NetworkParameters params;
@ -33,13 +33,11 @@ public class AddressEntry implements Serializable
private final byte[] pubKeyHash;
public AddressEntry(DeterministicKey key, NetworkParameters params, AddressContext addressContext)
{
public AddressEntry(DeterministicKey key, NetworkParameters params, AddressContext addressContext) {
this(key, params, addressContext, null);
}
public AddressEntry(DeterministicKey key, NetworkParameters params, AddressContext addressContext, String offerId)
{
public AddressEntry(DeterministicKey key, NetworkParameters params, AddressContext addressContext, String offerId) {
this.key = key;
this.params = params;
this.addressContext = addressContext;
@ -48,48 +46,39 @@ public class AddressEntry implements Serializable
pubKeyHash = key.getPubOnly().getPubKeyHash();
}
public String getOfferId()
{
public String getOfferId() {
return offerId;
}
public AddressContext getAddressContext()
{
public AddressContext getAddressContext() {
return addressContext;
}
public String getAddressString()
{
public String getAddressString() {
return getAddress().toString();
}
public String getPubKeyAsHexString()
{
public String getPubKeyAsHexString() {
return Utils.HEX.encode(key.getPubKey());
}
public DeterministicKey getKey()
{
public DeterministicKey getKey() {
return key;
}
public Address getAddress()
{
public Address getAddress() {
return key.toAddress(params);
}
public void setDeterministicKey(DeterministicKey key)
{
public void setDeterministicKey(DeterministicKey key) {
this.key = key;
}
public byte[] getPubKeyHash()
{
public byte[] getPubKeyHash() {
return pubKeyHash;
}
public static enum AddressContext
{
public static enum AddressContext {
REGISTRATION_FEE,
TRADE,
ARBITRATOR_DEPOSIT

View File

@ -18,29 +18,26 @@
package io.bitsquare.btc;
import io.bitsquare.bank.BankAccount;
import javax.inject.Inject;
/**
* That facade delivers blockchain functionality from the bitcoinJ library
*/
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
public class BlockChainFacade
{
public class BlockChainFacade {
@Inject
public BlockChainFacade()
{
public BlockChainFacade() {
}
//TODO
public boolean isAccountBlackListed(String accountID, BankAccount bankAccount)
{
public boolean isAccountBlackListed(String accountID, BankAccount bankAccount) {
return false;
}
//TODO
public boolean verifyAccountRegistration()
{
public boolean verifyAccountRegistration() {
return true;
// tx id 76982adc582657b2eb68f3e43341596a68aadc4ef6b9590e88e93387d4d5d1f9
@ -52,37 +49,32 @@ public class BlockChainFacade
return true; */
}
private boolean findAddressInBlockChain(String address)
{
private boolean findAddressInBlockChain(String address) {
// TODO
// lookup for address in blockchain
return true;
}
private byte[] getDataForTxWithAddress(String address)
{
private byte[] getDataForTxWithAddress(String address) {
// TODO
// return data after OP_RETURN
return null;
}
private boolean isFeePayed(String address)
{
private boolean isFeePayed(String address) {
// TODO
// check if fee is payed
return true;
}
private boolean isAccountIDBlacklisted(String accountID)
{
private boolean isAccountIDBlacklisted(String accountID) {
// TODO
// check if accountID is on blacklist
return false;
}
private boolean isBankAccountBlacklisted(BankAccount bankAccount)
{
private boolean isBankAccountBlacklisted(BankAccount bankAccount) {
// TODO
// check if accountID is on blacklist
return false;

View File

@ -20,20 +20,18 @@ package io.bitsquare.btc;
import com.google.bitcoin.core.Coin;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.core.Transaction;
import javax.inject.Inject;
public class BtcValidator
{
public class BtcValidator {
private static NetworkParameters params;
@Inject
public BtcValidator(NetworkParameters params)
{
public BtcValidator(NetworkParameters params) {
BtcValidator.params = params;
}
public static boolean isMinSpendableAmount(Coin amount)
{
public static boolean isMinSpendableAmount(Coin amount) {
return amount != null && amount.compareTo(FeePolicy.TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)) > 0;
}

View File

@ -18,12 +18,13 @@
package io.bitsquare.btc;
import com.google.bitcoin.core.*;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FeePolicy
{
public class FeePolicy {
public static final Coin TX_FEE = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
public static final Coin ACCOUNT_REGISTRATION_FEE = Coin.CENT; // 0.01
public static final Coin CREATE_OFFER_FEE = Coin.MILLICOIN; // 0.001
@ -36,20 +37,16 @@ public class FeePolicy
private final NetworkParameters params;
@Inject
public FeePolicy(NetworkParameters params)
{
public FeePolicy(NetworkParameters params) {
this.params = params;
}
//TODO other users or dev address? use donation option list? (dev, other users, wikileaks, tor, sub projects (bitcoinj, tomp2p,...)...)
public Address getAddressForRegistrationFee()
{
try
{
public Address getAddressForRegistrationFee() {
try {
return new Address(params, registrationFeeAddress);
} catch (AddressFormatException e)
{
} catch (AddressFormatException e) {
e.printStackTrace();
return null;
}
@ -57,13 +54,10 @@ public class FeePolicy
//TODO get address form arbitrator list
public Address getAddressForCreateOfferFee()
{
try
{
public Address getAddressForCreateOfferFee() {
try {
return new Address(params, createOfferFeeAddress);
} catch (AddressFormatException e)
{
} catch (AddressFormatException e) {
e.printStackTrace();
return null;
}
@ -71,13 +65,10 @@ public class FeePolicy
//TODO get address form the intersection of both traders arbitrator lists
public Address getAddressForTakeOfferFee()
{
try
{
public Address getAddressForTakeOfferFee() {
try {
return new Address(params, takeOfferFeeAddress);
} catch (AddressFormatException e)
{
} catch (AddressFormatException e) {
e.printStackTrace();
return null;
}

View File

@ -19,8 +19,7 @@ package io.bitsquare.btc;
import com.google.bitcoin.core.Coin;
public class Restritions
{
public class Restritions {
public static final Coin MIN_TRADE_AMOUNT = Coin.CENT; // 0.01 Bitcoins

View File

@ -36,15 +36,19 @@ import io.bitsquare.btc.listeners.ConfidenceListener;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.storage.Persistence;
import io.bitsquare.util.StorageDirectory;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.util.Pair;
import javax.annotation.concurrent.GuardedBy;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -54,8 +58,7 @@ import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN;
* TODO: use walletextension (with protobuffer) instead of saving addressEntryList via storage
* TODO: use HD wallet features instead of addressEntryList
*/
public class WalletFacade
{
public class WalletFacade {
public static final String MAIN_NET = "MAIN_NET";
public static final String TEST_NET = "TEST_NET";
public static final String REG_TEST_NET = "REG_TEST_NET";
@ -88,8 +91,7 @@ public class WalletFacade
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade, Persistence persistence)
{
public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade, Persistence persistence) {
this.params = params;
this.feePolicy = feePolicy;
this.cryptoFacade = cryptoFacade;
@ -101,8 +103,7 @@ public class WalletFacade
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void initialize(StartupListener startupListener)
{
public void initialize(StartupListener startupListener) {
// Tell bitcoinj to execute event handlers on the JavaFX UI thread. This keeps things simple and means
// we cannot forget to switch threads when adding event handlers. Unfortunately, the DownloadListener
// we give to the app kit is currently an exception and runs on a library thread. It'll get fixed in
@ -110,11 +111,9 @@ public class WalletFacade
Threading.USER_THREAD = Platform::runLater;
// If seed is non-null it means we are restoring from backup.
walletAppKit = new WalletAppKit(params, StorageDirectory.getStorageDirectory(), WALLET_PREFIX)
{
walletAppKit = new WalletAppKit(params, StorageDirectory.getStorageDirectory(), WALLET_PREFIX) {
@Override
protected void onSetupCompleted()
{
protected void onSetupCompleted() {
// Don't make the user wait for confirmations for now, as the intention is they're sending it
// their own money!
walletAppKit.wallet().allowSpendingUnconfirmedTransactions();
@ -127,12 +126,9 @@ public class WalletFacade
};
// Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen
// or progress widget to keep the user engaged whilst we initialise, but we don't.
if (params == RegTestParams.get())
{
if (params == RegTestParams.get()) {
walletAppKit.connectToLocalHost(); // You should run a regtest mode bitcoind locally.
}
else if (params == MainNetParams.get())
{
} else if (params == MainNetParams.get()) {
// Checkpoints are block headers that ship inside our app: for a new user, we pick the last header
// in the checkpoints file and then download the rest from the network. It makes things much faster.
// Checkpoint files are made using the BuildCheckpoints tool and usually we have to download the
@ -142,68 +138,58 @@ public class WalletFacade
// walletAppKit.useTor();
}
walletAppKit.setDownloadListener(new BlockChainDownloadListener())
.setBlockingStartup(false)
.restoreWalletFromSeed(null)
.setUserAgent("BitSquare", "0.1");
.setBlockingStartup(false)
.restoreWalletFromSeed(null)
.setUserAgent("BitSquare", "0.1");
walletAppKit.startAsync();
}
private void initWallet()
{
private void initWallet() {
wallet = walletAppKit.wallet();
wallet.allowSpendingUnconfirmedTransactions();
//walletAppKit.peerGroup().setMaxConnections(11);
if (params == RegTestParams.get())
{
if (params == RegTestParams.get()) {
walletAppKit.peerGroup().setMinBroadcastConnections(1);
}
/* else
walletAppKit.peerGroup().setMinBroadcastConnections(2); */
walletEventListener = new WalletEventListener()
{
walletEventListener = new WalletEventListener() {
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
notifyBalanceListeners();
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
notifyBalanceListeners();
}
@Override
public void onReorganize(Wallet wallet)
{
public void onReorganize(Wallet wallet) {
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
{
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
notifyConfidenceListeners(tx);
}
@Override
public void onWalletChanged(Wallet wallet)
{
public void onWalletChanged(Wallet wallet) {
}
@Override
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
{
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
}
@Override
public void onKeysAdded(List<ECKey> keys)
{
public void onKeysAdded(List<ECKey> keys) {
}
};
@ -211,17 +197,13 @@ public class WalletFacade
Serializable serializable = persistence.read(this, "addressEntryList");
List<AddressEntry> persistedAddressEntryList = (List<AddressEntry>) serializable;
if (serializable instanceof List)
{
for (AddressEntry persistedAddressEntry : persistedAddressEntryList)
{
if (serializable instanceof List) {
for (AddressEntry persistedAddressEntry : persistedAddressEntryList) {
persistedAddressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash(persistedAddressEntry.getPubKeyHash()));
}
addressEntryList = persistedAddressEntryList;
registrationAddressEntry = addressEntryList.get(0);
}
else
{
} else {
lock.lock();
DeterministicKey registrationKey = wallet.currentReceiveKey();
registrationAddressEntry = new AddressEntry(registrationKey, params, AddressEntry.AddressContext.REGISTRATION_FEE);
@ -231,14 +213,12 @@ public class WalletFacade
}
}
public void shutDown()
{
public void shutDown() {
wallet.removeEventListener(walletEventListener);
walletAppKit.stopAsync();
}
public Wallet getWallet()
{
public Wallet getWallet() {
return wallet;
}
@ -248,36 +228,30 @@ public class WalletFacade
///////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("UnusedReturnValue")
public DownloadListener addDownloadListener(DownloadListener listener)
{
public DownloadListener addDownloadListener(DownloadListener listener) {
downloadListeners.add(listener);
return listener;
}
public void removeDownloadListener(DownloadListener listener)
{
public void removeDownloadListener(DownloadListener listener) {
downloadListeners.remove(listener);
}
public ConfidenceListener addConfidenceListener(ConfidenceListener listener)
{
public ConfidenceListener addConfidenceListener(ConfidenceListener listener) {
confidenceListeners.add(listener);
return listener;
}
public void removeConfidenceListener(ConfidenceListener listener)
{
public void removeConfidenceListener(ConfidenceListener listener) {
confidenceListeners.remove(listener);
}
public BalanceListener addBalanceListener(BalanceListener listener)
{
public BalanceListener addBalanceListener(BalanceListener listener) {
balanceListeners.add(listener);
return listener;
}
public void removeBalanceListener(BalanceListener listener)
{
public void removeBalanceListener(BalanceListener listener) {
balanceListeners.remove(listener);
}
@ -286,26 +260,22 @@ public class WalletFacade
// Get AddressInfo objects
///////////////////////////////////////////////////////////////////////////////////////////
public List<AddressEntry> getAddressEntryList()
{
public List<AddressEntry> getAddressEntryList() {
return ImmutableList.copyOf(addressEntryList);
}
public AddressEntry getRegistrationAddressEntry()
{
public AddressEntry getRegistrationAddressEntry() {
return registrationAddressEntry;
}
public AddressEntry getArbitratorDepositAddressEntry()
{
public AddressEntry getArbitratorDepositAddressEntry() {
if (arbitratorDepositAddressEntry == null)
arbitratorDepositAddressEntry = getNewAddressEntry(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT, null);
return arbitratorDepositAddressEntry;
}
public AddressEntry getAddressInfoByTradeID(String offerId)
{
public AddressEntry getAddressInfoByTradeID(String offerId) {
Optional<AddressEntry> addressEntry = getAddressEntryList().stream().filter(e -> offerId.equals(e.getOfferId())).findFirst();
if (addressEntry.isPresent())
@ -319,8 +289,7 @@ public class WalletFacade
// Create new AddressInfo objects
///////////////////////////////////////////////////////////////////////////////////////////
private AddressEntry getNewAddressEntry(AddressEntry.AddressContext addressContext, String offerId)
{
private AddressEntry getNewAddressEntry(AddressEntry.AddressContext addressContext, String offerId) {
lock.lock();
wallet.getLock().lock();
DeterministicKey key = wallet.freshReceiveKey();
@ -332,8 +301,7 @@ public class WalletFacade
return addressEntry;
}
private Optional<AddressEntry> getAddressEntryByAddressString(String address)
{
private Optional<AddressEntry> getAddressEntryByAddressString(String address) {
return getAddressEntryList().stream().filter(e -> address.equals(e.getAddressString())).findFirst();
}
@ -342,12 +310,10 @@ public class WalletFacade
// TransactionConfidence
///////////////////////////////////////////////////////////////////////////////////////////
public TransactionConfidence getConfidenceForAddress(Address address)
{
public TransactionConfidence getConfidenceForAddress(Address address) {
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
Set<Transaction> transactions = wallet.getTransactions(true);
if (transactions != null)
{
if (transactions != null) {
transactionConfidenceList.addAll(transactions.stream().map(tx -> getTransactionConfidence(tx, address)).collect(Collectors.toList()));
/* same as:
for (Transaction tx : transactions)
@ -359,10 +325,8 @@ public class WalletFacade
return getMostRecentConfidence(transactionConfidenceList);
}
private void notifyConfidenceListeners(Transaction tx)
{
for (ConfidenceListener confidenceListener : confidenceListeners)
{
private void notifyConfidenceListeners(Transaction tx) {
for (ConfidenceListener confidenceListener : confidenceListeners) {
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
transactionConfidenceList.add(getTransactionConfidence(tx, confidenceListener.getAddress()));
@ -372,15 +336,13 @@ public class WalletFacade
}
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address)
{
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
mergedOutputs.stream().filter(e -> e.getScriptPubKey().isSentToAddress() || e.getScriptPubKey().isSentToP2SH()).forEach(transactionOutput -> {
Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params);
if (address.equals(outputAddress))
{
if (address.equals(outputAddress)) {
transactionConfidenceList.add(tx.getConfidence());
}
});
@ -402,18 +364,15 @@ public class WalletFacade
}
private List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx)
{
private List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx) {
List<TransactionOutput> transactionOutputs = tx.getOutputs();
List<TransactionOutput> connectedOutputs = new ArrayList<>();
// add all connected outputs from any inputs as well
List<TransactionInput> transactionInputs = tx.getInputs();
for (TransactionInput transactionInput : transactionInputs)
{
for (TransactionInput transactionInput : transactionInputs) {
TransactionOutput transactionOutput = transactionInput.getConnectedOutput();
if (transactionOutput != null)
{
if (transactionOutput != null) {
connectedOutputs.add(transactionOutput);
}
}
@ -425,19 +384,15 @@ public class WalletFacade
}
private TransactionConfidence getMostRecentConfidence(List<TransactionConfidence> transactionConfidenceList)
{
private TransactionConfidence getMostRecentConfidence(List<TransactionConfidence> transactionConfidenceList) {
TransactionConfidence transactionConfidence = null;
for (TransactionConfidence confidence : transactionConfidenceList)
{
if (confidence != null)
{
for (TransactionConfidence confidence : transactionConfidenceList) {
if (confidence != null) {
if (transactionConfidence == null ||
confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.PENDING) ||
(confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING) &&
transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING) &&
confidence.getDepthInBlocks() < transactionConfidence.getDepthInBlocks()))
{
confidence.getDepthInBlocks() < transactionConfidence.getDepthInBlocks())) {
transactionConfidence = confidence;
}
}
@ -447,11 +402,9 @@ public class WalletFacade
}
public boolean isRegistrationFeeConfirmed()
{
public boolean isRegistrationFeeConfirmed() {
TransactionConfidence transactionConfidence = null;
if (getRegistrationAddressEntry() != null)
{
if (getRegistrationAddressEntry() != null) {
transactionConfidence = getConfidenceForAddress(getRegistrationAddressEntry().getAddress());
}
return transactionConfidence != null && transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING);
@ -462,21 +415,16 @@ public class WalletFacade
// Balance
///////////////////////////////////////////////////////////////////////////////////////////
public Coin getBalanceForAddress(Address address)
{
public Coin getBalanceForAddress(Address address) {
return getBalance(wallet.calculateAllSpendCandidates(true), address);
}
private Coin getBalance(LinkedList<TransactionOutput> transactionOutputs, Address address)
{
private Coin getBalance(LinkedList<TransactionOutput> transactionOutputs, Address address) {
Coin balance = Coin.ZERO;
for (TransactionOutput transactionOutput : transactionOutputs)
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
for (TransactionOutput transactionOutput : transactionOutputs) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) {
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
if (addressOutput.equals(address))
{
if (addressOutput.equals(address)) {
balance = balance.add(transactionOutput.getValue());
}
}
@ -484,10 +432,8 @@ public class WalletFacade
return balance;
}
private void notifyBalanceListeners()
{
for (BalanceListener balanceListener : balanceListeners)
{
private void notifyBalanceListeners() {
for (BalanceListener balanceListener : balanceListeners) {
Coin balance;
if (balanceListener.getAddress() != null)
balance = getBalanceForAddress(balanceListener.getAddress());
@ -498,28 +444,23 @@ public class WalletFacade
}
}
public Coin getWalletBalance()
{
public Coin getWalletBalance() {
return wallet.getBalance(Wallet.BalanceType.ESTIMATED);
}
Coin getRegistrationBalance()
{
Coin getRegistrationBalance() {
return getBalanceForAddress(getRegistrationAddressEntry().getAddress());
}
public Coin getArbitratorDepositBalance()
{
public Coin getArbitratorDepositBalance() {
return getBalanceForAddress(getArbitratorDepositAddressEntry().getAddress());
}
public boolean isRegistrationFeeBalanceNonZero()
{
public boolean isRegistrationFeeBalanceNonZero() {
return getRegistrationBalance().compareTo(Coin.ZERO) > 0;
}
public boolean isRegistrationFeeBalanceSufficient()
{
public boolean isRegistrationFeeBalanceSufficient() {
return getRegistrationBalance().compareTo(FeePolicy.ACCOUNT_REGISTRATION_FEE) >= 0;
}
@ -538,8 +479,7 @@ public class WalletFacade
}*/
//TODO
public int getNumOfPeersSeenTx(String txID)
{
public int getNumOfPeersSeenTx(String txID) {
// TODO check from blockchain
// will be async
return 3;
@ -550,8 +490,7 @@ public class WalletFacade
// Transactions
///////////////////////////////////////////////////////////////////////////////////////////
public void payRegistrationFee(String stringifiedBankAccounts, FutureCallback<Transaction> callback) throws InsufficientMoneyException
{
public void payRegistrationFee(String stringifiedBankAccounts, FutureCallback<Transaction> callback) throws InsufficientMoneyException {
log.debug("payRegistrationFee");
log.trace("stringifiedBankAccounts " + stringifiedBankAccounts);
@ -591,8 +530,7 @@ public class WalletFacade
printInputs("payRegistrationFee", tx);
}
public Transaction createOfferFeeTx(String offerId) throws InsufficientMoneyException
{
public Transaction createOfferFeeTx(String offerId) throws InsufficientMoneyException {
log.trace("createOfferFeeTx");
Transaction tx = new Transaction(params);
Coin fee = FeePolicy.CREATE_OFFER_FEE.subtract(FeePolicy.TX_FEE);
@ -609,15 +547,13 @@ public class WalletFacade
return tx;
}
public void broadcastCreateOfferFeeTx(Transaction tx, FutureCallback<Transaction> callback) throws InsufficientMoneyException
{
public void broadcastCreateOfferFeeTx(Transaction tx, FutureCallback<Transaction> callback) throws InsufficientMoneyException {
log.trace("broadcast tx");
ListenableFuture<Transaction> future = walletAppKit.peerGroup().broadcastTransaction(tx);
Futures.addCallback(future, callback);
}
public String payTakeOfferFee(String offerId, FutureCallback<Transaction> callback) throws InsufficientMoneyException
{
public String payTakeOfferFee(String offerId, FutureCallback<Transaction> callback) throws InsufficientMoneyException {
Transaction tx = new Transaction(params);
Coin fee = FeePolicy.TAKE_OFFER_FEE.subtract(FeePolicy.TX_FEE);
log.trace("fee: " + fee.toFriendlyString());
@ -647,8 +583,7 @@ public class WalletFacade
String withdrawToAddress,
String changeAddress,
Coin amount,
FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException
{
FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException {
Transaction tx = new Transaction(params);
tx.addOutput(amount.subtract(FeePolicy.TX_FEE), new Address(params, withdrawToAddress));
@ -685,8 +620,7 @@ public class WalletFacade
String offererPubKey,
String takerPubKey,
String arbitratorPubKey,
String tradeId) throws InsufficientMoneyException
{
String tradeId) throws InsufficientMoneyException {
log.debug("offererCreatesMSTxAndAddPayment");
log.trace("inputs: ");
log.trace("offererInputAmount=" + offererInputAmount.toFriendlyString());
@ -747,8 +681,7 @@ public class WalletFacade
String takerPubKey,
String arbitratorPubKey,
String offerersPartialDepositTxAsHex,
String tradeId) throws InsufficientMoneyException
{
String tradeId) throws InsufficientMoneyException {
log.debug("takerAddPaymentAndSignTx");
log.trace("inputs: ");
log.trace("takerInputAmount=" + takerInputAmount.toFriendlyString());
@ -803,8 +736,7 @@ public class WalletFacade
// Now we add the inputs and outputs from our temp tx and change the multiSig amount to the correct value
tx.addInput(tempTx.getInput(0));
if (tempTx.getOutputs().size() == 2)
{
if (tempTx.getOutputs().size() == 2) {
tx.addOutput(tempTx.getOutput(1));
}
@ -814,8 +746,7 @@ public class WalletFacade
// Now we sign our input
TransactionInput input = tx.getInput(1);
if (input == null || input.getConnectedOutput() == null)
{
if (input == null || input.getConnectedOutput() == null) {
log.error("input or input.getConnectedOutput() is null: " + input);
}
@ -824,16 +755,11 @@ public class WalletFacade
Sha256Hash hash = tx.hashForSignature(1, scriptPubKey, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature ecSig = sigKey.sign(hash);
TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
if (scriptPubKey.isSentToRawPubKey())
{
if (scriptPubKey.isSentToRawPubKey()) {
input.setScriptSig(ScriptBuilder.createInputScript(txSig));
}
else if (scriptPubKey.isSentToAddress())
{
} else if (scriptPubKey.isSentToAddress()) {
input.setScriptSig(ScriptBuilder.createInputScript(txSig, sigKey));
}
else
{
} else {
throw new ScriptException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey);
}
@ -872,8 +798,7 @@ public class WalletFacade
String takersSignedScriptSigAsHex,
long offererTxOutIndex,
long takerTxOutIndex,
FutureCallback<Transaction> callback)
{
FutureCallback<Transaction> callback) {
log.debug("offererSignAndPublishTx");
log.trace("inputs: ");
log.trace("offerersFirstTxAsHex=" + offerersFirstTxAsHex);
@ -916,12 +841,10 @@ public class WalletFacade
//TODO onResult non change output cases
// add outputs from takers tx, they are already correct
tx.addOutput(takersSignedTx.getOutput(0));
if (takersSignedTx.getOutputs().size() > 1)
{
if (takersSignedTx.getOutputs().size() > 1) {
tx.addOutput(takersSignedTx.getOutput(1));
}
if (takersSignedTx.getOutputs().size() == 3)
{
if (takersSignedTx.getOutputs().size() == 3) {
tx.addOutput(takersSignedTx.getOutput(2));
}
@ -931,8 +854,7 @@ public class WalletFacade
// sign the input
TransactionInput input = tx.getInput(0);
if (input == null || input.getConnectedOutput() == null)
{
if (input == null || input.getConnectedOutput() == null) {
log.error("input or input.getConnectedOutput() is null: " + input);
}
@ -941,16 +863,11 @@ public class WalletFacade
Sha256Hash hash = tx.hashForSignature(0, scriptPubKey, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature ecSig = sigKey.sign(hash);
TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
if (scriptPubKey.isSentToRawPubKey())
{
if (scriptPubKey.isSentToRawPubKey()) {
input.setScriptSig(ScriptBuilder.createInputScript(txSig));
}
else if (scriptPubKey.isSentToAddress())
{
} else if (scriptPubKey.isSentToAddress()) {
input.setScriptSig(ScriptBuilder.createInputScript(txSig, sigKey));
}
else
{
} else {
throw new ScriptException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey);
}
@ -989,8 +906,7 @@ public class WalletFacade
}
// 4 step deposit tx: Offerer send deposit tx to taker
public String takerCommitDepositTx(String depositTxAsHex)
{
public String takerCommitDepositTx(String depositTxAsHex) {
log.trace("takerCommitDepositTx");
log.trace("inputs: ");
log.trace("depositTxID=" + depositTxAsHex);
@ -999,13 +915,11 @@ public class WalletFacade
// boolean isAlreadyInWallet = wallet.maybeCommitTx(depositTx);
//log.trace("isAlreadyInWallet=" + isAlreadyInWallet);
try
{
try {
// Manually add the multisigContract to the wallet, overriding the isRelevant checks so we can track
// it and check for double-spends later
wallet.receivePending(depositTx, null, true);
} catch (VerificationException e)
{
} catch (VerificationException e) {
throw new RuntimeException(e); // Cannot happen, we already called multisigContract.verify()
}
@ -1019,8 +933,7 @@ public class WalletFacade
Coin offererPaybackAmount,
Coin takerPaybackAmount,
String takerAddress,
String tradeID) throws AddressFormatException
{
String tradeID) throws AddressFormatException {
log.debug("offererCreatesAndSignsPayoutTx");
log.trace("inputs: ");
log.trace("depositTxID=" + depositTxID);
@ -1057,8 +970,7 @@ public class WalletFacade
Coin takerPaybackAmount,
String offererAddress,
String tradeID,
FutureCallback<Transaction> callback) throws AddressFormatException
{
FutureCallback<Transaction> callback) throws AddressFormatException {
log.debug("takerSignsAndSendsTx");
log.trace("inputs: ");
log.trace("depositTxAsHex=" + depositTxAsHex);
@ -1110,22 +1022,18 @@ public class WalletFacade
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void saveAddressInfoList()
{
private void saveAddressInfoList() {
// use wallet extension?
lock.lock();
try
{
try {
persistence.write(this, "addressEntryList", addressEntryList);
} finally
{
} finally {
lock.unlock();
}
}
//TODO
private Script getMultiSigScript(String offererPubKey, String takerPubKey, String arbitratorPubKey)
{
private Script getMultiSigScript(String offererPubKey, String takerPubKey, String arbitratorPubKey) {
ECKey offererKey = ECKey.fromPublicOnly(Utils.parseAsHexOrBase58(offererPubKey));
ECKey takerKey = ECKey.fromPublicOnly(Utils.parseAsHexOrBase58(takerPubKey));
ECKey arbitratorKey = ECKey.fromPublicOnly(Utils.parseAsHexOrBase58(arbitratorPubKey));
@ -1135,8 +1043,7 @@ public class WalletFacade
}
private Transaction createPayoutTx(String depositTxAsHex, Coin offererPaybackAmount, Coin takerPaybackAmount, String offererAddress, String takerAddress) throws AddressFormatException
{
private Transaction createPayoutTx(String depositTxAsHex, Coin offererPaybackAmount, Coin takerPaybackAmount, String offererAddress, String takerAddress) throws AddressFormatException {
log.trace("createPayoutTx");
log.trace("inputs: ");
log.trace("depositTxAsHex=" + depositTxAsHex);
@ -1155,16 +1062,11 @@ public class WalletFacade
return tx;
}
public static void printInputs(String tracePrefix, Transaction tx)
{
for (TransactionInput input : tx.getInputs())
{
if (input.getConnectedOutput() != null)
{
public static void printInputs(String tracePrefix, Transaction tx) {
for (TransactionInput input : tx.getInputs()) {
if (input.getConnectedOutput() != null) {
log.trace(tracePrefix + " input value : " + input.getConnectedOutput().getValue().toFriendlyString());
}
else
{
} else {
log.trace(tracePrefix + ": " + "Transaction already has inputs but we don't have the connected outputs, so we don't know the value.");
}
}
@ -1175,46 +1077,37 @@ public class WalletFacade
// Inner classes
///////////////////////////////////////////////////////////////////////////////////////////
public static interface StartupListener
{
public static interface StartupListener {
void completed();
}
public static interface DownloadListener
{
public static interface DownloadListener {
void progress(double percent);
void downloadComplete();
}
private class BlockChainDownloadListener extends com.google.bitcoin.core.DownloadListener
{
private class BlockChainDownloadListener extends com.google.bitcoin.core.DownloadListener {
@Override
protected void progress(double percent, int blocksSoFar, Date date)
{
protected void progress(double percent, int blocksSoFar, Date date) {
super.progress(percent, blocksSoFar, date);
Platform.runLater(() -> onProgressInUserThread(percent));
}
@Override
protected void doneDownload()
{
protected void doneDownload() {
super.doneDownload();
Platform.runLater(this::onDoneDownloadInUserThread);
}
private void onProgressInUserThread(double percent)
{
for (DownloadListener downloadListener : downloadListeners)
{
private void onProgressInUserThread(double percent) {
for (DownloadListener downloadListener : downloadListeners) {
downloadListener.progress(percent);
}
}
private void onDoneDownloadInUserThread()
{
for (DownloadListener downloadListener : downloadListeners)
{
private void onDoneDownloadInUserThread() {
for (DownloadListener downloadListener : downloadListeners) {
downloadListener.downloadComplete();
}
}

View File

@ -20,25 +20,20 @@ package io.bitsquare.btc.listeners;
import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.Coin;
public class BalanceListener
{
public class BalanceListener {
private Address address;
public BalanceListener()
{
public BalanceListener() {
}
public BalanceListener(Address address)
{
public BalanceListener(Address address) {
this.address = address;
}
public Address getAddress()
{
public Address getAddress() {
return address;
}
public void onBalanceChanged(Coin balance)
{
public void onBalanceChanged(Coin balance) {
}
}

View File

@ -20,22 +20,18 @@ package io.bitsquare.btc.listeners;
import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.TransactionConfidence;
public class ConfidenceListener
{
public class ConfidenceListener {
private final Address address;
public ConfidenceListener(Address address)
{
public ConfidenceListener(Address address) {
this.address = address;
}
public Address getAddress()
{
public Address getAddress() {
return address;
}
public void onTransactionConfidenceChanged(TransactionConfidence confidence)
{
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
}
}

View File

@ -22,10 +22,12 @@ import com.google.bitcoin.core.Sha256Hash;
import com.google.bitcoin.core.Utils;
import com.google.bitcoin.crypto.KeyCrypterException;
import com.google.common.base.Charsets;
import java.nio.charset.Charset;
import java.security.SignatureException;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.crypto.params.KeyParameter;
@ -34,29 +36,24 @@ import org.spongycastle.util.encoders.Base64;
/**
* That facade delivers crypto functionality from the bitcoinJ library
*/
public class CryptoFacade
{
public class CryptoFacade {
private static final Logger log = LoggerFactory.getLogger(CryptoFacade.class);
@Inject
public CryptoFacade()
{
public CryptoFacade() {
}
// DeterministicKey does not support signMessage yet.
private String signMessage(ECKey key, String message, @Nullable KeyParameter aesKey) throws KeyCrypterException
{
private String signMessage(ECKey key, String message, @Nullable KeyParameter aesKey) throws KeyCrypterException {
byte[] data = Utils.formatMessageForSigning(message);
Sha256Hash hash = Sha256Hash.createDouble(data);
ECKey.ECDSASignature sig = key.sign(hash, aesKey);
// Now we have to work backwards to figure out the recId needed to recover the signature.
int recId = -1;
for (int i = 0; i < 4; i++)
{
for (int i = 0; i < 4; i++) {
ECKey k = ECKey.recoverFromSignature(i, sig, hash, key.isCompressed());
if (k != null && k.getPubKeyPoint().equals(key.getPubKeyPoint()))
{
if (k != null && k.getPubKeyPoint().equals(key.getPubKeyPoint())) {
recId = i;
break;
}
@ -71,46 +68,38 @@ public class CryptoFacade
return new String(Base64.encode(sigData), Charset.forName("UTF-8"));
}
public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts)
{
public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts) {
String signedBankAccountIDs = signMessage(registrationKey, stringifiedBankAccounts, null);
return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets.UTF_8));
}
public String signContract(ECKey key, String contractAsJson)
{
public String signContract(ECKey key, String contractAsJson) {
return signMessage(key, contractAsJson, null);
}
// registration
public boolean verifySignature(byte[] pubKey, String msg, String sig)
{
try
{
public boolean verifySignature(byte[] pubKey, String msg, String sig) {
try {
ECKey key = ECKey.fromPublicOnly(pubKey);
key.verifyMessage(msg, sig);
return true;
} catch (SignatureException e)
{
} catch (SignatureException e) {
return false;
}
}
public boolean verifyHash(String hashAsHexStringToVerify, String msg, String sig)
{
public boolean verifyHash(String hashAsHexStringToVerify, String msg, String sig) {
String hashAsHexString = Utils.HEX.encode(createHash(msg, sig));
return hashAsHexString.equals(hashAsHexStringToVerify);
}
private byte[] createHash(String msg, String sig)
{
private byte[] createHash(String msg, String sig) {
byte[] hashBytes = concatenateChunks(msg, sig).getBytes(Charsets.UTF_8);
return Utils.sha256hash160(hashBytes);
}
private String concatenateChunks(String stringifiedBankAccounts, String signedBankAccountIDs)
{
private String concatenateChunks(String stringifiedBankAccounts, String signedBankAccountIDs) {
return stringifiedBankAccounts + signedBankAccountIDs;
}

View File

@ -40,14 +40,13 @@ import io.bitsquare.storage.Persistence;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.user.User;
import javax.inject.Inject;
public class BitSquareModule extends AbstractModule
{
public class BitSquareModule extends AbstractModule {
@Override
protected void configure()
{
protected void configure() {
bind(User.class).asEagerSingleton();
bind(OrderBook.class).asEagerSingleton();
bind(Persistence.class).asEagerSingleton();
@ -80,23 +79,19 @@ public class BitSquareModule extends AbstractModule
}
}
class NetworkParametersProvider implements Provider<NetworkParameters>
{
class NetworkParametersProvider implements Provider<NetworkParameters> {
private final String networkType;
@Inject
public NetworkParametersProvider(@Named("networkType") String networkType)
{
public NetworkParametersProvider(@Named("networkType") String networkType) {
this.networkType = networkType;
}
public NetworkParameters get()
{
public NetworkParameters get() {
NetworkParameters result = null;
switch (networkType)
{
switch (networkType) {
case WalletFacade.MAIN_NET:
result = MainNetParams.get();
break;

View File

@ -19,9 +19,11 @@ package io.bitsquare.di;
import com.google.inject.Injector;
import io.bitsquare.locale.Localisation;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javafx.fxml.FXMLLoader;
import javafx.util.Callback;
import org.slf4j.Logger;
@ -31,8 +33,7 @@ import org.slf4j.LoggerFactory;
* Guice support for fxml controllers
* Support caching. Speed up switches between UI screens.
*/
public class GuiceFXMLLoader
{
public class GuiceFXMLLoader {
private static final Logger log = LoggerFactory.getLogger(GuiceFXMLLoader.class);
private static Injector injector = null;
private FXMLLoader loader;
@ -40,26 +41,22 @@ public class GuiceFXMLLoader
private final URL url;
private Item item;
public static void setInjector(Injector injector)
{
public static void setInjector(Injector injector) {
GuiceFXMLLoader.injector = injector;
}
// TODO maybe add more sophisticated caching strategy with removal of rarely accessed items
private static final Map<URL, Item> cachedGUIItems = new HashMap<>();
public GuiceFXMLLoader(URL url)
{
public GuiceFXMLLoader(URL url) {
this(url, true);
}
public GuiceFXMLLoader(URL url, boolean useCaching)
{
public GuiceFXMLLoader(URL url, boolean useCaching) {
this.url = url;
isCached = useCaching && cachedGUIItems.containsKey(url);
if (!isCached)
{
if (!isCached) {
loader = new FXMLLoader(url, Localisation.getResourceBundle());
if (GuiceFXMLLoader.injector != null)
loader.setControllerFactory(new GuiceControllerFactory(GuiceFXMLLoader.injector));
@ -67,16 +64,12 @@ public class GuiceFXMLLoader
}
@SuppressWarnings("unchecked")
public <T> T load() throws java.io.IOException
{
if (isCached)
{
public <T> T load() throws java.io.IOException {
if (isCached) {
item = cachedGUIItems.get(url);
log.debug("loaded from cache " + url);
return (T) cachedGUIItems.get(url).view;
}
else
{
} else {
log.debug("load from disc " + url);
T result = loader.load();
item = new Item(result, loader.getController());
@ -86,19 +79,16 @@ public class GuiceFXMLLoader
}
@SuppressWarnings("unchecked")
public <T> T getController()
{
public <T> T getController() {
return (T) item.controller;
}
class Item<T>
{
class Item<T> {
final T view;
final T controller;
Item(T view, T controller)
{
Item(T view, T controller) {
this.view = view;
this.controller = controller;
}
@ -109,23 +99,20 @@ public class GuiceFXMLLoader
* A JavaFX controller factory for constructing controllers via Guice DI. To
* install this in the {@link javafx.fxml.FXMLLoader}, pass it as a parameter to
* {@link javafx.fxml.FXMLLoader#setControllerFactory(javafx.util.Callback)}.
* <p>
* <p/>
* Once set, make sure you do <b>not</b> use the static methods on
* {@link javafx.fxml.FXMLLoader} when creating your JavaFX node.
*/
class GuiceControllerFactory implements Callback<Class<?>, Object>
{
class GuiceControllerFactory implements Callback<Class<?>, Object> {
private final Injector injector;
public GuiceControllerFactory(Injector injector)
{
public GuiceControllerFactory(Injector injector) {
this.injector = injector;
}
@Override
public Object call(Class<?> aClass)
{
public Object call(Class<?> aClass) {
return injector.getInstance(aClass);
}
}

View File

@ -19,14 +19,14 @@ package io.bitsquare.gui;
import java.net.URL;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* If caching is used for loader we use the CachedViewController for turning the controller into sleep mode if not active and awake it at reactivation.
*/
public abstract class CachedViewController extends ViewController
{
public abstract class CachedViewController extends ViewController {
private static final Logger log = LoggerFactory.getLogger(CachedViewController.class);
/**
@ -38,8 +38,7 @@ public abstract class CachedViewController extends ViewController
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
root.sceneProperty().addListener((ov, oldValue, newValue) -> {
// we got removed from the scene
@ -54,8 +53,7 @@ public abstract class CachedViewController extends ViewController
* In caching controllers the terminate calls the deactivate method.
*/
@Override
public void terminate()
{
public void terminate() {
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
super.terminate();
@ -65,8 +63,7 @@ public abstract class CachedViewController extends ViewController
/**
* Used for deactivating resources (removing listeners, stopping timers or animations,...)
*/
public void deactivate()
{
public void deactivate() {
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
if (childController instanceof CachedViewController) ((CachedViewController) childController).deactivate();
}
@ -74,8 +71,7 @@ public abstract class CachedViewController extends ViewController
/**
* Used to activate resources (adding listeners, starting timers or animations,...)
*/
public void activate()
{
public void activate() {
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
if (childController instanceof CachedViewController) ((CachedViewController) childController).activate();
}

View File

@ -34,9 +34,11 @@ import io.bitsquare.storage.Persistence;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.user.User;
import io.bitsquare.util.AWTSystemTray;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
@ -47,7 +49,9 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.util.StringConverter;
import javax.inject.Inject;
import net.tomp2p.peers.PeerAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -58,8 +62,7 @@ import org.slf4j.LoggerFactory;
* We use a sequence of Platform.runLater cascaded calls to make the startup more smooth, otherwise the rendering is frozen for too long.
* Pre-loading of views is not implemented yet, and after a quick test it seemed that it does not give much improvements.
*/
public class MainController extends ViewController
{
public class MainController extends ViewController {
private static final Logger log = LoggerFactory.getLogger(MainController.class);
private static MainController INSTANCE;
@ -84,8 +87,7 @@ public class MainController extends ViewController
// Static
///////////////////////////////////////////////////////////////////////////////////////////
public static MainController GET_INSTANCE()
{
public static MainController GET_INSTANCE() {
return INSTANCE;
}
@ -95,8 +97,7 @@ public class MainController extends ViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private MainController(User user, WalletFacade walletFacade, MessageFacade messageFacade, TradeManager tradeManager, Persistence persistence)
{
private MainController(User user, WalletFacade walletFacade, MessageFacade messageFacade, TradeManager tradeManager, Persistence persistence) {
this.user = user;
this.walletFacade = walletFacade;
this.messageFacade = messageFacade;
@ -114,8 +115,7 @@ public class MainController extends ViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
Profiler.printMsgWithTime("MainController.initialize");
@ -123,8 +123,7 @@ public class MainController extends ViewController
}
@Override
public void terminate()
{
public void terminate() {
super.terminate();
}
@ -134,10 +133,8 @@ public class MainController extends ViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
switch (navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
switch (navigationItem) {
case HOME:
homeButton.fire();
break;
@ -168,29 +165,24 @@ public class MainController extends ViewController
// Startup Handlers
///////////////////////////////////////////////////////////////////////////////////////////
void onViewInitialized()
{
void onViewInitialized() {
Profiler.printMsgWithTime("MainController.onViewInitialized");
Platform.runLater(this::initFacades);
}
private void onFacadesInitialised()
{
private void onFacadesInitialised() {
Profiler.printMsgWithTime("MainController.onFacadesInitialised");
// never called on regtest
walletFacade.addDownloadListener(new WalletFacade.DownloadListener()
{
walletFacade.addDownloadListener(new WalletFacade.DownloadListener() {
@Override
public void progress(double percent)
{
public void progress(double percent) {
viewBuilder.loadingLabel.setText("Synchronise with network...");
if (viewBuilder.networkSyncPane == null)
viewBuilder.setShowNetworkSyncPane();
}
@Override
public void downloadComplete()
{
public void downloadComplete() {
viewBuilder.loadingLabel.setText("Synchronise with network done.");
if (viewBuilder.networkSyncPane != null)
viewBuilder.networkSyncPane.downloadComplete();
@ -201,21 +193,18 @@ public class MainController extends ViewController
Platform.runLater(this::addNavigation);
}
private void onNavigationAdded()
{
private void onNavigationAdded() {
Profiler.printMsgWithTime("MainController.onNavigationAdded");
Platform.runLater(this::loadContentView);
}
private void onContentViewLoaded()
{
private void onContentViewLoaded() {
Profiler.printMsgWithTime("MainController.onContentViewLoaded");
root.setId("main-view");
Platform.runLater(this::fadeOutSplash);
}
private void fadeOutSplash()
{
private void fadeOutSplash() {
Profiler.printMsgWithTime("MainController.fadeOutSplash");
Transitions.blurOutAndRemove(viewBuilder.splashVBox);
Transitions.fadeIn(viewBuilder.menuBar);
@ -228,8 +217,7 @@ public class MainController extends ViewController
///////////////////////////////////////////////////////////////////////////////////////////
//TODO make ordersButton also reacting to jump to pending tab
private void onTakeOfferRequested(String offerId, PeerAddress sender)
{
private void onTakeOfferRequested(String offerId, PeerAddress sender) {
final Button alertButton = new Button("", ImageUtil.getIconImageView(ImageUtil.MSG_ALERT));
alertButton.setId("nav-alert-button");
alertButton.relocate(36, 19);
@ -248,21 +236,17 @@ public class MainController extends ViewController
// Private startup methods
///////////////////////////////////////////////////////////////////////////////////////////
private void initFacades()
{
private void initFacades() {
Profiler.printMsgWithTime("MainController.initFacades");
messageFacade.init(new BootstrapListener()
{
messageFacade.init(new BootstrapListener() {
@Override
public void onCompleted()
{
public void onCompleted() {
messageFacadeInited = true;
if (walletFacadeInited) onFacadesInitialised();
}
@Override
public void onFailed(Throwable throwable)
{
public void onFailed(Throwable throwable) {
log.error(throwable.toString());
}
});
@ -273,8 +257,7 @@ public class MainController extends ViewController
});
}
private void addNavigation()
{
private void addNavigation() {
Profiler.printMsgWithTime("MainController.addNavigation");
homeButton = addNavButton(viewBuilder.leftNavPane, "Overview", NavigationItem.HOME);
buyButton = addNavButton(viewBuilder.leftNavPane, "Buy BTC", NavigationItem.BUY);
@ -306,8 +289,7 @@ public class MainController extends ViewController
Platform.runLater(this::onNavigationAdded);
}
private void loadContentView()
{
private void loadContentView() {
Profiler.printMsgWithTime("MainController.loadContentView");
NavigationItem selectedNavigationItem = (NavigationItem) persistence.read(this, "selectedNavigationItem");
if (selectedNavigationItem == null)
@ -323,8 +305,7 @@ public class MainController extends ViewController
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void loadViewFromNavButton(NavigationItem navigationItem)
{
private void loadViewFromNavButton(NavigationItem navigationItem) {
/* if (childController instanceof CachedViewController)
((CachedViewController) childController).deactivate();
@ -332,20 +313,17 @@ public class MainController extends ViewController
childController.terminate();*/
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
try
{
try {
final Node view = loader.load();
viewBuilder.contentPane.getChildren().setAll(view);
childController = loader.getController();
childController.setParentController(this);
} catch (IOException e)
{
} catch (IOException e) {
log.error("Loading view failed. " + navigationItem.getFxmlUrl());
}
}
private ToggleButton addNavButton(Pane parent, String title, NavigationItem navigationItem)
{
private ToggleButton addNavButton(Pane parent, String title, NavigationItem navigationItem) {
final Pane pane = new Pane();
pane.setPrefSize(50, 50);
final ToggleButton toggleButton = new ToggleButton("", ImageUtil.getIconImageView(navigationItem.getIcon()));
@ -353,8 +331,7 @@ public class MainController extends ViewController
toggleButton.setId("nav-button");
toggleButton.setPrefSize(50, 50);
toggleButton.setOnAction(e -> {
if (prevToggleButton != null)
{
if (prevToggleButton != null) {
((ImageView) (prevToggleButton.getGraphic())).setImage(prevToggleButtonIcon);
}
prevToggleButtonIcon = ((ImageView) (toggleButton.getGraphic())).getImage();
@ -379,18 +356,15 @@ public class MainController extends ViewController
return toggleButton;
}
private void addBalanceInfo(Pane parent)
{
private void addBalanceInfo(Pane parent) {
final TextField balanceTextField = new TextField();
balanceTextField.setEditable(false);
balanceTextField.setPrefWidth(110);
balanceTextField.setId("nav-balance-label");
balanceTextField.setText(BitSquareFormatter.formatCoinWithCode(walletFacade.getWalletBalance()));
walletFacade.addBalanceListener(new BalanceListener()
{
walletFacade.addBalanceListener(new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance)
{
public void onBalanceChanged(Coin balance) {
balanceTextField.setText(BitSquareFormatter.formatCoinWithCode(walletFacade.getWalletBalance()));
}
});
@ -407,25 +381,21 @@ public class MainController extends ViewController
parent.getChildren().add(vBox);
}
private void addAccountComboBox(Pane parent)
{
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>()
{
accountComboBox.setConverter(new StringConverter<BankAccount>() {
@Override
public String toString(BankAccount bankAccount)
{
public String toString(BankAccount bankAccount) {
return bankAccount.getAccountTitle();
}
@Override
public BankAccount fromString(String s)
{
public BankAccount fromString(String s) {
return null;
}
});
@ -453,8 +423,7 @@ public class MainController extends ViewController
}
class ViewBuilder
{
class ViewBuilder {
HBox leftNavPane, rightNavPane;
AnchorPane contentPane;
NetworkSyncPane networkSyncPane;
@ -466,8 +435,7 @@ class ViewBuilder
Label loadingLabel;
boolean showNetworkSyncPane;
void buildSplashScreen(BorderPane root, MainController controller)
{
void buildSplashScreen(BorderPane root, MainController controller) {
Profiler.printMsgWithTime("MainController.ViewBuilder.buildSplashScreen");
this.root = root;
@ -482,8 +450,7 @@ class ViewBuilder
Platform.runLater(() -> buildContentView(controller));
}
void buildContentView(MainController controller)
{
void buildContentView(MainController controller) {
Profiler.printMsgWithTime("MainController.ViewBuilder.buildContentView");
contentScreen = getContentScreen();
stackPane.getChildren().add(contentScreen);
@ -491,8 +458,7 @@ class ViewBuilder
Platform.runLater(controller::onViewInitialized);
}
AnchorPane getContentScreen()
{
AnchorPane getContentScreen() {
AnchorPane anchorPane = new AnchorPane();
anchorPane.setId("content-pane");
@ -524,16 +490,14 @@ class ViewBuilder
return anchorPane;
}
void setShowNetworkSyncPane()
{
void setShowNetworkSyncPane() {
showNetworkSyncPane = true;
if (contentScreen != null)
addNetworkSyncPane();
}
private void addNetworkSyncPane()
{
private void addNetworkSyncPane() {
networkSyncPane = new NetworkSyncPane();
networkSyncPane.setSpacing(10);
networkSyncPane.setPrefHeight(20);
@ -543,8 +507,7 @@ class ViewBuilder
contentScreen.getChildren().addAll(networkSyncPane);
}
VBox getSplashScreen()
{
VBox getSplashScreen() {
VBox splashVBox = new VBox();
splashVBox.setAlignment(Pos.CENTER);
splashVBox.setSpacing(10);
@ -569,8 +532,7 @@ class ViewBuilder
return splashVBox;
}
MenuBar getMenuBar()
{
MenuBar getMenuBar() {
MenuBar menuBar = new MenuBar();
// on mac we could place menu bar in the systems menu
// menuBar.setUseSystemMenuBar(true);

View File

@ -19,8 +19,7 @@ package io.bitsquare.gui;
import io.bitsquare.gui.util.ImageUtil;
public enum NavigationItem
{
public enum NavigationItem {
MAIN("/io/bitsquare/gui/MainView.fxml"),
HOME("/io/bitsquare/gui/home/HomeView.fxml", ImageUtil.HOME, ImageUtil.HOME_ACTIVE),
BUY("/io/bitsquare/gui/trade/BuyView.fxml", ImageUtil.NAV_BUY, ImageUtil.NAV_BUY_ACTIVE),
@ -51,30 +50,25 @@ public enum NavigationItem
private String icon;
private String activeIcon;
NavigationItem(String fxmlUrl, String icon, String activeIcon)
{
NavigationItem(String fxmlUrl, String icon, String activeIcon) {
this.fxmlUrl = fxmlUrl;
this.icon = icon;
this.activeIcon = activeIcon;
}
NavigationItem(String fxmlUrl)
{
NavigationItem(String fxmlUrl) {
this.fxmlUrl = fxmlUrl;
}
public String getFxmlUrl()
{
public String getFxmlUrl() {
return fxmlUrl;
}
public String getIcon()
{
public String getIcon() {
return icon;
}
public String getActiveIcon()
{
public String getActiveIcon() {
return activeIcon;
}
}

View File

@ -19,6 +19,7 @@ package io.bitsquare.gui;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
@ -28,8 +29,7 @@ import org.slf4j.LoggerFactory;
/**
* Base class for all controllers.
*/
public abstract class ViewController implements Initializable
{
public abstract class ViewController implements Initializable {
private static final Logger log = LoggerFactory.getLogger(ViewController.class);
protected ViewController childController;
@ -44,8 +44,7 @@ public abstract class ViewController implements Initializable
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
root.sceneProperty().addListener((ov, oldValue, newValue) -> {
// we got removed from the scene
@ -57,8 +56,7 @@ public abstract class ViewController implements Initializable
/**
* Called automatically when view gets removed. Used for house keeping (removing listeners, stopping timers or animations,...).
*/
public void terminate()
{
public void terminate() {
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
if (childController != null) childController.terminate();
}
@ -66,8 +64,7 @@ public abstract class ViewController implements Initializable
/**
* @param parentController Controller who has created this.getClass().getSimpleName() instance (via navigateToView/FXMLLoader).
*/
public void setParentController(ViewController parentController)
{
public void setParentController(ViewController parentController) {
log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " + parentController);
this.parentController = parentController;
}
@ -76,8 +73,7 @@ public abstract class ViewController implements Initializable
* @param navigationItem NavigationItem to be loaded.
* @return The ViewController of the loaded view.
*/
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
log.trace("Lifecycle: loadViewAndGetChildController " + this.getClass().getSimpleName() + " / navigationItem = " + navigationItem);
return null;
}

View File

@ -28,18 +28,22 @@ import io.bitsquare.msg.listeners.ArbitratorListener;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Persistence;
import io.bitsquare.user.Arbitrator;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javax.inject.Inject;
import net.tomp2p.peers.Number640;
import net.tomp2p.storage.Data;
@ -49,8 +53,7 @@ import net.tomp2p.storage.Data;
* import net.tomp2p.storage.Data;
*/
@SuppressWarnings({"ALL", "UnusedParameters"})
public class ArbitratorOverviewController extends CachedViewController implements ArbitratorListener
{
public class ArbitratorOverviewController extends CachedViewController implements ArbitratorListener {
private final Settings settings;
private final Persistence persistence;
@ -68,8 +71,7 @@ public class ArbitratorOverviewController extends CachedViewController implement
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorOverviewController(Settings settings, Persistence persistence, MessageFacade messageFacade)
{
public ArbitratorOverviewController(Settings settings, Persistence persistence, MessageFacade messageFacade) {
this.settings = settings;
this.persistence = persistence;
@ -85,8 +87,7 @@ public class ArbitratorOverviewController extends CachedViewController implement
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
loadViewAndGetChildController(NavigationItem.ARBITRATOR_PROFILE);
@ -94,20 +95,17 @@ public class ArbitratorOverviewController extends CachedViewController implement
}
@Override
public void terminate()
{
public void terminate() {
super.terminate();
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -117,25 +115,21 @@ public class ArbitratorOverviewController extends CachedViewController implement
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setParentController(ViewController parentController)
{
public void setParentController(ViewController parentController) {
super.setParentController(parentController);
}
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
try
{
try {
final Node view = loader.load();
arbitratorProfileController = loader.getController();
arbitratorProfileController.setParentController(this);
((Pane) root).getChildren().set(0, view);
return arbitratorProfileController;
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return null;
@ -147,40 +141,30 @@ public class ArbitratorOverviewController extends CachedViewController implement
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onArbitratorAdded(Data offerData, boolean success)
{
public void onArbitratorAdded(Data offerData, boolean success) {
}
@Override
public void onArbitratorsReceived(Map<Number640, Data> dataMap, boolean success)
{
if (success && dataMap != null)
{
public void onArbitratorsReceived(Map<Number640, Data> dataMap, boolean success) {
if (success && dataMap != null) {
allArbitrators.clear();
for (Data arbitratorData : dataMap.values())
{
try
{
for (Data arbitratorData : dataMap.values()) {
try {
Object arbitratorDataObject = arbitratorData.object();
if (arbitratorDataObject instanceof Arbitrator)
{
if (arbitratorDataObject instanceof Arbitrator) {
Arbitrator arbitrator = (Arbitrator) arbitratorDataObject;
allArbitrators.add(arbitrator);
}
} catch (ClassNotFoundException | IOException e)
{
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}
else
{
} else {
allArbitrators.clear();
}
if (!allArbitrators.isEmpty())
{
if (!allArbitrators.isEmpty()) {
index = 0;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileController.applyArbitrator(currentArbitrator);
@ -189,8 +173,7 @@ public class ArbitratorOverviewController extends CachedViewController implement
}
@Override
public void onArbitratorRemoved(Data data, boolean success)
{
public void onArbitratorRemoved(Data data, boolean success) {
}
@ -199,10 +182,8 @@ public class ArbitratorOverviewController extends CachedViewController implement
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onPrevious()
{
if (index > 0)
{
public void onPrevious() {
if (index > 0) {
index--;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileController.applyArbitrator(currentArbitrator);
@ -211,10 +192,8 @@ public class ArbitratorOverviewController extends CachedViewController implement
}
@FXML
public void onNext()
{
if (index < allArbitrators.size() - 1)
{
public void onNext() {
if (index < allArbitrators.size() - 1) {
index++;
currentArbitrator = allArbitrators.get(index);
arbitratorProfileController.applyArbitrator(currentArbitrator);
@ -223,15 +202,13 @@ public class ArbitratorOverviewController extends CachedViewController implement
}
@FXML
public void onSelect()
{
public void onSelect() {
settings.addAcceptedArbitrator(currentArbitrator);
persistence.write(settings);
}
@FXML
public void onClose()
{
public void onClose() {
Stage stage = (Stage) root.getScene().getWindow();
stage.close();
}
@ -241,8 +218,7 @@ public class ArbitratorOverviewController extends CachedViewController implement
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void checkButtonState()
{
private void checkButtonState() {
prevButton.setDisable(index < 1);
nextButton.setDisable(index == allArbitrators.size() - 1 || index == -1);
}

View File

@ -24,16 +24,18 @@ import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Persistence;
import io.bitsquare.user.Arbitrator;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javax.inject.Inject;
public class ArbitratorProfileController extends CachedViewController
{
public class ArbitratorProfileController extends CachedViewController {
private final Settings settings;
@ -52,8 +54,7 @@ public class ArbitratorProfileController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorProfileController(Settings settings, Persistence persistence)
{
public ArbitratorProfileController(Settings settings, Persistence persistence) {
this.settings = settings;
this.persistence = persistence;
@ -67,26 +68,22 @@ public class ArbitratorProfileController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@Override
public void terminate()
{
public void terminate() {
super.terminate();
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -96,14 +93,12 @@ public class ArbitratorProfileController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setParentController(ViewController parentController)
{
public void setParentController(ViewController parentController) {
super.setParentController(parentController);
}
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
return null;
}
@ -112,13 +107,10 @@ public class ArbitratorProfileController extends CachedViewController
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void applyArbitrator(Arbitrator arbitrator)
{
if (arbitrator != null)
{
public void applyArbitrator(Arbitrator arbitrator) {
if (arbitrator != null) {
String name = "";
switch (arbitrator.getIdType())
{
switch (arbitrator.getIdType()) {
case REAL_LIFE_ID:
name = "Name:";
break;

View File

@ -38,8 +38,10 @@ import io.bitsquare.user.Arbitrator;
import io.bitsquare.user.Reputation;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import java.net.URL;
import java.util.*;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.*;
@ -47,13 +49,14 @@ import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"ALL", "EmptyMethod", "UnusedParameters"})
public class ArbitratorRegistrationController extends CachedViewController
{
public class ArbitratorRegistrationController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(ArbitratorRegistrationController.class);
private final Persistence persistence;
@ -91,8 +94,7 @@ public class ArbitratorRegistrationController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private ArbitratorRegistrationController(Persistence persistence, WalletFacade walletFacade, MessageFacade messageFacade, User user)
{
private ArbitratorRegistrationController(Persistence persistence, WalletFacade walletFacade, MessageFacade messageFacade, User user) {
this.persistence = persistence;
this.walletFacade = walletFacade;
this.messageFacade = messageFacade;
@ -105,111 +107,92 @@ public class ArbitratorRegistrationController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
accordion.setExpandedPane(profileTitledPane);
Arbitrator persistedArbitrator = (Arbitrator) persistence.read(arbitrator);
if (persistedArbitrator != null)
{
if (persistedArbitrator != null) {
arbitrator.applyPersistedArbitrator(persistedArbitrator);
applyArbitrator();
}
else
{
} else {
languageList.add(LanguageUtil.getDefaultLanguageLocale());
languagesTextField.setText(BitSquareFormatter.languageLocalesToString(languageList));
}
languageComboBox.setItems(FXCollections.observableArrayList(LanguageUtil.getAllLanguageLocales()));
languageComboBox.setConverter(new StringConverter<Locale>()
{
languageComboBox.setConverter(new StringConverter<Locale>() {
@Override
public String toString(Locale locale)
{
public String toString(Locale locale) {
return locale.getDisplayLanguage();
}
@Override
public Locale fromString(String s)
{
public Locale fromString(String s) {
return null;
}
});
idTypeComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class))));
idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>()
{
idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() {
@Override
public String toString(Arbitrator.ID_TYPE item)
{
public String toString(Arbitrator.ID_TYPE item) {
return Localisation.get(item.toString());
}
@Override
public Arbitrator.ID_TYPE fromString(String s)
{
public Arbitrator.ID_TYPE fromString(String s) {
return null;
}
});
methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD.class))));
methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>()
{
methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() {
@Override
public String toString(Arbitrator.METHOD item)
{
public String toString(Arbitrator.METHOD item) {
return Localisation.get(item.toString());
}
@Override
public Arbitrator.METHOD fromString(String s)
{
public Arbitrator.METHOD fromString(String s) {
return null;
}
});
idVerificationsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class))));
idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>()
{
idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() {
@Override
public String toString(Arbitrator.ID_VERIFICATION item)
{
public String toString(Arbitrator.ID_VERIFICATION item) {
return Localisation.get(item.toString());
}
@Override
public Arbitrator.ID_VERIFICATION fromString(String s)
{
public Arbitrator.ID_VERIFICATION fromString(String s) {
return null;
}
});
}
@Override
public void terminate()
{
public void terminate() {
super.terminate();
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -219,14 +202,12 @@ public class ArbitratorRegistrationController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setParentController(ViewController parentController)
{
public void setParentController(ViewController parentController) {
super.setParentController(parentController);
}
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
return null;
}
@ -235,12 +216,10 @@ public class ArbitratorRegistrationController extends CachedViewController
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setEditMode(@SuppressWarnings("SameParameterValue") boolean isEditMode)
{
public void setEditMode(@SuppressWarnings("SameParameterValue") boolean isEditMode) {
this.isEditMode = isEditMode;
if (isEditMode)
{
if (isEditMode) {
saveProfileButton.setText("Save");
profileTitledPane.setCollapsible(false);
payCollateralTitledPane.setVisible(false);
@ -253,16 +232,13 @@ public class ArbitratorRegistrationController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onSelectIDType()
{
public void onSelectIDType() {
idType = idTypeComboBox.getSelectionModel().getSelectedItem();
if (idType != null)
{
if (idType != null) {
idTypeTextField.setText(Localisation.get(idType.toString()));
String name = "";
switch (idType)
{
switch (idType) {
case REAL_LIFE_ID:
name = "Name:";
break;
@ -280,11 +256,9 @@ public class ArbitratorRegistrationController extends CachedViewController
}
@FXML
public void onAddLanguage()
{
public void onAddLanguage() {
Locale item = languageComboBox.getSelectionModel().getSelectedItem();
if (!languageList.contains(item) && item != null)
{
if (!languageList.contains(item) && item != null) {
languageList.add(item);
languagesTextField.setText(BitSquareFormatter.languageLocalesToString(languageList));
languageComboBox.getSelectionModel().clearSelection();
@ -292,18 +266,15 @@ public class ArbitratorRegistrationController extends CachedViewController
}
@FXML
public void onClearLanguages()
{
public void onClearLanguages() {
languageList.clear();
languagesTextField.setText("");
}
@FXML
public void onAddMethod()
{
public void onAddMethod() {
Arbitrator.METHOD item = methodsComboBox.getSelectionModel().getSelectedItem();
if (!methodList.contains(item) && item != null)
{
if (!methodList.contains(item) && item != null) {
methodList.add(item);
methodsTextField.setText(BitSquareFormatter.arbitrationMethodsToString(methodList));
methodsComboBox.getSelectionModel().clearSelection();
@ -311,21 +282,17 @@ public class ArbitratorRegistrationController extends CachedViewController
}
@FXML
public void onClearMethods()
{
public void onClearMethods() {
methodList.clear();
methodsTextField.setText("");
}
@FXML
public void onAddIDVerification()
{
public void onAddIDVerification() {
Arbitrator.ID_VERIFICATION idVerification = idVerificationsComboBox.getSelectionModel().getSelectedItem();
if (idVerification != null)
{
if (!idVerificationList.contains(idVerification))
{
if (idVerification != null) {
if (!idVerificationList.contains(idVerification)) {
idVerificationList.add(idVerification);
idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString(idVerificationList));
}
@ -335,26 +302,20 @@ public class ArbitratorRegistrationController extends CachedViewController
}
@FXML
public void onClearIDVerifications()
{
public void onClearIDVerifications() {
idVerificationList.clear();
idVerificationsTextField.setText("");
}
@FXML
public void onSaveProfile()
{
public void onSaveProfile() {
arbitrator = getEditedArbitrator();
if (arbitrator != null)
{
if (arbitrator != null) {
persistence.write(arbitrator);
if (isEditMode)
{
if (isEditMode) {
close();
}
else
{
} else {
setupPayCollateralScreen();
accordion.setExpandedPane(payCollateralTitledPane);
}
@ -364,8 +325,7 @@ public class ArbitratorRegistrationController extends CachedViewController
}
@FXML
public void onPaymentDone()
{
public void onPaymentDone() {
//To change body of created methods use File | Settings | File Templates.
}
@ -374,14 +334,13 @@ public class ArbitratorRegistrationController extends CachedViewController
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupPayCollateralScreen()
{
private void setupPayCollateralScreen() {
infoLabel.setText("You need to pay 10 x the max. trading volume as collateral.\n\n" +
"That payment will be locked into a MultiSig fund and be refunded when you leave the arbitration pool.\n" +
"In case of fraud (collusion, not fulfilling the min. dispute quality requirements) you will lose your collateral.\n" +
"If you have a negative feedback from your clients you will lose a part of the collateral,\n" +
"depending on the overall relation of negative to positive ratings you received after a dispute resolution.\n\n" +
"Please pay in " + arbitrator.getMaxTradeVolume() * 10 + " BTC");
"That payment will be locked into a MultiSig fund and be refunded when you leave the arbitration pool.\n" +
"In case of fraud (collusion, not fulfilling the min. dispute quality requirements) you will lose your collateral.\n" +
"If you have a negative feedback from your clients you will lose a part of the collateral,\n" +
"depending on the overall relation of negative to positive ratings you received after a dispute resolution.\n\n" +
"Please pay in " + arbitrator.getMaxTradeVolume() * 10 + " BTC");
String collateralAddress = walletFacade.getRegistrationAddressEntry() != null ? walletFacade.getRegistrationAddressEntry().toString() : "";
@ -398,59 +357,48 @@ public class ArbitratorRegistrationController extends CachedViewController
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, balanceTextField, progressIndicator);
paymentDoneButton.setDisable(walletFacade.getArbitratorDepositBalance().isZero());
log.debug("getArbitratorDepositBalance " + walletFacade.getArbitratorDepositBalance());
walletFacade.getWallet().addEventListener(new WalletEventListener()
{
walletFacade.getWallet().addEventListener(new WalletEventListener() {
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
paymentDoneButton.setDisable(newBalance.isZero());
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
}
@Override
public void onReorganize(Wallet wallet)
{
public void onReorganize(Wallet wallet) {
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
{
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
}
@Override
public void onWalletChanged(Wallet wallet)
{
public void onWalletChanged(Wallet wallet) {
}
@Override
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
{
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
}
@Override
public void onKeysAdded(List<ECKey> keys)
{
public void onKeysAdded(List<ECKey> keys) {
}
});
}
private void applyArbitrator()
{
if (arbitrator != null)
{
private void applyArbitrator() {
if (arbitrator != null) {
String name = "";
switch (arbitrator.getIdType())
{
switch (arbitrator.getIdType()) {
case REAL_LIFE_ID:
name = "Name:";
break;
@ -484,16 +432,14 @@ public class ArbitratorRegistrationController extends CachedViewController
}
private Arbitrator getEditedArbitrator()
{
try
{
private Arbitrator getEditedArbitrator() {
try {
BitSquareValidator.textFieldsNotEmptyWithReset(nameTextField, idTypeTextField, languagesTextField, methodsTextField, idVerificationsTextField);
BitSquareValidator.textFieldsHasDoubleValueWithReset(maxTradeVolumeTextField,
passiveServiceFeeTextField,
minPassiveServiceFeeTextField,
arbitrationFeeTextField,
minArbitrationFeeTextField);
passiveServiceFeeTextField,
minPassiveServiceFeeTextField,
arbitrationFeeTextField,
minArbitrationFeeTextField);
String pubKeyAsHex = walletFacade.getArbitratorDepositAddressEntry().getPubKeyAsHexString();
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePublicKey());
@ -509,28 +455,26 @@ public class ArbitratorRegistrationController extends CachedViewController
String description = descriptionTextArea.getText();
return new Arbitrator(pubKeyAsHex,
messagePubKeyAsHex,
name,
idType,
languageList,
new Reputation(),
maxTradeVolume,
passiveServiceFee,
minPassiveServiceFee,
arbitrationFee,
minArbitrationFee,
methodList,
idVerificationList,
webUrl,
description);
} catch (BitSquareValidator.ValidationException e)
{
messagePubKeyAsHex,
name,
idType,
languageList,
new Reputation(),
maxTradeVolume,
passiveServiceFee,
minPassiveServiceFee,
arbitrationFee,
minArbitrationFee,
methodList,
idVerificationList,
webUrl,
description);
} catch (BitSquareValidator.ValidationException e) {
return null;
}
}
private void close()
{
private void close() {
Stage stage = (Stage) root.getScene().getWindow();
stage.close();
}

View File

@ -2,8 +2,8 @@
-fx-background-color: #ffffff;
}
#logo-sub-title-label{
-fx-font-weight: bold;
#logo-sub-title-label {
-fx-font-weight: bold;
-fx-font-size: 24;
}
@ -32,7 +32,6 @@
-fx-fill: red;
}
/* main nav */
#nav-button {
-fx-cursor: hand;
@ -55,7 +54,8 @@
-fx-font-weight: bold;
-fx-alignment: center;
}
#nav-account-combo-box .list-cell{
#nav-account-combo-box .list-cell {
-fx-alignment: center;
}
@ -89,7 +89,7 @@
-fx-cursor: hand;
}
#copy-icon .hover{
#copy-icon .hover {
-fx-fill: #0096c9;
-fx-cursor: hand;
}
@ -189,18 +189,17 @@
#form-group-label {
-fx-font-weight: bold;
-fx-font-size: 14;
-fx-text-fill:#111;
-fx-background-color:#f4f4f4;
-fx-text-fill: #111;
-fx-background-color: #f4f4f4;
}
#form-group-border {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #ddd, #ccc);
-fx-background-color:
-fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
@ -209,7 +208,6 @@
-fx-font-weight: bold;
}
/* tab pane */
.tab-pane .tab-label {
-fx-font-size: 15;
@ -247,8 +245,7 @@
-fx-background-insets: 0;
}
/* validation */
#validation-error {
-fx-text-fill: red;
-fx-text-fill: red;
}

View File

@ -20,9 +20,11 @@ package io.bitsquare.gui.components;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.ViewController;
import io.bitsquare.storage.Persistence;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.Node;
import javafx.scene.control.TabPane;
import org.slf4j.Logger;
@ -34,8 +36,7 @@ import org.slf4j.LoggerFactory;
*/
//TODO remove manual caching as its done now in loader
public class CachingTabPane extends TabPane
{
public class CachingTabPane extends TabPane {
private static final Logger log = LoggerFactory.getLogger(CachingTabPane.class);
private final List<TabInfo> tabInfoList = new ArrayList<>();
@ -48,10 +49,8 @@ public class CachingTabPane extends TabPane
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void initialize(ViewController parentController, Persistence persistence, String... tabContentFXMLUrls)
{
if (tabContentFXMLUrls.length == 0)
{
public void initialize(ViewController parentController, Persistence persistence, String... tabContentFXMLUrls) {
if (tabContentFXMLUrls.length == 0) {
throw new IllegalArgumentException("No tabContentFXMLUrls defined");
}
@ -72,12 +71,9 @@ public class CachingTabPane extends TabPane
getSelectionModel().select(selectedTabIndex);
}
public ViewController loadViewAndGetChildController(String fxmlView)
{
for (int i = 0; i < tabInfoList.size(); i++)
{
if (tabInfoList.get(i).url.equals(fxmlView))
{
public ViewController loadViewAndGetChildController(String fxmlView) {
for (int i = 0; i < tabInfoList.size(); i++) {
if (tabInfoList.get(i).url.equals(fxmlView)) {
// selection will cause loadView() call
getSelectionModel().select(i);
return currentController();
@ -86,8 +82,7 @@ public class CachingTabPane extends TabPane
throw new IllegalArgumentException("fxmlView not defined in tabContentFXMLUrlMap.");
}
public void setSelectedTabIndex(int selectedTabIndex)
{
public void setSelectedTabIndex(int selectedTabIndex) {
getSelectionModel().select(selectedTabIndex);
}
@ -96,19 +91,16 @@ public class CachingTabPane extends TabPane
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void loadView()
{
private void loadView() {
selectedTabIndex = getSelectionModel().getSelectedIndex();
TabInfo selectedTabInfo = tabInfoList.get(selectedTabIndex);
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(selectedTabInfo.url));
try
{
try {
Node view = loader.load();
selectedTabInfo.controller = loader.getController();
getSelectionModel().getSelectedItem().setContent(view);
} catch (IOException e)
{
} catch (IOException e) {
log.error(e.getMessage());
}
@ -117,19 +109,16 @@ public class CachingTabPane extends TabPane
persistence.write(parentController, "selectedTabIndex", selectedTabIndex);
}
private ViewController currentController()
{
private ViewController currentController() {
return tabInfoList.get(selectedTabIndex).controller;
}
}
class TabInfo
{
class TabInfo {
ViewController controller;
final String url;
TabInfo(String url)
{
TabInfo(String url) {
this.url = url;
}
}

View File

@ -21,20 +21,16 @@ package io.bitsquare.gui.components;
import javafx.scene.layout.Pane;
@SuppressWarnings("WeakerAccess")
public class HSpacer extends Pane
{
public HSpacer()
{
public class HSpacer extends Pane {
public HSpacer() {
}
public HSpacer(@SuppressWarnings("SameParameterValue") double width)
{
public HSpacer(@SuppressWarnings("SameParameterValue") double width) {
setPrefWidth(width);
}
@Override
protected double computePrefWidth(double width)
{
protected double computePrefWidth(double width) {
return getPrefWidth();
}
}

View File

@ -24,15 +24,13 @@ import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.util.Duration;
public class NetworkSyncPane extends HBox
{
public class NetworkSyncPane extends HBox {
private final ProgressBar networkSyncProgressBar;
private final Label networkSyncInfoLabel;
public NetworkSyncPane()
{
public NetworkSyncPane() {
networkSyncInfoLabel = new Label();
networkSyncInfoLabel.setText("Synchronize with network...");
networkSyncProgressBar = new ProgressBar();
@ -42,14 +40,12 @@ public class NetworkSyncPane extends HBox
getChildren().addAll(new HSpacer(5), networkSyncProgressBar, networkSyncInfoLabel);
}
public void setProgress(double percent)
{
public void setProgress(double percent) {
networkSyncProgressBar.setProgress(percent / 100.0);
networkSyncInfoLabel.setText("Synchronize with network: " + (int) percent + "%");
}
public void downloadComplete()
{
public void downloadComplete() {
networkSyncInfoLabel.setText("Sync with network: Done");
networkSyncProgressBar.setProgress(1);

View File

@ -19,14 +19,11 @@ package io.bitsquare.gui.components;
import javafx.scene.control.ScrollPane;
class NoFocusScrollPane extends ScrollPane
{
public NoFocusScrollPane()
{
class NoFocusScrollPane extends ScrollPane {
public NoFocusScrollPane() {
}
public void requestFocus()
{
public void requestFocus() {
// prevent focus
}
}

View File

@ -20,110 +20,93 @@ package io.bitsquare.gui.components;
import com.google.bitcoin.store.BlockStoreException;
import com.google.common.base.Throwables;
import io.bitsquare.BitSquare;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.Dialogs;
@SuppressWarnings({"SameParameterValue", "WeakerAccess"})
public class Popups
{
public class Popups {
// Information
public static void openInformationPopup(String title, String message)
{
public static void openInformationPopup(String title, String message) {
openInformationPopup(title, message, null);
}
public static void openInformationPopup(String title, String message, String masthead)
{
public static void openInformationPopup(String title, String message, String masthead) {
Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showInformation();
}
// Confirm
public static Action openConfirmPopup(String title, String message)
{
public static Action openConfirmPopup(String title, String message) {
return openConfirmPopup(title, message, null);
}
public static Action openConfirmPopup(String title, String message, String masthead)
{
public static Action openConfirmPopup(String title, String message, String masthead) {
List<Action> actions = new ArrayList<>();
actions.add(Dialog.Actions.OK);
actions.add(Dialog.Actions.CANCEL);
return openConfirmPopup(title, message, masthead, actions);
}
public static Action openConfirmPopup(String title, String message, String masthead, List<Action> actions)
{
public static Action openConfirmPopup(String title, String message, String masthead, List<Action> actions) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).actions(actions).showConfirm();
}
// Warning
public static void openWarningPopup(String message)
{
public static void openWarningPopup(String message) {
openWarningPopup("Warning", message, null);
}
public static void openWarningPopup(String title, String message)
{
public static void openWarningPopup(String title, String message) {
openWarningPopup(title, message, null);
}
public static void openWarningPopup(String title, String message, String masthead)
{
public static void openWarningPopup(String title, String message, String masthead) {
Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showWarning();
}
// Error
public static Action openErrorPopup(String message)
{
public static Action openErrorPopup(String message) {
return openErrorPopup("Error", message);
}
public static Action openErrorPopup(String title, String message)
{
public static Action openErrorPopup(String title, String message) {
return openErrorPopup(title, message, null);
}
public static Action openErrorPopup(String title, String message, String masthead)
{
public static Action openErrorPopup(String title, String message, String masthead) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showError();
}
// Exception
public static Action openExceptionPopup(Throwable throwable)
{
public static Action openExceptionPopup(Throwable throwable) {
return openExceptionPopup(throwable, "Exception", "That should not have happened...");
}
public static Action openExceptionPopup(Throwable throwable, String title, String message)
{
public static Action openExceptionPopup(Throwable throwable, String title, String message) {
return openExceptionPopup(throwable, title, message, null);
}
public static Action openExceptionPopup(Throwable throwable, String title, String message, String masthead)
{
public static Action openExceptionPopup(Throwable throwable, String title, String message, String masthead) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showException(throwable);
}
// Support handling of uncaught exception from any thread (also non gui thread)
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public static void handleUncaughtExceptions(Throwable throwable)
{
public static void handleUncaughtExceptions(Throwable throwable) {
// while dev
throwable.printStackTrace();
Runnable runnable = () -> {
if (Throwables.getRootCause(throwable) instanceof BlockStoreException)
{
if (Throwables.getRootCause(throwable) instanceof BlockStoreException) {
Action response = Popups.openErrorPopup("Application already running", "This application is already running and cannot be started twice.", "");
if (response == Dialog.Actions.OK) Platform.exit();
}
else
{
} else {
Action response = Popups.openExceptionPopup(throwable, "Exception", "", "A critical error has occurred.\nPlease copy the exception details and send a bug report to bugs@bitsquare.io.");
if (response == Dialog.Actions.OK) Platform.exit();
}
@ -134,13 +117,11 @@ public class Popups
}
// custom
public static void openInsufficientMoneyPopup()
{
public static void openInsufficientMoneyPopup() {
openWarningPopup("Not enough money available", "There is not enough money available. Please pay in first to your wallet.", null);
}
public static Action openRegistrationMissingPopup(String title, String message, String masthead, List<Dialogs.CommandLink> commandLinks, int selectedIndex)
{
public static Action openRegistrationMissingPopup(String title, String message, String masthead, List<Dialogs.CommandLink> commandLinks, int selectedIndex) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showCommandLinks(commandLinks.get(selectedIndex), commandLinks);
}
}

View File

@ -20,21 +20,17 @@ package io.bitsquare.gui.components;
import javafx.scene.layout.Pane;
public class VSpacer extends Pane
{
public VSpacer()
{
public class VSpacer extends Pane {
public VSpacer() {
}
@SuppressWarnings("SameParameterValue")
public VSpacer(double height)
{
public VSpacer(double height) {
setPrefHeight(height);
}
@Override
protected double computePrefHeight(double width)
{
protected double computePrefHeight(double width) {
return getPrefHeight();
}
}

View File

@ -40,8 +40,7 @@ import org.slf4j.LoggerFactory;
* </p>
*/
@Deprecated
public class ValidatedTextField extends TextField
{
public class ValidatedTextField extends TextField {
private static final Logger log = LoggerFactory.getLogger(ValidatedTextField.class);
private final BooleanProperty invalid = new SimpleBooleanProperty(false);
@ -51,8 +50,7 @@ public class ValidatedTextField extends TextField
private Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
public ValidatedTextField()
{
public ValidatedTextField() {
super();
this.mask = new SimpleStringProperty("^[0-9.,]*$");
this.minLength = new SimpleIntegerProperty(1);
@ -61,13 +59,11 @@ public class ValidatedTextField extends TextField
bind();
}
public ValidatedTextField(String mask, int minLength, int maxLength, boolean nullable)
{
public ValidatedTextField(String mask, int minLength, int maxLength, boolean nullable) {
this(mask, minLength, maxLength, nullable, null);
}
public ValidatedTextField(String mask, int minLength, int maxLength, boolean nullable, String string)
{
public ValidatedTextField(String mask, int minLength, int maxLength, boolean nullable, String string) {
super(string);
this.mask = new SimpleStringProperty(mask);
this.minLength = new SimpleIntegerProperty(minLength);
@ -76,101 +72,78 @@ public class ValidatedTextField extends TextField
bind();
}
public ReadOnlyBooleanProperty invalidProperty()
{
public ReadOnlyBooleanProperty invalidProperty() {
return invalid;
}
public ReadOnlyStringProperty maskProperty()
{
public ReadOnlyStringProperty maskProperty() {
return mask;
}
public ReadOnlyIntegerProperty minLengthProperty()
{
public ReadOnlyIntegerProperty minLengthProperty() {
return minLength;
}
public ReadOnlyIntegerProperty maxLengthProperty()
{
public ReadOnlyIntegerProperty maxLengthProperty() {
return maxLength;
}
public boolean isInvalid()
{
public boolean isInvalid() {
return invalid.get();
}
public String getMask()
{
public String getMask() {
return mask.get();
}
public void setMask(String mask)
{
public void setMask(String mask) {
this.mask.set(mask);
}
public int getMinLength()
{
public int getMinLength() {
return minLength.get();
}
public void setMinLength(int minLength)
{
public void setMinLength(int minLength) {
this.minLength.set(minLength);
}
public int getMaxLength()
{
public int getMaxLength() {
return maxLength.get();
}
public void setMaxLength(int maxLength)
{
public void setMaxLength(int maxLength) {
this.maxLength.set(maxLength);
}
public Effect getInvalidEffect()
{
public Effect getInvalidEffect() {
return this.invalidEffect;
}
public void setInvalidEffect(Effect effect)
{
public void setInvalidEffect(Effect effect) {
this.invalidEffect = effect;
}
private void bind()
{
private void bind() {
this.invalid.bind(maskCheck().or(minLengthCheck()));
this.textProperty().addListener(new ChangeListener<String>()
{
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())
{
public void changed(ObservableValue<? extends String> ov, String t, String t1) {
if (textProperty().get() != null && textProperty().get().length() > maxLength.get()) {
setText(t);
}
}
});
this.invalid.addListener(new ChangeListener<Boolean>()
{
this.invalid.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1)
{
if (t ^ t1)
{
if (t1)
{
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
{
} else {
// setStyle("-fx-font-weight: normal; -fx-text-fill: inherit;");
setEffect(null);
}
@ -180,49 +153,40 @@ public class ValidatedTextField extends TextField
});
}
private BooleanBinding maskCheck()
{
return new BooleanBinding()
{
private BooleanBinding maskCheck() {
return new BooleanBinding() {
{
super.bind(textProperty(), mask);
}
@Override
protected boolean computeValue()
{
protected boolean computeValue() {
return (textProperty().get() != null) ? !textProperty().get().matches(mask.get()) : false;
}
};
}
private BooleanBinding minLengthCheck()
{
return new BooleanBinding()
{
private BooleanBinding minLengthCheck() {
return new BooleanBinding() {
{
super.bind(textProperty(), minLength);
}
@Override
protected boolean computeValue()
{
protected boolean computeValue() {
return (textProperty().get() != null) ? textProperty().get().length() < minLength.get() : false;
}
};
}
private BooleanBinding maxLengthCheck()
{
return new BooleanBinding()
{
private BooleanBinding maxLengthCheck() {
return new BooleanBinding() {
{
super.bind(textProperty(), maxLength);
}
@Override
protected boolean computeValue()
{
protected boolean computeValue() {
return textProperty().get().length() > maxLength.get();
}
};

View File

@ -38,11 +38,10 @@ import org.slf4j.LoggerFactory;
* TextField with validation support. Validation is executed on the Validator object.
* In case of a invalid result we display a error message with a PopOver.
* The position is derived from the textField or if set from the errorPopupLayoutReference object.
* <p>
* <p/>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
public class ValidatingTextField extends TextField
{
public class ValidatingTextField extends TextField {
private static final Logger log = LoggerFactory.getLogger(ValidatingTextField.class);
private static PopOver popOver;
@ -59,8 +58,7 @@ public class ValidatingTextField extends TextField
// Static
///////////////////////////////////////////////////////////////////////////////////////////
public static void hidePopover()
{
public static void hidePopover() {
if (popOver != null)
popOver.hide();
}
@ -70,8 +68,7 @@ public class ValidatingTextField extends TextField
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public ValidatingTextField()
{
public ValidatingTextField() {
super();
setupListeners();
@ -82,8 +79,7 @@ public class ValidatingTextField extends TextField
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void reValidate()
{
public void reValidate() {
validate(getText());
}
@ -92,16 +88,14 @@ public class ValidatingTextField extends TextField
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setNumberValidator(NumberValidator numberValidator)
{
public void setNumberValidator(NumberValidator numberValidator) {
this.numberValidator = numberValidator;
}
/**
* @param errorPopupLayoutReference The node used as reference for positioning
*/
public void setErrorPopupLayoutReference(Region errorPopupLayoutReference)
{
public void setErrorPopupLayoutReference(Region errorPopupLayoutReference) {
this.errorPopupLayoutReference = errorPopupLayoutReference;
}
@ -110,13 +104,11 @@ public class ValidatingTextField extends TextField
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public boolean getIsValid()
{
public boolean getIsValid() {
return isValid.get();
}
public BooleanProperty isValidProperty()
{
public BooleanProperty isValidProperty() {
return isValid;
}
@ -125,8 +117,7 @@ public class ValidatingTextField extends TextField
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupListeners()
{
private void setupListeners() {
sceneProperty().addListener((ov, oldValue, newValue) -> {
// we got removed from the scene
// lets hide an open popup
@ -135,8 +126,7 @@ public class ValidatingTextField extends TextField
});
textProperty().addListener((ov, oldValue, newValue) -> {
if (numberValidator != null)
{
if (numberValidator != null) {
if (!validateOnFocusOut)
validate(newValue);
else
@ -152,27 +142,20 @@ public class ValidatingTextField extends TextField
isValid.addListener((ov, oldValue, newValue) -> applyEffect(newValue));
}
private void validate(String input)
{
if (input != null)
{
private void validate(String input) {
if (input != null) {
NumberValidator.ValidationResult validationResult = numberValidator.validate(input);
isValid.set(validationResult.isValid);
applyErrorMessage(validationResult);
}
}
private void applyErrorMessage(NumberValidator.ValidationResult validationResult)
{
if (validationResult.isValid)
{
if (popOver != null)
{
private void applyErrorMessage(NumberValidator.ValidationResult validationResult) {
if (validationResult.isValid) {
if (popOver != null) {
popOver.hide();
}
}
else
{
} else {
if (popOver == null)
createErrorPopOver(validationResult.errorMessage);
else
@ -182,23 +165,18 @@ public class ValidatingTextField extends TextField
}
}
private void applyEffect(boolean isValid)
{
private void applyEffect(boolean isValid) {
setEffect(isValid ? null : invalidEffect);
}
private Point2D getErrorPopupPosition()
{
private Point2D getErrorPopupPosition() {
Window window = getScene().getWindow();
Point2D point;
double x;
if (errorPopupLayoutReference == null)
{
if (errorPopupLayoutReference == null) {
point = localToScene(0, 0);
x = point.getX() + window.getX() + getWidth() + 20;
}
else
{
} else {
point = errorPopupLayoutReference.localToScene(0, 0);
x = point.getX() + window.getX() + errorPopupLayoutReference.getWidth() + 20;
}
@ -206,13 +184,11 @@ public class ValidatingTextField extends TextField
return new Point2D(x, y);
}
private static void setErrorMessage(String errorMessage)
{
private static void setErrorMessage(String errorMessage) {
((Label) popOver.getContentNode()).setText(errorMessage);
}
private static void createErrorPopOver(String errorMessage)
{
private static void createErrorPopOver(String errorMessage) {
Label errorLabel = new Label(errorMessage);
errorLabel.setId("validation-error");
errorLabel.setPadding(new Insets(0, 10, 0, 10));

View File

@ -24,10 +24,12 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.BitSquare;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BitSquareFormatter;
import java.awt.Desktop;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
@ -43,8 +45,7 @@ import org.controlsfx.control.PopOver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AddressTextField extends AnchorPane
{
public class AddressTextField extends AnchorPane {
private static final Logger log = LoggerFactory.getLogger(AddressTextField.class);
private final Label copyIcon;
@ -57,8 +58,7 @@ public class AddressTextField extends AnchorPane
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public AddressTextField()
{
public AddressTextField() {
addressLabel = new Label();
addressLabel.setFocusTraversable(false);
addressLabel.setId("address-label");
@ -69,8 +69,7 @@ public class AddressTextField extends AnchorPane
Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
copyIcon.setOnMouseClicked(e -> {
if (address != null && address.length() > 0)
{
if (address != null && address.length() > 0) {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putString(address);
@ -85,8 +84,7 @@ public class AddressTextField extends AnchorPane
AwesomeDude.setIcon(qrCode, AwesomeIcon.QRCODE);
Tooltip.install(qrCode, new Tooltip("Show QR code for this address"));
qrCode.setOnMouseClicked(e -> {
if (address != null && address.length() > 0)
{
if (address != null && address.length() > 0) {
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.withSize(300, 220)
@ -119,12 +117,10 @@ public class AddressTextField extends AnchorPane
getChildren().addAll(addressLabel, copyIcon, qrCode);
addressLabel.setOnMouseClicked(mouseEvent -> {
try
{
try {
if (address != null)
Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
} catch (IOException e)
{
} catch (IOException e) {
log.warn(e.getMessage());
Popups.openWarningPopup("Opening wallet app failed", "Perhaps you don't have one installed?");
}
@ -136,14 +132,12 @@ public class AddressTextField extends AnchorPane
// Getters/Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setAddress(String address)
{
public void setAddress(String address) {
this.address = address;
addressLabel.setText(address);
}
public void setAmountToPay(String amountToPay)
{
public void setAmountToPay(String amountToPay) {
this.amountToPay = amountToPay;
}
@ -151,8 +145,7 @@ public class AddressTextField extends AnchorPane
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private String getBitcoinURI()
{
private String getBitcoinURI() {
Coin d = BitSquareFormatter.parseToCoin(amountToPay);
return BitcoinURI.convertToBitcoinURI(address, BitSquareFormatter.parseToCoin(amountToPay), BitSquare.getAppName(), null);
}

View File

@ -30,8 +30,7 @@ import javafx.scene.layout.AnchorPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BalanceTextField extends AnchorPane
{
public class BalanceTextField extends AnchorPane {
private static final Logger log = LoggerFactory.getLogger(BalanceTextField.class);
private final TextField balanceTextField;
@ -48,8 +47,7 @@ public class BalanceTextField extends AnchorPane
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public BalanceTextField()
{
public BalanceTextField() {
balanceTextField = new TextField();
balanceTextField.setFocusTraversable(false);
balanceTextField.setEditable(false);
@ -77,30 +75,24 @@ public class BalanceTextField extends AnchorPane
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setAddress(Address address)
{
public void setAddress(Address address) {
this.address = address;
}
public void setWalletFacade(WalletFacade walletFacade)
{
public void setWalletFacade(WalletFacade walletFacade) {
this.walletFacade = walletFacade;
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(address)
{
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(address) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence)
{
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(confidence);
}
});
updateConfidence(walletFacade.getConfidenceForAddress(address));
balanceListener = walletFacade.addBalanceListener(new BalanceListener(address)
{
balanceListener = walletFacade.addBalanceListener(new BalanceListener(address) {
@Override
public void onBalanceChanged(Coin balance)
{
public void onBalanceChanged(Coin balance) {
updateBalance(balance);
}
});
@ -108,8 +100,7 @@ public class BalanceTextField extends AnchorPane
}
// TODO not called yet...
public void cleanup()
{
public void cleanup() {
walletFacade.removeConfidenceListener(confidenceListener);
walletFacade.removeBalanceListener(balanceListener);
}
@ -119,8 +110,7 @@ public class BalanceTextField extends AnchorPane
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public Coin getBalance()
{
public Coin getBalance() {
return balance;
}
@ -129,12 +119,9 @@ public class BalanceTextField extends AnchorPane
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void updateConfidence(TransactionConfidence confidence)
{
if (confidence != null)
{
switch (confidence.getConfidenceType())
{
private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) {
switch (confidence.getConfidenceType()) {
case UNKNOWN:
progressIndicatorTooltip.setText("Unknown transaction status");
progressIndicator.setProgress(0);
@ -153,8 +140,7 @@ public class BalanceTextField extends AnchorPane
break;
}
if (progressIndicator.getProgress() != 0)
{
if (progressIndicator.getProgress() != 0) {
progressIndicator.setVisible(true);
AnchorPane.setRightAnchor(progressIndicator, 0.0);
AnchorPane.setRightAnchor(balanceTextField, 35.0);
@ -162,11 +148,9 @@ public class BalanceTextField extends AnchorPane
}
}
private void updateBalance(Coin balance)
{
private void updateBalance(Coin balance) {
this.balance = balance;
if (balance != null)
{
if (balance != null) {
//TODO use BitSquareFormatter
balanceTextField.setText(balance.toFriendlyString());
}

View File

@ -60,30 +60,29 @@ import javafx.scene.control.Skin;
* <p>
* ProgressIndicator sets focusTraversable to false.
* </p>
* <p>
* <p>
* <p/>
* <p/>
* This first example creates a ProgressIndicator with an indeterminate value :
* <pre><code>
* import javafx.scene.control.ProgressIndicator;
* ProgressIndicator p1 = new ProgressIndicator();
* </code></pre>
* <p>
* <p>
* <p/>
* <p/>
* This next example creates a ProgressIndicator which is 25% complete :
* <pre><code>
* import javafx.scene.control.ProgressIndicator;
* ProgressIndicator p2 = new ProgressIndicator();
* p2.setProgress(0.25F);
* </code></pre>
* <p>
* <p/>
* Implementation of ProgressIndicator According to JavaFX UI Control API Specification
*
* @since JavaFX 2.0
*/
@SuppressWarnings({"SameParameterValue", "WeakerAccess"})
public class ConfidenceProgressIndicator extends Control
{
public class ConfidenceProgressIndicator extends Control {
/**
* Value for progress indicating that the progress is indeterminate.
@ -99,7 +98,7 @@ public class ConfidenceProgressIndicator extends Control
**************************************************************************/
/**
* Initialize the style class to 'progress-indicator'.
* <p>
* <p/>
* This is the selector class from which CSS can be used to style
* this control.
*/
@ -137,8 +136,7 @@ public class ConfidenceProgressIndicator extends Control
/**
* Creates a new indeterminate ProgressIndicator.
*/
public ConfidenceProgressIndicator()
{
public ConfidenceProgressIndicator() {
this(INDETERMINATE_PROGRESS);
}
@ -146,8 +144,7 @@ public class ConfidenceProgressIndicator extends Control
* Creates a new ProgressIndicator with the given progress value.
*/
@SuppressWarnings("unchecked")
public ConfidenceProgressIndicator(double progress)
{
public ConfidenceProgressIndicator(double progress) {
// focusTraversable is styleable through css. Calling setFocusTraversable
// makes it look to css like the user set the value and css will not
// override. Initializing focusTraversable by calling applyStyle with null
@ -162,30 +159,23 @@ public class ConfidenceProgressIndicator extends Control
pseudoClassStateChanged(PSEUDO_CLASS_DETERMINATE, c != 0);
}
public final boolean isIndeterminate()
{
public final boolean isIndeterminate() {
return indeterminate == null || indeterminate.get();
}
private void setIndeterminate(boolean value)
{
private void setIndeterminate(boolean value) {
indeterminatePropertyImpl().set(value);
}
public final ReadOnlyBooleanProperty indeterminateProperty()
{
public final ReadOnlyBooleanProperty indeterminateProperty() {
return indeterminatePropertyImpl().getReadOnlyProperty();
}
private ReadOnlyBooleanWrapper indeterminatePropertyImpl()
{
if (indeterminate == null)
{
indeterminate = new ReadOnlyBooleanWrapper(true)
{
private ReadOnlyBooleanWrapper indeterminatePropertyImpl() {
if (indeterminate == null) {
indeterminate = new ReadOnlyBooleanWrapper(true) {
@Override
protected void invalidated()
{
protected void invalidated() {
final boolean active = get();
pseudoClassStateChanged(PSEUDO_CLASS_INDETERMINATE, active);
pseudoClassStateChanged(PSEUDO_CLASS_DETERMINATE, !active);
@ -193,15 +183,13 @@ public class ConfidenceProgressIndicator extends Control
@Override
public Object getBean()
{
public Object getBean() {
return ConfidenceProgressIndicator.this;
}
@Override
public String getName()
{
public String getName() {
return "indeterminate";
}
};
@ -217,8 +205,7 @@ public class ConfidenceProgressIndicator extends Control
* ************************************************************************
*/
public final double getProgress()
{
public final double getProgress() {
return progress == null ? INDETERMINATE_PROGRESS : progress.get();
}
@ -230,34 +217,27 @@ public class ConfidenceProgressIndicator extends Control
* ************************************************************************
*/
public final void setProgress(double value)
{
public final void setProgress(double value) {
progressProperty().set(value);
}
public final DoubleProperty progressProperty()
{
if (progress == null)
{
progress = new DoublePropertyBase(-1.0)
{
public final DoubleProperty progressProperty() {
if (progress == null) {
progress = new DoublePropertyBase(-1.0) {
@Override
protected void invalidated()
{
protected void invalidated() {
setIndeterminate(getProgress() < 0.0);
}
@Override
public Object getBean()
{
public Object getBean() {
return ConfidenceProgressIndicator.this;
}
@Override
public String getName()
{
public String getName() {
return "progress";
}
};
@ -270,8 +250,7 @@ public class ConfidenceProgressIndicator extends Control
*/
@Override
protected Skin<?> createDefaultSkin()
{
protected Skin<?> createDefaultSkin() {
return new ConfidenceProgressIndicatorSkin(this);
}
@ -284,8 +263,7 @@ public class ConfidenceProgressIndicator extends Control
@Deprecated
@Override
@SuppressWarnings("deprecation")
protected /*do not make final*/ Boolean impl_cssGetFocusTraversableInitialValue()
{
protected /*do not make final*/ Boolean impl_cssGetFocusTraversableInitialValue() {
return Boolean.FALSE;
}

View File

@ -43,10 +43,10 @@ package io.bitsquare.gui.components.confidence.behavior;
import com.sun.javafx.scene.control.behavior.BehaviorBase;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import java.util.Collections;
public class ConfidenceProgressIndicatorBehavior<C extends ConfidenceProgressIndicator> extends BehaviorBase<C>
{
public class ConfidenceProgressIndicatorBehavior<C extends ConfidenceProgressIndicator> extends BehaviorBase<C> {
/**
* ************************************************************************
@ -56,8 +56,7 @@ public class ConfidenceProgressIndicatorBehavior<C extends ConfidenceProgressInd
* ************************************************************************
*/
public ConfidenceProgressIndicatorBehavior(final C progress)
{
public ConfidenceProgressIndicatorBehavior(final C progress) {
super(progress, Collections.emptyList());
}
}

View File

@ -48,9 +48,11 @@ import com.sun.javafx.css.converters.SizeConverter;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.components.confidence.behavior.ConfidenceProgressIndicatorBehavior;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
@ -78,8 +80,7 @@ import javafx.scene.transform.Scale;
import javafx.util.Duration;
@SuppressWarnings({"WeakerAccess", "SameReturnValue"})
public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<ConfidenceProgressIndicator, ConfidenceProgressIndicatorBehavior<ConfidenceProgressIndicator>>
{
public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<ConfidenceProgressIndicator, ConfidenceProgressIndicatorBehavior<ConfidenceProgressIndicator>> {
/**
* ************************************************************************
@ -105,36 +106,30 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* The number of segments in the spinner.
*/
private final IntegerProperty indeterminateSegmentCount = new StyleableIntegerProperty(8)
{
private final IntegerProperty indeterminateSegmentCount = new StyleableIntegerProperty(8) {
@Override
protected void invalidated()
{
if (spinner != null)
{
protected void invalidated() {
if (spinner != null) {
spinner.rebuild();
}
}
@Override
public Object getBean()
{
public Object getBean() {
return ConfidenceProgressIndicatorSkin.this;
}
@Override
public String getName()
{
public String getName() {
return "indeterminateSegmentCount";
}
@Override
public CssMetaData<ConfidenceProgressIndicator, Number> getCssMetaData()
{
public CssMetaData<ConfidenceProgressIndicator, Number> getCssMetaData() {
return StyleableProperties.INDETERMINATE_SEGMENT_COUNT;
}
};
@ -142,35 +137,29 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* True if the progress indicator should rotate as well as animate opacity.
*/
private final BooleanProperty spinEnabled = new StyleableBooleanProperty(false)
{
private final BooleanProperty spinEnabled = new StyleableBooleanProperty(false) {
@Override
protected void invalidated()
{
if (spinner != null)
{
protected void invalidated() {
if (spinner != null) {
spinner.setSpinEnabled(get());
}
}
@Override
public CssMetaData<ConfidenceProgressIndicator, Boolean> getCssMetaData()
{
public CssMetaData<ConfidenceProgressIndicator, Boolean> getCssMetaData() {
return StyleableProperties.SPIN_ENABLED;
}
@Override
public Object getBean()
{
public Object getBean() {
return ConfidenceProgressIndicatorSkin.this;
}
@Override
public String getName()
{
public String getName() {
return "spinEnabled";
}
};
@ -180,47 +169,39 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* The colour of the progress segment.
*/
private final ObjectProperty<Paint> progressColor = new StyleableObjectProperty<Paint>(null)
{
private final ObjectProperty<Paint> progressColor = new StyleableObjectProperty<Paint>(null) {
@Override
public void set(Paint newProgressColor)
{
public void set(Paint newProgressColor) {
final Paint color = (newProgressColor instanceof Color) ? newProgressColor : null;
super.set(color);
}
@Override
protected void invalidated()
{
if (spinner != null)
{
protected void invalidated() {
if (spinner != null) {
spinner.setFillOverride(get());
}
if (determinateIndicator != null)
{
if (determinateIndicator != null) {
determinateIndicator.setFillOverride(get());
}
}
@Override
public Object getBean()
{
public Object getBean() {
return ConfidenceProgressIndicatorSkin.this;
}
@Override
public String getName()
{
public String getName() {
return "progressColorProperty";
}
@Override
public CssMetaData<ConfidenceProgressIndicator, Paint> getCssMetaData()
{
public CssMetaData<ConfidenceProgressIndicator, Paint> getCssMetaData() {
return StyleableProperties.PROGRESS_COLOR;
}
};
@ -234,33 +215,25 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* ************************************************************************
*/
@SuppressWarnings("deprecation")
public ConfidenceProgressIndicatorSkin(ConfidenceProgressIndicator control)
{
public ConfidenceProgressIndicatorSkin(ConfidenceProgressIndicator control) {
super(control, new ConfidenceProgressIndicatorBehavior<>(control));
InvalidationListener indeterminateListener = valueModel -> initialize();
control.indeterminateProperty().addListener(indeterminateListener);
InvalidationListener visibilityListener = new InvalidationListener()
{
InvalidationListener visibilityListener = new InvalidationListener() {
@Override
public void invalidated(Observable valueModel)
{
if (getSkinnable().isIndeterminate() && timelineNulled && spinner == null)
{
public void invalidated(Observable valueModel) {
if (getSkinnable().isIndeterminate() && timelineNulled && spinner == null) {
timelineNulled = false;
spinner = new IndeterminateSpinner(getSkinnable(), ConfidenceProgressIndicatorSkin.this, spinEnabled.get(), progressColor.get());
getChildren().add(spinner);
}
if (spinner != null)
{
if (getSkinnable().impl_isTreeVisible() && getSkinnable().getScene() != null)
{
if (spinner != null) {
if (getSkinnable().impl_isTreeVisible() && getSkinnable().getScene() != null) {
spinner.indeterminateTimeline.play();
}
else
{
} else {
spinner.indeterminateTimeline.pause();
getChildren().remove(spinner);
spinner = null;
@ -272,30 +245,22 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
control.visibleProperty().addListener(visibilityListener);
control.parentProperty().addListener(visibilityListener);
InvalidationListener sceneListener = new InvalidationListener()
{
InvalidationListener sceneListener = new InvalidationListener() {
@Override
public void invalidated(Observable valueModel)
{
if (spinner != null)
{
if (getSkinnable().getScene() == null)
{
public void invalidated(Observable valueModel) {
if (spinner != null) {
if (getSkinnable().getScene() == null) {
spinner.indeterminateTimeline.pause();
getChildren().remove(spinner);
spinner = null;
timelineNulled = true;
}
}
else
{
if (getSkinnable().getScene() != null && getSkinnable().isIndeterminate())
{
} else {
if (getSkinnable().getScene() != null && getSkinnable().isIndeterminate()) {
timelineNulled = false;
spinner = new IndeterminateSpinner(getSkinnable(), ConfidenceProgressIndicatorSkin.this, spinEnabled.get(), progressColor.get());
getChildren().add(spinner);
if (getSkinnable().impl_isTreeVisible())
{
if (getSkinnable().impl_isTreeVisible()) {
spinner.indeterminateTimeline.play();
}
getSkinnable().requestLayout();
@ -313,34 +278,27 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* @return The CssMetaData associated with this class, which may include the
* CssMetaData of its super classes.
*/
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData()
{
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
return StyleableProperties.STYLEABLES;
}
@SuppressWarnings("deprecation")
private void initialize()
{
private void initialize() {
ConfidenceProgressIndicator control = getSkinnable();
boolean isIndeterminate = control.isIndeterminate();
if (isIndeterminate)
{
if (isIndeterminate) {
// clean up determinateIndicator
determinateIndicator = null;
// create spinner
spinner = new IndeterminateSpinner(control, this, spinEnabled.get(), progressColor.get());
getChildren().clear();
getChildren().add(spinner);
if (getSkinnable().impl_isTreeVisible())
{
if (getSkinnable().impl_isTreeVisible()) {
spinner.indeterminateTimeline.play();
}
}
else
{
} else {
// clean up after spinner
if (spinner != null)
{
if (spinner != null) {
spinner.indeterminateTimeline.stop();
spinner = null;
}
@ -352,33 +310,26 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
public void dispose()
{
public void dispose() {
super.dispose();
if (spinner != null)
{
if (spinner != null) {
spinner.indeterminateTimeline.stop();
spinner = null;
}
}
@Override
protected void layoutChildren(final double x, final double y, final double w, final double h)
{
if (spinner != null && getSkinnable().isIndeterminate())
{
protected void layoutChildren(final double x, final double y, final double w, final double h) {
if (spinner != null && getSkinnable().isIndeterminate()) {
spinner.layoutChildren();
spinner.resizeRelocate(0, 0, w, h);
}
else if (determinateIndicator != null)
{
} else if (determinateIndicator != null) {
determinateIndicator.layoutChildren();
determinateIndicator.resizeRelocate(0, 0, w, h);
}
}
public Paint getProgressColor()
{
public Paint getProgressColor() {
return progressColor.get();
}
@ -386,8 +337,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* {@inheritDoc}
*/
@Override
public List<CssMetaData<? extends Styleable, ?>> getCssMetaData()
{
public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
return getClassCssMetaData();
}
@ -402,8 +352,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
*/
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
static class DeterminateIndicator extends Region
{
static class DeterminateIndicator extends Region {
//private double textGap = 2.0F;
@ -424,8 +373,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
// only update pie arc to nearest degree
private int degProgress;
public DeterminateIndicator(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, Paint fillOverride)
{
public DeterminateIndicator(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, Paint fillOverride) {
this.control = control;
getStyleClass().add("determinate-indicator");
@ -472,30 +420,24 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
updateProgress();
}
private void setFillOverride(Paint fillOverride)
{
if (fillOverride instanceof Color)
{
private void setFillOverride(Paint fillOverride) {
if (fillOverride instanceof Color) {
Color c = (Color) fillOverride;
progress.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," + c.getOpacity() + ");");
}
else
{
} else {
progress.setStyle(null);
}
}
//@Override
public boolean isAutomaticallyMirrored()
{
public boolean isAutomaticallyMirrored() {
// This is used instead of setting NodeOrientation,
// allowing the Text node to inherit the current
// orientation.
return false;
}
private void updateProgress()
{
private void updateProgress() {
intProgress = (int) Math.round(control.getProgress() * 100.0);
// text.setText((control.getProgress() >= 1) ? (DONE) : ("" + intProgress + "%"));
@ -506,8 +448,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected void layoutChildren()
{
protected void layoutChildren() {
// Position and size the circular background
//double doneTextHeight = doneText.getLayoutBounds().getHeight();
final Insets controlInsets = control.getInsets();
@ -574,8 +515,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected double computePrefWidth(double height)
{
protected double computePrefWidth(double height) {
final Insets controlInsets = control.getInsets();
final double left = snapSize(controlInsets.getLeft());
final double right = snapSize(controlInsets.getRight());
@ -599,8 +539,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected double computePrefHeight(double width)
{
protected double computePrefHeight(double width) {
final Insets controlInsets = control.getInsets();
final double top = snapSize(controlInsets.getTop());
final double bottom = snapSize(controlInsets.getBottom());
@ -624,14 +563,12 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected double computeMaxWidth(double height)
{
protected double computeMaxWidth(double height) {
return computePrefWidth(height);
}
@Override
protected double computeMaxHeight(double width)
{
protected double computeMaxHeight(double width) {
return computePrefHeight(width);
}
}
@ -645,8 +582,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
*/
@SuppressWarnings("ConstantConditions")
static class IndeterminateSpinner extends Region
{
static class IndeterminateSpinner extends Region {
private final ConfidenceProgressIndicator control;
private final ConfidenceProgressIndicatorSkin skin;
@ -658,8 +594,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
private Paint fillOverride = null;
public IndeterminateSpinner(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, boolean spinEnabled, Paint fillOverride)
{
public IndeterminateSpinner(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, boolean spinEnabled, Paint fillOverride) {
this.control = control;
this.skin = s;
this.spinEnabled = spinEnabled;
@ -678,51 +613,40 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
rebuild();
}
public void setFillOverride(Paint fillOverride)
{
public void setFillOverride(Paint fillOverride) {
this.fillOverride = fillOverride;
rebuild();
}
public void setSpinEnabled(boolean spinEnabled)
{
public void setSpinEnabled(boolean spinEnabled) {
this.spinEnabled = spinEnabled;
rebuildTimeline();
}
private void rebuildTimeline()
{
private void rebuildTimeline() {
final ObservableList<KeyFrame> keyFrames = FXCollections.<KeyFrame>observableArrayList();
if (spinEnabled)
{
if (spinEnabled) {
keyFrames.add(new KeyFrame(Duration.millis(0), new KeyValue(pathsG.rotateProperty(), 360)));
keyFrames.add(new KeyFrame(Duration.millis(3900), new KeyValue(pathsG.rotateProperty(), 0)));
}
for (int i = 100; i <= 3900; i += 100)
{
for (int i = 100; i <= 3900; i += 100) {
keyFrames.add(new KeyFrame(Duration.millis(i), event -> shiftColors()));
}
indeterminateTimeline.getKeyFrames().setAll(keyFrames);
}
private void pauseIndicator(boolean pause)
{
if (indeterminateTimeline != null)
{
if (pause)
{
private void pauseIndicator(boolean pause) {
if (indeterminateTimeline != null) {
if (pause) {
indeterminateTimeline.pause();
}
else
{
} else {
indeterminateTimeline.play();
}
}
}
@Override
protected void layoutChildren()
{
protected void layoutChildren() {
Insets controlInsets = control.getInsets();
final double w = control.getWidth() - controlInsets.getLeft() - controlInsets.getRight();
final double h = control.getHeight() - controlInsets.getTop() - controlInsets.getBottom();
@ -730,8 +654,7 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
final double prefH = pathsG.prefHeight(-1);
double scaleX = w / prefW;
double scale = scaleX;
if ((scaleX * prefH) > h)
{
if ((scaleX * prefH) > h) {
scale = h / prefH;
}
double indicatorW = prefW * scale - 3;
@ -739,26 +662,21 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
pathsG.resizeRelocate((w - indicatorW) / 2, (h - indicatorH) / 2, indicatorW, indicatorH);
}
private void rebuild()
{
private void rebuild() {
// update indeterminate indicator
final int segments = skin.indeterminateSegmentCount.get();
opacities.clear();
pathsG.getChildren().clear();
final double step = 0.8 / (segments - 1);
for (int i = 0; i < segments; i++)
{
for (int i = 0; i < segments; i++) {
Region region = new Region();
region.setScaleShape(false);
region.setCenterShape(false);
region.getStyleClass().addAll("segment", "segment" + i);
if (fillOverride instanceof Color)
{
if (fillOverride instanceof Color) {
Color c = (Color) fillOverride;
region.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," + c.getOpacity() + ");");
}
else
{
} else {
region.setStyle(null);
}
pathsG.getChildren().add(region);
@ -766,36 +684,28 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
}
private void shiftColors()
{
if (opacities.size() <= 0)
{
private void shiftColors() {
if (opacities.size() <= 0) {
return;
}
final int segments = skin.indeterminateSegmentCount.get();
Collections.rotate(opacities, -1);
for (int i = 0; i < segments; i++)
{
for (int i = 0; i < segments; i++) {
pathsG.getChildren().get(i).setOpacity(opacities.get(i));
}
}
@SuppressWarnings("deprecation")
private class IndicatorPaths extends Pane
{
private class IndicatorPaths extends Pane {
final IndeterminateSpinner piSkin;
IndicatorPaths(IndeterminateSpinner pi)
{
IndicatorPaths(IndeterminateSpinner pi) {
super();
piSkin = pi;
InvalidationListener treeVisibilityListener = valueModel -> {
if (piSkin.skin.getSkinnable().impl_isTreeVisible())
{
if (piSkin.skin.getSkinnable().impl_isTreeVisible()) {
piSkin.pauseIndicator(false);
}
else
{
} else {
piSkin.pauseIndicator(true);
}
};
@ -803,20 +713,14 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected double computePrefWidth(double height)
{
protected double computePrefWidth(double height) {
double w = 0;
for (Node child : getChildren())
{
if (child instanceof Region)
{
for (Node child : getChildren()) {
if (child instanceof Region) {
Region region = (Region) child;
if (region.getShape() != null)
{
if (region.getShape() != null) {
w = Math.max(w, region.getShape().getLayoutBounds().getMaxX());
}
else
{
} else {
w = Math.max(w, region.prefWidth(height));
}
}
@ -825,20 +729,14 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected double computePrefHeight(double width)
{
protected double computePrefHeight(double width) {
double h = 0;
for (Node child : getChildren())
{
if (child instanceof Region)
{
for (Node child : getChildren()) {
if (child instanceof Region) {
Region region = (Region) child;
if (region.getShape() != null)
{
if (region.getShape() != null) {
h = Math.max(h, region.getShape().getLayoutBounds().getMaxY());
}
else
{
} else {
h = Math.max(h, region.prefHeight(width));
}
}
@ -847,19 +745,15 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}
@Override
protected void layoutChildren()
{
protected void layoutChildren() {
// calculate scale
double scale = getWidth() / computePrefWidth(-1);
getChildren().stream().filter(child -> child instanceof Region).forEach(child -> {
Region region = (Region) child;
if (region.getShape() != null)
{
if (region.getShape() != null) {
region.resize(region.getShape().getLayoutBounds().getMaxX(), region.getShape().getLayoutBounds().getMaxY());
region.getTransforms().setAll(new Scale(scale, scale, 0, 0));
}
else
{
} else {
region.autosize();
}
});
@ -871,26 +765,22 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
* Super-lazy instantiation pattern from Bill Pugh.
*/
@SuppressWarnings({"deprecation", "unchecked", "ConstantConditions"})
private static class StyleableProperties
{
private static class StyleableProperties {
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
private static final CssMetaData<ConfidenceProgressIndicator, Paint> PROGRESS_COLOR = new CssMetaData<ConfidenceProgressIndicator, Paint>("-fx-progress-color",
PaintConverter.getInstance(),
null)
{
PaintConverter.getInstance(),
null) {
@Override
public boolean isSettable(ConfidenceProgressIndicator n)
{
public boolean isSettable(ConfidenceProgressIndicator n) {
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return skin.progressColor == null || !skin.progressColor.isBound();
}
@Override
public StyleableProperty<Paint> getStyleableProperty(ConfidenceProgressIndicator n)
{
public StyleableProperty<Paint> getStyleableProperty(ConfidenceProgressIndicator n) {
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return (StyleableProperty<Paint>) skin.progressColor;
}
@ -898,55 +788,47 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
private static final CssMetaData<ConfidenceProgressIndicator, Number> INDETERMINATE_SEGMENT_COUNT = new CssMetaData<ConfidenceProgressIndicator, Number>("-fx-indeterminate-segment-count",
SizeConverter.getInstance(),
8)
{
SizeConverter.getInstance(),
8) {
@Override
public void set(ConfidenceProgressIndicator node, Number value, StyleOrigin origin)
{
public void set(ConfidenceProgressIndicator node, Number value, StyleOrigin origin) {
super.set(node, value.intValue(), origin);
}
@Override
public boolean isSettable(ConfidenceProgressIndicator n)
{
public boolean isSettable(ConfidenceProgressIndicator n) {
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return skin.indeterminateSegmentCount == null || !skin.indeterminateSegmentCount.isBound();
}
@Override
public StyleableProperty<Number> getStyleableProperty(ConfidenceProgressIndicator n)
{
public StyleableProperty<Number> getStyleableProperty(ConfidenceProgressIndicator n) {
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) n.getSkin();
return (StyleableProperty<Number>) skin.indeterminateSegmentCount;
}
};
private static final CssMetaData<ConfidenceProgressIndicator, Boolean> SPIN_ENABLED = new CssMetaData<ConfidenceProgressIndicator, Boolean>("-fx-spin-enabled",
BooleanConverter.getInstance(),
Boolean.FALSE)
{
BooleanConverter.getInstance(),
Boolean.FALSE) {
@Override
public boolean isSettable(ConfidenceProgressIndicator node)
{
public boolean isSettable(ConfidenceProgressIndicator node) {
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) node.getSkin();
return skin.spinEnabled == null || !skin.spinEnabled.isBound();
}
@Override
public StyleableProperty<Boolean> getStyleableProperty(ConfidenceProgressIndicator node)
{
public StyleableProperty<Boolean> getStyleableProperty(ConfidenceProgressIndicator node) {
final ConfidenceProgressIndicatorSkin skin = (ConfidenceProgressIndicatorSkin) node.getSkin();
return (StyleableProperty<Boolean>) skin.spinEnabled;
}
};
static
{
static {
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(SkinBase.getClassCssMetaData());
styleables.add(PROGRESS_COLOR);
styleables.add(INDETERMINATE_SEGMENT_COUNT);

View File

@ -18,49 +18,42 @@
package io.bitsquare.gui.components.processbar;
import java.util.List;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
public class ProcessStepBar<T> extends Control
{
public class ProcessStepBar<T> extends Control {
private List<ProcessStepItem> processStepItems = null;
public ProcessStepBar()
{
public ProcessStepBar() {
}
public ProcessStepBar(List<ProcessStepItem> processStepItems)
{
public ProcessStepBar(List<ProcessStepItem> processStepItems) {
this.processStepItems = processStepItems;
}
@Override
protected Skin<?> createDefaultSkin()
{
protected Skin<?> createDefaultSkin() {
return new ProcessStepBarSkin<>(this);
}
List<ProcessStepItem> getProcessStepItems()
{
List<ProcessStepItem> getProcessStepItems() {
return processStepItems;
}
public void setProcessStepItems(List<ProcessStepItem> processStepItems)
{
public void setProcessStepItems(List<ProcessStepItem> processStepItems) {
this.processStepItems = processStepItems;
if (getSkin() != null)
{
if (getSkin() != null) {
((ProcessStepBarSkin) getSkin()).dataChanged();
}
}
public void next()
{
public void next() {
((ProcessStepBarSkin) getSkin()).next();
}
}

View File

@ -20,9 +20,11 @@ package io.bitsquare.gui.components.processbar;
import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.control.behavior.KeyBinding;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
@ -34,16 +36,14 @@ import javafx.scene.layout.BorderWidths;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>>
{
class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, BehaviorBase<ProcessStepBar<T>>> {
private final ProcessStepBar<T> controller;
private LabelWithBorder currentLabelWithBorder;
private LabelWithBorder prevLabelWithBorder;
private int index;
private List<LabelWithBorder> labelWithBorders;
public ProcessStepBarSkin(final ProcessStepBar<T> control)
{
public ProcessStepBarSkin(final ProcessStepBar<T> control) {
super(control, new BehaviorBase<>(control, Collections.<KeyBinding>emptyList()));
controller = getSkinnable();
@ -51,25 +51,20 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
applyData();
}
public void dataChanged()
{
public void dataChanged() {
applyData();
}
private void applyData()
{
if (controller.getProcessStepItems() != null)
{
private void applyData() {
if (controller.getProcessStepItems() != null) {
int i = 0;
labelWithBorders = new ArrayList<>();
int size = controller.getProcessStepItems().size();
for (ProcessStepItem processStepItem : controller.getProcessStepItems())
{
for (ProcessStepItem processStepItem : controller.getProcessStepItems()) {
LabelWithBorder labelWithBorder = new LabelWithBorder(processStepItem, i == 0, i == size - 1);
getChildren().add(labelWithBorder);
labelWithBorders.add(labelWithBorder);
if (i == 0)
{
if (i == 0) {
currentLabelWithBorder = prevLabelWithBorder = labelWithBorder;
}
@ -80,13 +75,11 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
}
}
public void next()
{
public void next() {
index++;
prevLabelWithBorder.deSelect();
if (index < labelWithBorders.size())
{
if (index < labelWithBorders.size()) {
currentLabelWithBorder = labelWithBorders.get(index);
currentLabelWithBorder.select();
@ -95,19 +88,16 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
}
@Override
protected void layoutChildren(double x, double y, double width, double height)
{
protected void layoutChildren(double x, double y, double width, double height) {
double distance = 10;
double padding = 50;
for (int i = 0; i < getChildren().size(); i++)
{
for (int i = 0; i < getChildren().size(); i++) {
Node node = getChildren().get(i);
double newWidth = snapSize(node.prefWidth(height)) + padding;
double newHeight = snapSize(node.prefHeight(-1) + 10);
if (i > 0)
{
if (i > 0) {
x = snapPosition(x - ((LabelWithBorder) node).getArrowWidth());
}
@ -121,8 +111,7 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
@SuppressWarnings("EmptyMethod")
public static class LabelWithBorder extends Label
{
public static class LabelWithBorder extends Label {
final double borderWidth = 1;
private final double arrowWidth = 10;
private final double arrowHeight = 30;
@ -131,8 +120,7 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
private final boolean isFirst;
private final boolean isLast;
public LabelWithBorder(ProcessStepItem processStepItem, boolean isFirst, boolean isLast)
{
public LabelWithBorder(ProcessStepItem processStepItem, boolean isFirst, boolean isLast) {
super(processStepItem.getLabel());
this.processStepItem = processStepItem;
@ -149,15 +137,13 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
this.setBorder(new Border(borderStroke));
}
public void select()
{
public void select() {
BorderStroke borderStroke = new BorderStroke(processStepItem.getColor(), BorderStrokeStyle.SOLID, null, new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
this.setBorder(new Border(borderStroke));
setTextFill(processStepItem.getColor());
}
public void deSelect()
{
public void deSelect() {
/*BorderStroke borderStroke = new BorderStroke(Color.GRAY, BorderStrokeStyle.SOLID, null,
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
this.setBorder(new Border(borderStroke));
@ -165,14 +151,12 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
}
public double getArrowWidth()
{
public double getArrowWidth() {
return arrowWidth;
}
private Path createButtonShape()
{
private Path createButtonShape() {
// build the following shape (or home without left arrow)
// --------
@ -191,8 +175,7 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
e2.xProperty().bind(this.widthProperty().subtract(arrowWidth));
path.getElements().add(e2);
if (!isLast)
{
if (!isLast) {
// draw upper part of right arrow
LineTo e3 = new LineTo();
// the x endpoint of this line depends on the x property of line e2
@ -213,8 +196,7 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
HLineTo e5 = new HLineTo(0);
path.getElements().add(e5);
if (!isFirst)
{
if (!isFirst) {
LineTo e6 = new LineTo(arrowWidth, arrowHeight / 2.0);
path.getElements().add(e6);
}

View File

@ -20,41 +20,34 @@ package io.bitsquare.gui.components.processbar;
import io.bitsquare.gui.util.Colors;
import javafx.scene.paint.Paint;
public class ProcessStepItem
{
public class ProcessStepItem {
private final String label;
private final Paint color;
private final boolean progressIndicator;
public ProcessStepItem(String label)
{
public ProcessStepItem(String label) {
this(label, Colors.BLUE, false);
}
public ProcessStepItem(String label, Paint color)
{
public ProcessStepItem(String label, Paint color) {
this(label, color, false);
}
private ProcessStepItem(String label, Paint color, @SuppressWarnings("SameParameterValue") boolean hasProgressIndicator)
{
private ProcessStepItem(String label, Paint color, @SuppressWarnings("SameParameterValue") boolean hasProgressIndicator) {
this.label = label;
this.color = color;
this.progressIndicator = hasProgressIndicator;
}
public String getLabel()
{
public String getLabel() {
return label;
}
public Paint getColor()
{
public Paint getColor() {
return color;
}
public boolean hasProgressIndicator()
{
public boolean hasProgressIndicator() {
return progressIndicator;
}
}

View File

@ -22,14 +22,15 @@ import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.ViewController;
import io.bitsquare.gui.components.CachingTabPane;
import io.bitsquare.storage.Persistence;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FundsController extends CachedViewController
{
public class FundsController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(FundsController.class);
private final Persistence persistence;
private ViewController childController;
@ -40,8 +41,7 @@ public class FundsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private FundsController(Persistence persistence)
{
private FundsController(Persistence persistence) {
this.persistence = persistence;
}
@ -51,22 +51,19 @@ public class FundsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
((CachingTabPane) root).initialize(this, persistence, NavigationItem.DEPOSIT.getFxmlUrl(), NavigationItem.WITHDRAWAL.getFxmlUrl(), NavigationItem.TRANSACTIONS.getFxmlUrl());
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -76,8 +73,7 @@ public class FundsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
childController = ((CachingTabPane) root).loadViewAndGetChildController(navigationItem.getFxmlUrl());
return childController;
}

View File

@ -22,10 +22,12 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.CachedViewController;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@ -34,12 +36,13 @@ import javafx.scene.control.*;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.util.Callback;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DepositController extends CachedViewController
{
public class DepositController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(DepositController.class);
private final WalletFacade walletFacade;
@ -54,8 +57,7 @@ public class DepositController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private DepositController(WalletFacade walletFacade)
{
private DepositController(WalletFacade walletFacade) {
this.walletFacade = walletFacade;
}
@ -65,8 +67,7 @@ public class DepositController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
@ -78,8 +79,7 @@ public class DepositController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
for (DepositListItem anAddressList : addressList)
@ -87,8 +87,7 @@ public class DepositController extends CachedViewController
}
@Override
public void activate()
{
public void activate() {
super.activate();
List<AddressEntry> addressEntryList = walletFacade.getAddressEntryList();
@ -113,40 +112,31 @@ public class DepositController extends CachedViewController
// Cell factories
///////////////////////////////////////////////////////////////////////////////////////////
private void setLabelColumnCellFactory()
{
private void setLabelColumnCellFactory() {
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
labelColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() {
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
return new TableCell<String, DepositListItem>()
{
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
return new TableCell<String, DepositListItem>() {
Hyperlink hyperlink;
@Override
public void updateItem(final DepositListItem item, boolean empty)
{
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
hyperlink = new Hyperlink(item.getLabel());
hyperlink.setId("id-link");
if (item.getAddressEntry().getOfferId() != null)
{
if (item.getAddressEntry().getOfferId() != null) {
Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry().getOfferId()));
}
setGraphic(hyperlink);
}
else
{
} else {
setGraphic(null);
setId(null);
}
@ -156,28 +146,20 @@ public class DepositController extends CachedViewController
});
}
private void setBalanceColumnCellFactory()
{
private void setBalanceColumnCellFactory() {
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
balanceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
balanceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() {
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
return new TableCell<String, DepositListItem>()
{
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
return new TableCell<String, DepositListItem>() {
@Override
public void updateItem(final DepositListItem item, boolean empty)
{
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
setGraphic(item.getBalanceLabel());
}
else
{
} else {
setGraphic(null);
}
}
@ -186,17 +168,13 @@ public class DepositController extends CachedViewController
});
}
private void setCopyColumnCellFactory()
{
private void setCopyColumnCellFactory() {
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
copyColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
copyColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() {
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
return new TableCell<String, DepositListItem>()
{
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
return new TableCell<String, DepositListItem>() {
final Label copyIcon = new Label();
{
@ -206,12 +184,10 @@ public class DepositController extends CachedViewController
}
@Override
public void updateItem(final DepositListItem item, boolean empty)
{
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
setGraphic(copyIcon);
copyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
@ -220,9 +196,7 @@ public class DepositController extends CachedViewController
clipboard.setContent(content);
});
}
else
{
} else {
setGraphic(null);
}
}
@ -231,29 +205,21 @@ public class DepositController extends CachedViewController
});
}
private void setConfidenceColumnCellFactory()
{
private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>()
{
confidenceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() {
@Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column)
{
return new TableCell<String, DepositListItem>()
{
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
return new TableCell<String, DepositListItem>() {
@Override
public void updateItem(final DepositListItem item, boolean empty)
{
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
setGraphic(item.getProgressIndicator());
}
else
{
} else {
setGraphic(null);
}
}

View File

@ -21,10 +21,8 @@ import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.funds.withdrawal.WithdrawalListItem;
public class DepositListItem extends WithdrawalListItem
{
public DepositListItem(AddressEntry addressEntry, WalletFacade walletFacade)
{
public class DepositListItem extends WithdrawalListItem {
public DepositListItem(AddressEntry addressEntry, WalletFacade walletFacade) {
super(addressEntry, walletFacade);
}

View File

@ -20,22 +20,25 @@ package io.bitsquare.gui.funds.transactions;
import com.google.bitcoin.core.Transaction;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.CachedViewController;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.util.Callback;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TransactionsController extends CachedViewController
{
public class TransactionsController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(TransactionsController.class);
private final WalletFacade walletFacade;
@ -51,8 +54,7 @@ public class TransactionsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private TransactionsController(WalletFacade walletFacade)
{
private TransactionsController(WalletFacade walletFacade) {
this.walletFacade = walletFacade;
}
@ -62,8 +64,7 @@ public class TransactionsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
@ -73,8 +74,7 @@ public class TransactionsController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
for (TransactionsListItem transactionsListItem : transactionsListItems)
@ -82,8 +82,7 @@ public class TransactionsController extends CachedViewController
}
@Override
public void activate()
{
public void activate() {
super.activate();
List<Transaction> transactions = walletFacade.getWallet().getRecentTransactions(10000, true);
@ -108,33 +107,25 @@ public class TransactionsController extends CachedViewController
// Cell factories
///////////////////////////////////////////////////////////////////////////////////////////
private void setAddressColumnCellFactory()
{
private void setAddressColumnCellFactory() {
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
addressColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>()
{
addressColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>() {
@Override
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column)
{
return new TableCell<String, TransactionsListItem>()
{
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column) {
return new TableCell<String, TransactionsListItem>() {
Hyperlink hyperlink;
@Override
public void updateItem(final TransactionsListItem item, boolean empty)
{
public void updateItem(final TransactionsListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
hyperlink = new Hyperlink(item.getAddressString());
hyperlink.setId("id-link");
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressString()));
setGraphic(hyperlink);
}
else
{
} else {
setGraphic(null);
setId(null);
}
@ -144,29 +135,21 @@ public class TransactionsController extends CachedViewController
});
}
private void setConfidenceColumnCellFactory()
{
private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>()
{
confidenceColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>() {
@Override
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column)
{
return new TableCell<String, TransactionsListItem>()
{
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column) {
return new TableCell<String, TransactionsListItem>() {
@Override
public void updateItem(final TransactionsListItem item, boolean empty)
{
public void updateItem(final TransactionsListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
setGraphic(item.getProgressIndicator());
}
else
{
} else {
setGraphic(null);
}
}

View File

@ -28,8 +28,7 @@ import javafx.scene.control.Tooltip;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TransactionsListItem
{
public class TransactionsListItem {
private static final Logger log = LoggerFactory.getLogger(TransactionsListItem.class);
private final StringProperty date = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty();
@ -43,87 +42,63 @@ public class TransactionsListItem
private String addressString;
private ConfidenceListener confidenceListener;
public TransactionsListItem(Transaction transaction, WalletFacade walletFacade)
{
public TransactionsListItem(Transaction transaction, WalletFacade walletFacade) {
this.walletFacade = walletFacade;
Coin valueSentToMe = transaction.getValueSentToMe(walletFacade.getWallet());
Coin valueSentFromMe = transaction.getValueSentFromMe(walletFacade.getWallet());
Address address = null;
if (valueSentToMe.isZero())
{
if (valueSentToMe.isZero()) {
//TODO use BitSquareFormatter
amount.set("-" + valueSentFromMe.toFriendlyString());
for (TransactionOutput transactionOutput : transaction.getOutputs())
{
if (!transactionOutput.isMine(walletFacade.getWallet()))
{
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
if (!transactionOutput.isMine(walletFacade.getWallet())) {
type.set("Sent to");
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash())
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams());
addressString = address.toString();
}
else
{
} else {
addressString = "No sent to address script used.";
}
}
}
}
else if (valueSentFromMe.isZero())
{
} else if (valueSentFromMe.isZero()) {
//TODO use BitSquareFormatter
amount.set(valueSentToMe.toFriendlyString());
type.set("Received with");
for (TransactionOutput transactionOutput : transaction.getOutputs())
{
if (transactionOutput.isMine(walletFacade.getWallet()))
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash())
{
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
if (transactionOutput.isMine(walletFacade.getWallet())) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams());
addressString = address.toString();
}
else
{
} else {
addressString = "No sent to address script used.";
}
}
}
}
else
{
} else {
//TODO use BitSquareFormatter
amount.set(valueSentToMe.subtract(valueSentFromMe).toFriendlyString());
boolean outgoing = false;
for (TransactionOutput transactionOutput : transaction.getOutputs())
{
if (!transactionOutput.isMine(walletFacade.getWallet()))
{
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
if (!transactionOutput.isMine(walletFacade.getWallet())) {
outgoing = true;
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash())
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams());
addressString = address.toString();
}
else
{
} else {
addressString = "No sent to address script used.";
}
}
}
if (outgoing)
{
if (outgoing) {
type.set("Sent to");
}
else
{
} else {
type.set("Internal (TX Fee)");
addressString = "Internal swap between addresses.";
}
@ -140,13 +115,10 @@ public class TransactionsListItem
progressIndicator.setPrefWidth(30);
Tooltip.install(progressIndicator, tooltip);
if (address != null)
{
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(address)
{
if (address != null) {
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(address) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence)
{
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(confidence);
}
});
@ -156,18 +128,14 @@ public class TransactionsListItem
}
public void cleanup()
{
public void cleanup() {
walletFacade.removeConfidenceListener(confidenceListener);
}
private void updateConfidence(TransactionConfidence confidence)
{
if (confidence != null)
{
private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) {
//log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " + confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks());
switch (confidence.getConfidenceType())
{
switch (confidence.getConfidenceType()) {
case UNKNOWN:
tooltip.setText("Unknown transaction status");
progressIndicator.setProgress(0);
@ -191,31 +159,26 @@ public class TransactionsListItem
}
public ConfidenceProgressIndicator getProgressIndicator()
{
public ConfidenceProgressIndicator getProgressIndicator() {
return progressIndicator;
}
public final StringProperty dateProperty()
{
public final StringProperty dateProperty() {
return this.date;
}
public final StringProperty amountProperty()
{
public final StringProperty amountProperty() {
return this.amount;
}
public final StringProperty typeProperty()
{
public final StringProperty typeProperty() {
return this.type;
}
public String getAddressString()
{
public String getAddressString() {
return addressString;
}
}

View File

@ -32,10 +32,12 @@ import io.bitsquare.gui.CachedViewController;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.gui.util.BitSquareValidator;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@ -44,14 +46,15 @@ import javafx.scene.control.*;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.util.Callback;
import javax.inject.Inject;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WithdrawalController extends CachedViewController
{
public class WithdrawalController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(WithdrawalController.class);
@ -69,8 +72,7 @@ public class WithdrawalController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private WithdrawalController(WalletFacade walletFacade)
{
private WithdrawalController(WalletFacade walletFacade) {
this.walletFacade = walletFacade;
}
@ -79,8 +81,7 @@ public class WithdrawalController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
@ -92,8 +93,7 @@ public class WithdrawalController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
for (WithdrawalListItem anAddressList : addressList)
@ -101,23 +101,18 @@ public class WithdrawalController extends CachedViewController
}
@Override
public void activate()
{
public void activate() {
super.activate();
tableView.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
if (newValue != null)
{
if (newValue != null) {
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField);
if (Coin.ZERO.compareTo(newValue.getBalance()) <= 0)
{
if (Coin.ZERO.compareTo(newValue.getBalance()) <= 0) {
amountTextField.setText(newValue.getBalance().toPlainString());
withdrawFromTextField.setText(newValue.getAddressEntry().getAddressString());
changeAddressTextField.setText(newValue.getAddressEntry().getAddressString());
}
else
{
} else {
withdrawFromTextField.setText("");
withdrawFromTextField.setPromptText("No fund to withdrawal on that address.");
amountTextField.setText("");
@ -139,31 +134,24 @@ public class WithdrawalController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onWithdraw()
{
try
{
public void onWithdraw() {
try {
BitSquareValidator.textFieldsNotEmpty(amountTextField, withdrawFromTextField, withdrawToTextField, changeAddressTextField);
BitSquareValidator.textFieldsHasDoubleValueWithReset(amountTextField);
Coin amount = BitSquareFormatter.parseToCoin(amountTextField.getText());
if (BtcValidator.isMinSpendableAmount(amount))
{
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
if (BtcValidator.isMinSpendableAmount(amount)) {
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
@Override
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField);
if (transaction != null)
{
if (transaction != null) {
log.info("onWithdraw onSuccess txid:" + transaction.getHashAsString());
}
}
@Override
public void onFailure(Throwable t)
{
public void onFailure(Throwable t) {
log.debug("onWithdraw onFailure");
}
};
@ -175,32 +163,24 @@ public class WithdrawalController extends CachedViewController
"Transaction fee: " + BitSquareFormatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
"You receive in total: " + BitSquareFormatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
"Are you sure you withdraw that amount?");
if (response == Dialog.Actions.OK)
{
try
{
if (response == Dialog.Actions.OK) {
try {
walletFacade.sendFunds(withdrawFromTextField.getText(), withdrawToTextField.getText(), changeAddressTextField.getText(), amount, callback);
} catch (AddressFormatException e)
{
} catch (AddressFormatException e) {
Popups.openErrorPopup("Address invalid", "The address is not correct. Please check the address format.");
} catch (InsufficientMoneyException e)
{
} catch (InsufficientMoneyException e) {
Popups.openInsufficientMoneyPopup();
} catch (IllegalArgumentException e)
{
} catch (IllegalArgumentException e) {
Popups.openErrorPopup("Wrong inputs", "Please check the inputs.");
}
}
}
else
{
} else {
Popups.openErrorPopup("Insufficient amount", "The amount to transfer is lower the the transaction fee and the min. possible tx value.");
}
} catch (BitSquareValidator.ValidationException e)
{
} catch (BitSquareValidator.ValidationException e) {
log.trace(e.toString());
}
}
@ -215,40 +195,31 @@ public class WithdrawalController extends CachedViewController
// Cell factories
///////////////////////////////////////////////////////////////////////////////////////////
private void setLabelColumnCellFactory()
{
private void setLabelColumnCellFactory() {
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
labelColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() {
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
return new TableCell<String, WithdrawalListItem>()
{
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
return new TableCell<String, WithdrawalListItem>() {
Hyperlink hyperlink;
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
{
public void updateItem(final WithdrawalListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
hyperlink = new Hyperlink(item.getLabel());
hyperlink.setId("id-link");
if (item.getAddressEntry().getOfferId() != null)
{
if (item.getAddressEntry().getOfferId() != null) {
Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry().getOfferId()));
}
setGraphic(hyperlink);
}
else
{
} else {
setGraphic(null);
setId(null);
}
@ -258,20 +229,15 @@ public class WithdrawalController extends CachedViewController
});
}
private void setBalanceColumnCellFactory()
{
private void setBalanceColumnCellFactory() {
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
balanceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
balanceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() {
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
return new TableCell<String, WithdrawalListItem>()
{
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
return new TableCell<String, WithdrawalListItem>() {
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
{
public void updateItem(final WithdrawalListItem item, boolean empty) {
super.updateItem(item, empty);
setGraphic((item != null && !empty) ? item.getBalanceLabel() : null);
}
@ -280,17 +246,13 @@ public class WithdrawalController extends CachedViewController
});
}
private void setCopyColumnCellFactory()
{
private void setCopyColumnCellFactory() {
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
copyColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
copyColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() {
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
return new TableCell<String, WithdrawalListItem>()
{
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
return new TableCell<String, WithdrawalListItem>() {
final Label copyIcon = new Label();
{
@ -300,12 +262,10 @@ public class WithdrawalController extends CachedViewController
}
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
{
public void updateItem(final WithdrawalListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
setGraphic(copyIcon);
copyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
@ -314,9 +274,7 @@ public class WithdrawalController extends CachedViewController
clipboard.setContent(content);
});
}
else
{
} else {
setGraphic(null);
}
}
@ -325,29 +283,21 @@ public class WithdrawalController extends CachedViewController
});
}
private void setConfidenceColumnCellFactory()
{
private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>()
{
confidenceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() {
@Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column)
{
return new TableCell<String, WithdrawalListItem>()
{
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
return new TableCell<String, WithdrawalListItem>() {
@Override
public void updateItem(final WithdrawalListItem item, boolean empty)
{
public void updateItem(final WithdrawalListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
setGraphic(item.getProgressIndicator());
}
else
{
} else {
setGraphic(null);
}
}

View File

@ -32,8 +32,7 @@ import javafx.scene.control.Tooltip;
import static com.google.common.base.Preconditions.checkNotNull;
public class WithdrawalListItem
{
public class WithdrawalListItem {
private final StringProperty addressString = new SimpleStringProperty();
private final BalanceListener balanceListener;
@ -50,8 +49,7 @@ public class WithdrawalListItem
private Coin balance;
public WithdrawalListItem(AddressEntry addressEntry, WalletFacade walletFacade)
{
public WithdrawalListItem(AddressEntry addressEntry, WalletFacade walletFacade) {
this.addressEntry = addressEntry;
this.walletFacade = walletFacade;
this.addressString.set(getAddress().toString());
@ -64,11 +62,9 @@ public class WithdrawalListItem
progressIndicator.setPrefSize(24, 24);
Tooltip.install(progressIndicator, tooltip);
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(getAddress())
{
confidenceListener = walletFacade.addConfidenceListener(new ConfidenceListener(getAddress()) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence)
{
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(confidence);
}
});
@ -78,11 +74,9 @@ public class WithdrawalListItem
// balance
balanceLabel = new Label();
balanceListener = walletFacade.addBalanceListener(new BalanceListener(getAddress())
{
balanceListener = walletFacade.addBalanceListener(new BalanceListener(getAddress()) {
@Override
public void onBalanceChanged(Coin balance)
{
public void onBalanceChanged(Coin balance) {
updateBalance(balance);
}
});
@ -90,29 +84,23 @@ public class WithdrawalListItem
updateBalance(walletFacade.getBalanceForAddress(getAddress()));
}
public void cleanup()
{
public void cleanup() {
walletFacade.removeConfidenceListener(confidenceListener);
walletFacade.removeBalanceListener(balanceListener);
}
private void updateBalance(Coin balance)
{
private void updateBalance(Coin balance) {
this.balance = balance;
if (balance != null)
{
if (balance != null) {
//TODO use BitSquareFormatter
balanceLabel.setText(balance.toFriendlyString());
}
}
private void updateConfidence(TransactionConfidence confidence)
{
if (confidence != null)
{
private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) {
//log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " + confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks());
switch (confidence.getConfidenceType())
{
switch (confidence.getConfidenceType()) {
case UNKNOWN:
tooltip.setText("Unknown transaction status");
progressIndicator.setProgress(0);
@ -134,10 +122,8 @@ public class WithdrawalListItem
}
public final String getLabel()
{
switch (addressEntry.getAddressContext())
{
public final String getLabel() {
switch (addressEntry.getAddressContext()) {
case REGISTRATION_FEE:
return "Registration fee";
case TRADE:
@ -150,37 +136,31 @@ public class WithdrawalListItem
}
public final StringProperty addressStringProperty()
{
public final StringProperty addressStringProperty() {
return this.addressString;
}
Address getAddress()
{
Address getAddress() {
return addressEntry.getAddress();
}
public AddressEntry getAddressEntry()
{
public AddressEntry getAddressEntry() {
return addressEntry;
}
public ConfidenceProgressIndicator getProgressIndicator()
{
public ConfidenceProgressIndicator getProgressIndicator() {
return progressIndicator;
}
public Label getBalanceLabel()
{
public Label getBalanceLabel() {
return balanceLabel;
}
public Coin getBalance()
{
public Coin getBalance() {
return balance;
}
}

View File

@ -23,17 +23,18 @@ import io.bitsquare.gui.CachedViewController;
import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.ViewController;
import io.bitsquare.gui.arbitrators.registration.ArbitratorRegistrationController;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class HomeController extends CachedViewController
{
public class HomeController extends CachedViewController {
private ArbitratorRegistrationController arbitratorRegistrationController;
///////////////////////////////////////////////////////////////////////////////////////////
@ -41,26 +42,22 @@ public class HomeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@Override
public void terminate()
{
public void terminate() {
super.terminate();
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -70,12 +67,10 @@ public class HomeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
// don't use caching here, cause exc. -> need to investigate and is rarely called so no caching is better
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
try
{
try {
final Parent view = loader.load();
arbitratorRegistrationController = loader.getController();
arbitratorRegistrationController.setParentController(this);
@ -96,8 +91,7 @@ public class HomeController extends CachedViewController
stage.show();
return arbitratorRegistrationController;
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return null;
@ -109,14 +103,12 @@ public class HomeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onArbitratorRegistration()
{
public void onArbitratorRegistration() {
loadViewAndGetChildController(NavigationItem.ARBITRATOR_REGISTRATION);
}
@FXML
public void onArbitratorEdit()
{
public void onArbitratorEdit() {
loadViewAndGetChildController(NavigationItem.ARBITRATOR_REGISTRATION);
arbitratorRegistrationController.setEditMode(true);
}

View File

@ -20,14 +20,15 @@ package io.bitsquare.gui.msg;
import io.bitsquare.gui.CachedViewController;
import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.ViewController;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MsgController extends CachedViewController
{
public class MsgController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(MsgController.class);
@ -36,8 +37,7 @@ public class MsgController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private MsgController()
{
private MsgController() {
}
///////////////////////////////////////////////////////////////////////////////////////////
@ -46,26 +46,22 @@ public class MsgController extends CachedViewController
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@Override
public void terminate()
{
public void terminate() {
super.terminate();
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -75,8 +71,7 @@ public class MsgController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
return null;
}

View File

@ -22,21 +22,21 @@ import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.ViewController;
import io.bitsquare.gui.components.CachingTabPane;
import io.bitsquare.storage.Persistence;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrdersController extends CachedViewController
{
public class OrdersController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(OrdersController.class);
private static OrdersController INSTANCE;
private final Persistence persistence;
@Inject
private OrdersController(Persistence persistence)
{
private OrdersController(Persistence persistence) {
this.persistence = persistence;
INSTANCE = this;
}
@ -45,8 +45,7 @@ public class OrdersController extends CachedViewController
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public static OrdersController GET_INSTANCE()
{
public static OrdersController GET_INSTANCE() {
return INSTANCE;
}
@ -56,22 +55,19 @@ public class OrdersController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
((CachingTabPane) root).initialize(this, persistence, NavigationItem.OFFER.getFxmlUrl(), NavigationItem.PENDING_TRADE.getFxmlUrl(), NavigationItem.CLOSED_TRADE.getFxmlUrl());
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -81,8 +77,7 @@ public class OrdersController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
childController = ((CachingTabPane) root).loadViewAndGetChildController(navigationItem.getFxmlUrl());
return childController;
}
@ -92,8 +87,7 @@ public class OrdersController extends CachedViewController
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setSelectedTabIndex(int index)
{
public void setSelectedTabIndex(int index) {
log.trace("setSelectedTabIndex " + index);
((CachingTabPane) root).setSelectedTabIndex(index);
persistence.write(this, "selectedTabIndex", index);

View File

@ -18,14 +18,15 @@
package io.bitsquare.gui.orders.closed;
import io.bitsquare.gui.CachedViewController;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ClosedTradeController extends CachedViewController
{
public class ClosedTradeController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(ClosedTradeController.class);
@ -34,8 +35,7 @@ public class ClosedTradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private ClosedTradeController()
{
private ClosedTradeController() {
}
@ -44,20 +44,17 @@ public class ClosedTradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}

View File

@ -21,12 +21,14 @@ import io.bitsquare.gui.CachedViewController;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.trade.Offer;
import io.bitsquare.trade.TradeManager;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.stream.Collectors;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@ -34,13 +36,14 @@ import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.util.Callback;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("EmptyMethod")
public class OfferController extends CachedViewController
{
public class OfferController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(OfferController.class);
private final TradeManager tradeManager;
private ObservableList<OfferListItem> offerListItems;
@ -54,8 +57,7 @@ public class OfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private OfferController(TradeManager tradeManager)
{
private OfferController(TradeManager tradeManager) {
this.tradeManager = tradeManager;
}
@ -65,8 +67,7 @@ public class OfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
setOfferIdColumnColumnCellFactory();
@ -75,14 +76,12 @@ public class OfferController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
offerListItems = FXCollections.observableArrayList();
@ -102,14 +101,12 @@ public class OfferController extends CachedViewController
// Private Methods
///////////////////////////////////////////////////////////////////////////////////////////
private void removeOffer(OfferListItem offerListItem)
{
private void removeOffer(OfferListItem offerListItem) {
tradeManager.removeOffer(offerListItem.getOffer());
offerListItems.remove(offerListItem);
}
private void openOfferDetails(OfferListItem offerListItem)
{
private void openOfferDetails(OfferListItem offerListItem) {
}
@ -117,35 +114,27 @@ public class OfferController extends CachedViewController
// Table columns
///////////////////////////////////////////////////////////////////////////////////////////
private void setOfferIdColumnColumnCellFactory()
{
private void setOfferIdColumnColumnCellFactory() {
offerIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue()));
offerIdColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>()
{
offerIdColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>() {
@Override
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> column)
{
return new TableCell<String, OfferListItem>()
{
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> column) {
return new TableCell<String, OfferListItem>() {
Hyperlink hyperlink;
@Override
public void updateItem(final OfferListItem item, boolean empty)
{
public void updateItem(final OfferListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
hyperlink = new Hyperlink(item.getOfferId());
//hyperlink.getStyleClass().setAll("aaa");
Tooltip tooltip = new Tooltip(item.getOfferId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> openOfferDetails(item));
setGraphic(hyperlink);
}
else
{
} else {
setGraphic(null);
setId(null);
}
@ -155,17 +144,13 @@ public class OfferController extends CachedViewController
});
}
private void setRemoveColumnCellFactory()
{
private void setRemoveColumnCellFactory() {
removeColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue()));
removeColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>()
{
removeColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>() {
@Override
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> directionColumn)
{
return new TableCell<String, OfferListItem>()
{
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> directionColumn) {
return new TableCell<String, OfferListItem>() {
final ImageView iconView = ImageUtil.getIconImageView(ImageUtil.REMOVE);
final Button button = new Button();
@ -176,17 +161,13 @@ public class OfferController extends CachedViewController
}
@Override
public void updateItem(final OfferListItem offerListItem, boolean empty)
{
public void updateItem(final OfferListItem offerListItem, boolean empty) {
super.updateItem(offerListItem, empty);
if (offerListItem != null)
{
if (offerListItem != null) {
button.setOnAction(event -> removeOffer(offerListItem));
setGraphic(button);
}
else
{
} else {
setGraphic(null);
}
}

View File

@ -22,8 +22,7 @@ import io.bitsquare.trade.Offer;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class OfferListItem
{
public class OfferListItem {
private final StringProperty price = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty();
private final StringProperty date = new SimpleStringProperty();
@ -32,8 +31,7 @@ public class OfferListItem
private final Offer offer;
private final String offerId;
public OfferListItem(Offer offer)
{
public OfferListItem(Offer offer) {
this.offer = offer;
this.date.set(BitSquareFormatter.formatDateTime(offer.getCreationDate()));
@ -45,39 +43,33 @@ public class OfferListItem
}
public Offer getOffer()
{
public Offer getOffer() {
return offer;
}
// called form table columns
public final StringProperty dateProperty()
{
public final StringProperty dateProperty() {
return this.date;
}
public final StringProperty priceProperty()
{
public final StringProperty priceProperty() {
return this.price;
}
public final StringProperty amountProperty()
{
public final StringProperty amountProperty() {
return this.amount;
}
public final StringProperty volumeProperty()
{
public final StringProperty volumeProperty() {
return this.volume;
}
public String getOfferId()
{
public String getOfferId() {
return offerId;
}
}

View File

@ -37,8 +37,10 @@ import io.bitsquare.trade.Offer;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.util.AWTSystemTray;
import java.net.URL;
import java.util.*;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
@ -52,12 +54,13 @@ import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.HBox;
import javafx.util.Callback;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PendingTradeController extends CachedViewController
{
public class PendingTradeController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(PendingTradeController.class);
private TradeManager tradeManager;
@ -89,8 +92,7 @@ public class PendingTradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public PendingTradeController(TradeManager tradeManager, WalletFacade walletFacade)
{
public PendingTradeController(TradeManager tradeManager, WalletFacade walletFacade) {
this.tradeManager = tradeManager;
this.walletFacade = walletFacade;
}
@ -101,27 +103,23 @@ public class PendingTradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
Map<String, Trade> trades = tradeManager.getTrades();
List<Trade> tradeList = new ArrayList<>(trades.values());
ObservableList<PendingTradesListItem> tradeItems = FXCollections.observableArrayList();
for (Iterator<Trade> iterator = tradeList.iterator(); iterator.hasNext(); )
{
for (Iterator<Trade> iterator = tradeList.iterator(); iterator.hasNext(); ) {
Trade trade = iterator.next();
tradeItems.add(new PendingTradesListItem(trade));
}
@ -135,16 +133,14 @@ public class PendingTradeController extends CachedViewController
openTradesTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
openTradesTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
if (newValue instanceof PendingTradesListItem)
{
if (newValue instanceof PendingTradesListItem) {
showTradeDetails((PendingTradesListItem) newValue);
}
});
tradeManager.getNewTradeProperty().addListener((observableValue, oldTradeId, newTradeId) -> {
Trade newTrade = tradeManager.getTrade(newTradeId);
if (newTrade != null)
{
if (newTrade != null) {
tradeItems.add(new PendingTradesListItem(newTrade));
}
});
@ -153,16 +149,14 @@ public class PendingTradeController extends CachedViewController
// select
Optional<PendingTradesListItem> currentTradeItemOptional = tradeItems.stream()
.filter((e) -> tradeManager.getPendingTrade() != null && e.getTrade().getId().equals(tradeManager.getPendingTrade().getId()))
.findFirst();
if (currentTradeItemOptional.isPresent())
{
.filter((e) -> tradeManager.getPendingTrade() != null && e.getTrade().getId().equals(tradeManager.getPendingTrade().getId()))
.findFirst();
if (currentTradeItemOptional.isPresent()) {
openTradesTable.getSelectionModel().select(currentTradeItemOptional.get());
}
tradeItems.addListener((ListChangeListener<PendingTradesListItem>) change -> {
if (openTradesTable.getSelectionModel().getSelectedItem() == null && tradeItems.size() > 0)
{
if (openTradesTable.getSelectionModel().getSelectedItem() == null && tradeItems.size() > 0) {
openTradesTable.getSelectionModel().select(0);
}
});
@ -173,14 +167,12 @@ public class PendingTradeController extends CachedViewController
// GUI handlers
///////////////////////////////////////////////////////////////////////////////////////////
public void bankTransferInited()
{
public void bankTransferInited() {
tradeManager.bankTransferInited(currentTrade.getId());
bankTransferInitedButton.setDisable(true);
}
public void close()
{
public void close() {
}
@ -188,13 +180,11 @@ public class PendingTradeController extends CachedViewController
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void showTradeDetails(PendingTradesListItem tradesTableItem)
{
private void showTradeDetails(PendingTradesListItem tradesTableItem) {
fillData(tradesTableItem.getTrade());
}
private void updateTx(Transaction transaction)
{
private void updateTx(Transaction transaction) {
txTextField.setText(transaction.getHashAsString());
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction, progressIndicator);
@ -202,69 +192,54 @@ public class PendingTradeController extends CachedViewController
int depthInBlocks = transaction.getConfidence().getDepthInBlocks();
bankTransferInitedButton.setDisable(depthInBlocks == 0);
walletFacade.getWallet().addEventListener(new WalletEventListener()
{
walletFacade.getWallet().addEventListener(new WalletEventListener() {
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
{
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
int depthInBlocks = tx.getConfidence().getDepthInBlocks();
bankTransferInitedButton.setDisable(depthInBlocks == 0);
}
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
}
@Override
public void onReorganize(Wallet wallet)
{
public void onReorganize(Wallet wallet) {
}
@Override
public void onWalletChanged(Wallet wallet)
{
public void onWalletChanged(Wallet wallet) {
}
@Override
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
{
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
}
@Override
public void onKeysAdded(List<ECKey> keys)
{
public void onKeysAdded(List<ECKey> keys) {
}
});
}
private void fillData(Trade trade)
{
private void fillData(Trade trade) {
currentTrade = trade;
Transaction transaction = trade.getDepositTransaction();
if (transaction == null)
{
if (transaction == null) {
trade.depositTxChangedProperty().addListener((observableValue, aBoolean, aBoolean2) -> updateTx(trade.getDepositTransaction()));
}
else
{
} else {
updateTx(trade.getDepositTransaction());
}
// back details
if (trade.getContract() != null)
{
if (trade.getContract() != null) {
setBankData(trade);
}
else
{
} else {
trade.contractChangedProperty().addListener((observableValue, aBoolean, aBoolean2) -> setBankData(trade));
}
@ -272,10 +247,8 @@ public class PendingTradeController extends CachedViewController
trade.stateChangedProperty().addListener((observableValue, aString, aString2) -> setState(trade));
}
private void setState(Trade trade)
{
if (trade.getState() == Trade.State.COMPLETED)
{
private void setState(Trade trade) {
if (trade.getState() == Trade.State.COMPLETED) {
Transaction transaction = trade.getPayoutTransaction();
confidenceDisplay.destroy();
@ -307,8 +280,7 @@ public class PendingTradeController extends CachedViewController
}
}
private void setBankData(Trade trade)
{
private void setBankData(Trade trade) {
BankAccount bankAccount = trade.getContract().getTakerBankAccount();
bankAccountTypeTextField.setText(bankAccount.getBankAccountType().toString());
holderNameTextField.setText(bankAccount.getAccountHolderName());
@ -316,8 +288,7 @@ public class PendingTradeController extends CachedViewController
secondaryBankAccountIDTextField.setText(bankAccount.getAccountSecondaryID());
}
private void initCopyIcons()
{
private void initCopyIcons() {
AwesomeDude.setIcon(txIDCopyIcon, AwesomeIcon.COPY);
txIDCopyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
@ -356,16 +327,12 @@ public class PendingTradeController extends CachedViewController
// Table columns
///////////////////////////////////////////////////////////////////////////////////////////
private void setCountryColumnCellFactory()
{
private void setCountryColumnCellFactory() {
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
countryColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>()
{
countryColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
@Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn)
{
return new TableCell<String, PendingTradesListItem>()
{
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() {
final HBox hBox = new HBox();
{
@ -375,20 +342,16 @@ public class PendingTradeController extends CachedViewController
}
@Override
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty)
{
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
super.updateItem(tradesTableItem, empty);
hBox.getChildren().clear();
if (tradesTableItem != null)
{
if (tradesTableItem != null) {
Country country = tradesTableItem.getTrade().getOffer().getBankAccountCountry();
try
{
try {
hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png"));
} catch (Exception e)
{
} catch (Exception e) {
log.warn("Country icon not found: " + "/images/countries/" + country.getCode().toLowerCase() + ".png country name: " + country.getName());
}
Tooltip.install(this, new Tooltip(country.getName()));
@ -399,28 +362,20 @@ public class PendingTradeController extends CachedViewController
});
}
private void setBankAccountTypeColumnCellFactory()
{
private void setBankAccountTypeColumnCellFactory() {
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>()
{
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
@Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn)
{
return new TableCell<String, PendingTradesListItem>()
{
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() {
@Override
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty)
{
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
super.updateItem(tradesTableItem, empty);
if (tradesTableItem != null)
{
if (tradesTableItem != null) {
BankAccountType bankAccountType = tradesTableItem.getTrade().getOffer().getBankAccountType();
setText(Localisation.get(bankAccountType.toString()));
}
else
{
} else {
setText("");
}
}
@ -429,16 +384,12 @@ public class PendingTradeController extends CachedViewController
});
}
private void setDirectionColumnCellFactory()
{
private void setDirectionColumnCellFactory() {
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
directionColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>()
{
directionColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
@Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn)
{
return new TableCell<String, PendingTradesListItem>()
{
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() {
final ImageView iconView = new ImageView();
final Button button = new Button();
@ -448,23 +399,18 @@ public class PendingTradeController extends CachedViewController
}
@Override
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty)
{
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
super.updateItem(tradesTableItem, empty);
if (tradesTableItem != null)
{
if (tradesTableItem != null) {
String title;
Image icon;
Offer offer = tradesTableItem.getTrade().getOffer();
if (offer.getDirection() == Direction.SELL)
{
if (offer.getDirection() == Direction.SELL) {
icon = buyIcon;
title = BitSquareFormatter.formatDirection(Direction.BUY, true);
}
else
{
} else {
icon = sellIcon;
title = BitSquareFormatter.formatDirection(Direction.SELL, true);
}
@ -472,9 +418,7 @@ public class PendingTradeController extends CachedViewController
iconView.setImage(icon);
button.setText(title);
setGraphic(button);
}
else
{
} else {
setGraphic(null);
}
}
@ -483,30 +427,22 @@ public class PendingTradeController extends CachedViewController
});
}
private void setSelectColumnCellFactory()
{
private void setSelectColumnCellFactory() {
selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
selectColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>()
{
selectColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() {
@Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn)
{
return new TableCell<String, PendingTradesListItem>()
{
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() {
final Button button = new Button("Select");
@Override
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty)
{
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
super.updateItem(tradesTableItem, empty);
if (tradesTableItem != null)
{
if (tradesTableItem != null) {
button.setOnAction(event -> showTradeDetails(tradesTableItem));
setGraphic(button);
}
else
{
} else {
setGraphic(null);
}
}

View File

@ -22,22 +22,19 @@ import io.bitsquare.trade.Trade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PendingTradesListItem extends OrderBookListItem
{
public class PendingTradesListItem extends OrderBookListItem {
private static final Logger log = LoggerFactory.getLogger(PendingTradesListItem.class);
private final Trade trade;
public PendingTradesListItem(Trade trade)
{
public PendingTradesListItem(Trade trade) {
super(trade.getOffer());
this.trade = trade;
}
public Trade getTrade()
{
public Trade getTrade() {
return trade;
}

View File

@ -37,9 +37,11 @@ import io.bitsquare.user.Arbitrator;
import io.bitsquare.user.Reputation;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
@ -54,13 +56,14 @@ import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
import javax.inject.Inject;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
// TODO separate in 2 view/controllers
public class SettingsController extends CachedViewController
{
public class SettingsController extends CachedViewController {
private final User user;
private final Settings settings;
private final Persistence persistence;
@ -89,29 +92,24 @@ public class SettingsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public SettingsController(User user, Settings settings, Persistence persistence, MessageFacade messageFacade)
{
public SettingsController(User user, Settings settings, Persistence persistence, MessageFacade messageFacade) {
this.user = user;
this.settings = settings;
this.persistence = persistence;
this.messageFacade = messageFacade;
Settings persistedSettings = (Settings) persistence.read(settings);
if (persistedSettings != null)
{
if (persistedSettings != null) {
settings.applyPersistedSettings(persistedSettings);
languageList = FXCollections.observableArrayList(settings.getAcceptedLanguageLocales());
countryList = FXCollections.observableArrayList(settings.getAcceptedCountries());
arbitratorList = FXCollections.observableArrayList(settings.getAcceptedArbitrators());
}
else
{
} else {
languageList = FXCollections.observableArrayList(new ArrayList<>());
countryList = FXCollections.observableArrayList(new ArrayList<>());
arbitratorList = FXCollections.observableArrayList(new ArrayList<>());
if (Locale.getDefault() != null)
{
if (Locale.getDefault() != null) {
addLanguage(LanguageUtil.getDefaultLanguageLocale());
addCountry(CountryUtil.getDefaultCountry());
}
@ -126,8 +124,7 @@ public class SettingsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
setupGeneralSettingsScreen();
@ -136,14 +133,12 @@ public class SettingsController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -153,13 +148,11 @@ public class SettingsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
// TODO
// caching causes exception
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
try
{
try {
final Node view = loader.load();
childController = loader.getController();
childController.setParentController(this);
@ -184,8 +177,7 @@ public class SettingsController extends CachedViewController
stage.show();
return childController;
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return null;
@ -196,8 +188,7 @@ public class SettingsController extends CachedViewController
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
void updateArbitrators()
{
void updateArbitrators() {
arbitratorList = FXCollections.observableArrayList(settings.getAcceptedArbitrators());
initArbitrators();
}
@ -209,41 +200,35 @@ public class SettingsController extends CachedViewController
// General Settings
@FXML
public void onAddLanguage()
{
public void onAddLanguage() {
addLanguage(languageComboBox.getSelectionModel().getSelectedItem());
languageComboBox.getSelectionModel().clearSelection();
}
@FXML
public void onSelectRegion()
{
public void onSelectRegion() {
countryComboBox.setVisible(true);
Region selectedRegion = regionComboBox.getSelectionModel().getSelectedItem();
countryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion)));
}
@FXML
public void onAddCountry()
{
public void onAddCountry() {
addCountry(countryComboBox.getSelectionModel().getSelectedItem());
countryComboBox.getSelectionModel().clearSelection();
}
@FXML
public void onOpenArbitratorScreen()
{
public void onOpenArbitratorScreen() {
loadViewAndGetChildController(NavigationItem.ARBITRATOR_OVERVIEW);
}
// Bank Account Settings
@FXML
public void selectBankAccount()
{
public void selectBankAccount() {
BankAccount bankAccount = bankAccountComboBox.getSelectionModel().getSelectedItem();
if (bankAccount != null && bankAccount != user.getCurrentBankAccount())
{
if (bankAccount != null && bankAccount != user.getCurrentBankAccount()) {
user.setCurrentBankAccount(bankAccount);
persistence.write(user);
fillWithCurrentBankAccount();
@ -251,11 +236,9 @@ public class SettingsController extends CachedViewController
}
@FXML
public void selectBankAccountType()
{
public void selectBankAccountType() {
BankAccountType bankAccountType = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
if (bankAccountType != null)
{
if (bankAccountType != null) {
bankAccountTitleTextField.setText("");
bankAccountPrimaryIDTextField.setText("");
bankAccountPrimaryIDTextField.setPromptText(bankAccountType.getPrimaryId());
@ -265,29 +248,25 @@ public class SettingsController extends CachedViewController
}
@FXML
public void onSelectBankAccountRegion()
{
public void onSelectBankAccountRegion() {
bankAccountCountryComboBox.setVisible(true);
Region selectedBankAccountRegion = bankAccountRegionComboBox.getSelectionModel().getSelectedItem();
bankAccountCountryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedBankAccountRegion)));
}
@FXML
public void onAddBankAccount()
{
public void onAddBankAccount() {
saveBankAccount();
resetBankAccountInput();
}
@FXML
public void onRemoveBankAccount()
{
public void onRemoveBankAccount() {
removeBankAccount();
}
@FXML
void onSaveBankAccount()
{
void onSaveBankAccount() {
saveBankAccount();
}
@ -296,23 +275,18 @@ public class SettingsController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
// General Settings
private void setupGeneralSettingsScreen()
{
private void setupGeneralSettingsScreen() {
initLanguage();
initCountry();
initArbitrators();
}
private void initLanguage()
{
languagesListView.setCellFactory(new Callback<ListView<Locale>, ListCell<Locale>>()
{
private void initLanguage() {
languagesListView.setCellFactory(new Callback<ListView<Locale>, ListCell<Locale>>() {
@Override
public ListCell<Locale> call(ListView<Locale> list)
{
return new ListCell<Locale>()
{
public ListCell<Locale> call(ListView<Locale> list) {
return new ListCell<Locale>() {
final HBox hBox = new HBox();
final Label label = new Label();
final Button removeButton = new Button();
@ -332,17 +306,13 @@ public class SettingsController extends CachedViewController
}
@Override
public void updateItem(final Locale item, boolean empty)
{
public void updateItem(final Locale item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
label.setText(item.getDisplayName());
removeButton.setOnAction(actionEvent -> removeLanguage(item));
setGraphic(hBox);
}
else
{
} else {
setGraphic(null);
}
}
@ -352,50 +322,40 @@ public class SettingsController extends CachedViewController
languagesListView.setItems(languageList);
languageComboBox.setItems(FXCollections.observableArrayList(LanguageUtil.getAllLanguageLocales()));
languageComboBox.setConverter(new StringConverter<Locale>()
{
languageComboBox.setConverter(new StringConverter<Locale>() {
@Override
public String toString(Locale locale)
{
public String toString(Locale locale) {
return locale.getDisplayLanguage();
}
@Override
public Locale fromString(String s)
{
public Locale fromString(String s) {
return null;
}
});
}
private void initCountry()
{
private void initCountry() {
regionComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllRegions()));
regionComboBox.setConverter(new StringConverter<Region>()
{
regionComboBox.setConverter(new StringConverter<Region>() {
@Override
public String toString(Region region)
{
public String toString(Region region) {
return region.getName();
}
@Override
public Region fromString(String s)
{
public Region fromString(String s) {
return null;
}
});
countriesListView.setCellFactory(new Callback<ListView<Country>, ListCell<Country>>()
{
countriesListView.setCellFactory(new Callback<ListView<Country>, ListCell<Country>>() {
@Override
public ListCell<Country> call(ListView<Country> list)
{
return new ListCell<Country>()
{
public ListCell<Country> call(ListView<Country> list) {
return new ListCell<Country>() {
final HBox hBox = new HBox();
final Label label = new Label();
final Button removeButton = new Button();
@ -416,17 +376,13 @@ public class SettingsController extends CachedViewController
@Override
public void updateItem(final Country item, boolean empty)
{
public void updateItem(final Country item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
label.setText(item.getName());
removeButton.setOnAction(actionEvent -> removeCountry(item));
setGraphic(hBox);
}
else
{
} else {
setGraphic(null);
}
}
@ -435,35 +391,28 @@ public class SettingsController extends CachedViewController
});
countriesListView.setItems(countryList);
countryComboBox.setConverter(new StringConverter<Country>()
{
countryComboBox.setConverter(new StringConverter<Country>() {
@Override
public String toString(Country country)
{
public String toString(Country country) {
return country.getName();
}
@Override
public Country fromString(String s)
{
public Country fromString(String s) {
return null;
}
});
}
private void initArbitrators()
{
arbitratorsListView.setCellFactory(new Callback<ListView<Arbitrator>, ListCell<Arbitrator>>()
{
private void initArbitrators() {
arbitratorsListView.setCellFactory(new Callback<ListView<Arbitrator>, ListCell<Arbitrator>>() {
@Override
public ListCell<Arbitrator> call(ListView<Arbitrator> list)
{
return new ListCell<Arbitrator>()
{
public ListCell<Arbitrator> call(ListView<Arbitrator> list) {
return new ListCell<Arbitrator>() {
final HBox hBox = new HBox();
final Label label = new Label();
final Button removeButton = new Button();
@ -484,17 +433,13 @@ public class SettingsController extends CachedViewController
@Override
public void updateItem(final Arbitrator item, boolean empty)
{
public void updateItem(final Arbitrator item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty)
{
if (item != null && !empty) {
label.setText(item.getName());
removeButton.setOnAction(actionEvent -> removeArbitrator(item));
setGraphic(hBox);
}
else
{
} else {
setGraphic(null);
}
}
@ -504,78 +449,64 @@ public class SettingsController extends CachedViewController
arbitratorsListView.setItems(arbitratorList);
}
private void addLanguage(Locale locale)
{
if (locale != null && !languageList.contains(locale))
{
private void addLanguage(Locale locale) {
if (locale != null && !languageList.contains(locale)) {
languageList.add(locale);
settings.addAcceptedLanguageLocale(locale);
}
}
private void removeLanguage(Locale locale)
{
private void removeLanguage(Locale locale) {
languageList.remove(locale);
settings.removeAcceptedLanguageLocale(locale);
saveSettings();
}
private void addCountry(Country country)
{
if (!countryList.contains(country) && country != null)
{
private void addCountry(Country country) {
if (!countryList.contains(country) && country != null) {
countryList.add(country);
settings.addAcceptedCountry(country);
saveSettings();
}
}
private void removeCountry(Country country)
{
private void removeCountry(Country country) {
countryList.remove(country);
settings.removeAcceptedCountry(country);
saveSettings();
}
private void removeArbitrator(Arbitrator arbitrator)
{
private void removeArbitrator(Arbitrator arbitrator) {
arbitratorList.remove(arbitrator);
settings.removeAcceptedArbitrator(arbitrator);
saveSettings();
}
private void saveSettings()
{
private void saveSettings() {
persistence.write(settings);
}
private void saveUser()
{
private void saveUser() {
persistence.write(user);
}
// Bank Account Settings
private void fillWithCurrentBankAccount()
{
private void fillWithCurrentBankAccount() {
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
if (currentBankAccount != null) {
bankAccountTitleTextField.setText(currentBankAccount.getAccountTitle());
bankAccountHolderNameTextField.setText(currentBankAccount.getAccountHolderName());
bankAccountPrimaryIDTextField.setText(currentBankAccount.getAccountPrimaryID());
bankAccountPrimaryIDTextField.setPromptText(currentBankAccount.getBankAccountType().getPrimaryId());
bankAccountSecondaryIDTextField.setText(currentBankAccount.getAccountSecondaryID());
bankAccountSecondaryIDTextField.setPromptText(currentBankAccount.getBankAccountType().getSecondaryId());
}
else
{
} else {
resetBankAccountInput();
}
}
private void initBankAccountScreen()
{
private void initBankAccountScreen() {
initBankAccountComboBox();
initBankAccountTypesComboBox();
initBankAccountCurrencyComboBox();
@ -584,8 +515,7 @@ public class SettingsController extends CachedViewController
fillWithCurrentBankAccount();
//TODO
if (BitSquare.fillFormsWithDummyData)
{
if (BitSquare.fillFormsWithDummyData) {
bankAccountTypesComboBox.getSelectionModel().selectFirst();
bankAccountCurrencyComboBox.getSelectionModel().selectFirst();
bankAccountRegionComboBox.getSelectionModel().select(3);
@ -604,8 +534,7 @@ public class SettingsController extends CachedViewController
}
}
private void resetBankAccountInput()
{
private void resetBankAccountInput() {
bankAccountTitleTextField.setText("");
bankAccountHolderNameTextField.setText("");
bankAccountPrimaryIDTextField.setText("");
@ -617,136 +546,110 @@ public class SettingsController extends CachedViewController
bankAccountCurrencyComboBox.getSelectionModel().clearSelection();
}
private void initBankAccountComboBox()
{
if (user.getBankAccounts().isEmpty())
{
private void initBankAccountComboBox() {
if (user.getBankAccounts().isEmpty()) {
bankAccountComboBox.setPromptText("No bank account available");
bankAccountComboBox.setDisable(true);
}
else
{
} else {
bankAccountComboBox.setPromptText("Select bank account");
bankAccountComboBox.setDisable(false);
bankAccountComboBox.setItems(FXCollections.observableArrayList(user.getBankAccounts()));
bankAccountComboBox.setConverter(new StringConverter<BankAccount>()
{
bankAccountComboBox.setConverter(new StringConverter<BankAccount>() {
@Override
public String toString(BankAccount bankAccount)
{
public String toString(BankAccount bankAccount) {
return bankAccount.getAccountTitle();
}
@Override
public BankAccount fromString(String s)
{
public BankAccount fromString(String s) {
return null;
}
});
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
if (currentBankAccount != null) {
int index = bankAccountComboBox.getItems().indexOf(currentBankAccount);
bankAccountComboBox.getSelectionModel().select(index);
}
}
}
private void initBankAccountTypesComboBox()
{
private void initBankAccountTypesComboBox() {
bankAccountTypesComboBox.setItems(FXCollections.observableArrayList(BankAccountType.getAllBankAccountTypes()));
bankAccountTypesComboBox.setConverter(new StringConverter<BankAccountType>()
{
bankAccountTypesComboBox.setConverter(new StringConverter<BankAccountType>() {
@Override
public String toString(BankAccountType bankAccountTypeInfo)
{
public String toString(BankAccountType bankAccountTypeInfo) {
return Localisation.get(bankAccountTypeInfo.toString());
}
@Override
public BankAccountType fromString(String s)
{
public BankAccountType fromString(String s) {
return null;
}
});
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
if (currentBankAccount != null) {
int index = bankAccountTypesComboBox.getItems().indexOf(currentBankAccount.getBankAccountType());
bankAccountTypesComboBox.getSelectionModel().select(index);
}
}
private void initBankAccountCurrencyComboBox()
{
private void initBankAccountCurrencyComboBox() {
bankAccountCurrencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getAllCurrencies()));
bankAccountCurrencyComboBox.setConverter(new StringConverter<Currency>()
{
bankAccountCurrencyComboBox.setConverter(new StringConverter<Currency>() {
@Override
public String toString(Currency currency)
{
public String toString(Currency currency) {
return currency.getCurrencyCode() + " (" + currency.getDisplayName() + ")";
}
@Override
public Currency fromString(String s)
{
public Currency fromString(String s) {
return null;
}
});
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
if (currentBankAccount != null) {
Currency currentCurrency = currentBankAccount.getCurrency();
int index = bankAccountCurrencyComboBox.getItems().indexOf(currentCurrency);
bankAccountCurrencyComboBox.getSelectionModel().select(index);
}
}
private void initBankAccountCountryComboBox()
{
private void initBankAccountCountryComboBox() {
bankAccountRegionComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllRegions()));
bankAccountRegionComboBox.setConverter(new StringConverter<Region>()
{
bankAccountRegionComboBox.setConverter(new StringConverter<Region>() {
@Override
public String toString(Region region)
{
public String toString(Region region) {
return region.getName();
}
@Override
public Region fromString(String s)
{
public Region fromString(String s) {
return null;
}
});
bankAccountCountryComboBox.setConverter(new StringConverter<Country>()
{
bankAccountCountryComboBox.setConverter(new StringConverter<Country>() {
@Override
public String toString(Country country)
{
public String toString(Country country) {
return country.getName();
}
@Override
public Country fromString(String s)
{
public Country fromString(String s) {
return null;
}
});
BankAccount currentBankAccount = user.getCurrentBankAccount();
if (currentBankAccount != null)
{
if (currentBankAccount != null) {
Country currentCountry = currentBankAccount.getCountry();
Region currentRegion = currentCountry.getRegion();
int regionIndex = bankAccountRegionComboBox.getItems().indexOf(currentRegion);
@ -758,39 +661,35 @@ public class SettingsController extends CachedViewController
}
}
private void saveBankAccount()
{
if (verifyBankAccountData())
{
private void saveBankAccount() {
if (verifyBankAccountData()) {
BankAccount bankAccount = new BankAccount(bankAccountTypesComboBox.getSelectionModel().getSelectedItem(),
bankAccountCurrencyComboBox.getSelectionModel().getSelectedItem(),
bankAccountCountryComboBox.getSelectionModel().getSelectedItem(),
bankAccountTitleTextField.getText(),
bankAccountHolderNameTextField.getText(),
bankAccountPrimaryIDTextField.getText(),
bankAccountSecondaryIDTextField.getText());
bankAccountCurrencyComboBox.getSelectionModel().getSelectedItem(),
bankAccountCountryComboBox.getSelectionModel().getSelectedItem(),
bankAccountTitleTextField.getText(),
bankAccountHolderNameTextField.getText(),
bankAccountPrimaryIDTextField.getText(),
bankAccountSecondaryIDTextField.getText());
user.addBankAccount(bankAccount);
saveUser();
if (!settings.getAcceptedCountries().contains(bankAccount.getCountry()))
{
if (!settings.getAcceptedCountries().contains(bankAccount.getCountry())) {
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?",
null,
actions);
"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);
if (response == Dialog.Actions.YES)
addCountry(bankAccount.getCountry());
}
}
}
private void removeBankAccount()
{
private void removeBankAccount() {
user.removeCurrentBankAccount();
saveUser();
@ -798,10 +697,8 @@ public class SettingsController extends CachedViewController
fillWithCurrentBankAccount();
}
private boolean verifyBankAccountData()
{
try
{
private boolean verifyBankAccountData() {
try {
BitSquareValidator.textFieldsNotEmptyWithReset(bankAccountTitleTextField, bankAccountHolderNameTextField, bankAccountPrimaryIDTextField, bankAccountSecondaryIDTextField);
BankAccountType bankAccountTypeInfo = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
@ -809,11 +706,10 @@ public class SettingsController extends CachedViewController
BitSquareValidator.textFieldBankAccountSecondaryIDIsValid(bankAccountSecondaryIDTextField, bankAccountTypeInfo);
return bankAccountTypesComboBox.getSelectionModel().getSelectedItem() != null && bankAccountCountryComboBox.getSelectionModel()
.getSelectedItem() != null && bankAccountCurrencyComboBox.getSelectionModel()
.getSelectedItem() !=
.getSelectedItem() != null && bankAccountCurrencyComboBox.getSelectionModel()
.getSelectedItem() !=
null;
} catch (BitSquareValidator.ValidationException e)
{
} catch (BitSquareValidator.ValidationException e) {
return false;
}
}
@ -823,10 +719,8 @@ public class SettingsController extends CachedViewController
// Arbitrators
///////////////////////////////////////////////////////////////////////////////////////////
private void addMockArbitrator()
{
if (settings.getAcceptedArbitrators().isEmpty())
{
private void addMockArbitrator() {
if (settings.getAcceptedArbitrators().isEmpty()) {
String pubKeyAsHex = Utils.HEX.encode(new ECKey().getPubKey());
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePublicKey());
List<Locale> languages = new ArrayList<>();
@ -838,20 +732,20 @@ public class SettingsController extends CachedViewController
idVerifications.add(Arbitrator.ID_VERIFICATION.GOV_ID);
Arbitrator arbitrator = new Arbitrator(pubKeyAsHex,
messagePubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
languages,
new Reputation(),
1,
0.01,
0.001,
10,
0.1,
arbitrationMethods,
idVerifications,
"http://bitsquare.io/",
"Bla bla...");
messagePubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
languages,
new Reputation(),
1,
0.01,
0.001,
10,
0.1,
arbitrationMethods,
idVerifications,
"http://bitsquare.io/",
"Bla bla...");
arbitratorList.add(arbitrator);
settings.addAcceptedArbitrator(arbitrator);

View File

@ -19,11 +19,9 @@ package io.bitsquare.gui.trade;
import io.bitsquare.trade.Direction;
public class BuyController extends TradeController
{
public class BuyController extends TradeController {
@Override
protected void applyDirection()
{
protected void applyDirection() {
//tabPane.getSelectionModel().select(0);
orderBookController.applyDirection(Direction.BUY);
}

View File

@ -19,11 +19,9 @@ package io.bitsquare.gui.trade;
import io.bitsquare.trade.Direction;
public class SellController extends TradeController
{
public class SellController extends TradeController {
@Override
protected void applyDirection()
{
protected void applyDirection() {
orderBookController.applyDirection(Direction.SELL);
}

View File

@ -26,9 +26,11 @@ import io.bitsquare.gui.trade.createoffer.CreateOfferController;
import io.bitsquare.gui.trade.orderbook.OrderBookController;
import io.bitsquare.gui.trade.takeoffer.TakerOfferController;
import io.bitsquare.trade.Direction;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.scene.Parent;
import javafx.scene.control.Tab;
@ -38,8 +40,7 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
public class TradeController extends CachedViewController
{
public class TradeController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(TradeController.class);
protected OrderBookController orderBookController;
@ -53,22 +54,19 @@ public class TradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
loadViewAndGetChildController(NavigationItem.ORDER_BOOK);
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
}
@Override
public void activate()
{
public void activate() {
super.activate();
applyDirection();
@ -84,37 +82,30 @@ public class TradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
TabPane tabPane = (TabPane) root;
if (navigationItem == NavigationItem.ORDER_BOOK)
{
if (navigationItem == NavigationItem.ORDER_BOOK) {
checkArgument(orderBookLoader == null);
// Orderbook must not be cached by GuiceFXMLLoader as we use 2 instances for sell and buy screens.
orderBookLoader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.ORDER_BOOK.getFxmlUrl()), false);
try
{
try {
final Parent view = orderBookLoader.load();
final Tab tab = new Tab("Orderbook");
tab.setClosable(false);
tab.setContent(view);
tabPane.getTabs().add(tab);
} catch (IOException e)
{
} catch (IOException e) {
log.error(e.getMessage());
}
orderBookController = orderBookLoader.getController();
orderBookController.setParentController(this);
return orderBookController;
}
else if (navigationItem == NavigationItem.CREATE_OFFER)
{
} else if (navigationItem == NavigationItem.CREATE_OFFER) {
checkArgument(createOfferController == null);
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times in different graphs
GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
try
{
try {
final Parent view = loader.load();
createOfferController = loader.getController();
createOfferController.setParentController(this);
@ -123,20 +114,16 @@ public class TradeController extends CachedViewController
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1);
return createOfferController;
} catch (IOException e)
{
} catch (IOException e) {
log.error(e.getMessage());
}
return null;
}
else if (navigationItem == NavigationItem.TAKE_OFFER)
{
} else if (navigationItem == NavigationItem.TAKE_OFFER) {
checkArgument(takerOfferController == null);
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times in different graphs
GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
try
{
try {
final Parent view = loader.load();
takerOfferController = loader.getController();
takerOfferController.setParentController(this);
@ -145,14 +132,11 @@ public class TradeController extends CachedViewController
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1);
return takerOfferController;
} catch (IOException e)
{
} catch (IOException e) {
log.error(e.getMessage());
}
return null;
}
else
{
} else {
log.error("navigationItem not supported: " + navigationItem);
return null;
}
@ -163,15 +147,13 @@ public class TradeController extends CachedViewController
// Public
///////////////////////////////////////////////////////////////////////////////////////////
public void onCreateOfferViewRemoved()
{
public void onCreateOfferViewRemoved() {
createOfferController = null;
orderBookController.onCreateOfferViewRemoved();
}
public void onTakeOfferViewRemoved()
{
public void onTakeOfferViewRemoved() {
takerOfferController = null;
}
@ -181,8 +163,7 @@ public class TradeController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
// Template method to be overwritten by sub class.
protected void applyDirection()
{
protected void applyDirection() {
orderBookController.applyDirection(Direction.SELL);
}

View File

@ -39,10 +39,12 @@ import io.bitsquare.trade.Direction;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User;
import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
import java.util.UUID;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
@ -54,12 +56,13 @@ import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Region;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CreateOfferController extends CachedViewController
{
public class CreateOfferController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class);
@ -88,8 +91,7 @@ public class CreateOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
CreateOfferController(TradeManager tradeManager, WalletFacade walletFacade, Settings settings, User user)
{
CreateOfferController(TradeManager tradeManager, WalletFacade walletFacade, Settings settings, User user) {
this.tradeManager = tradeManager;
this.walletFacade = walletFacade;
@ -97,8 +99,7 @@ public class CreateOfferController extends CachedViewController
viewModel.collateralLabel.set("Collateral (" + BitSquareFormatter.formatCollateralPercent(collateral) + "):");
BankAccount bankAccount = user.getCurrentBankAccount();
if (bankAccount != null)
{
if (bankAccount != null) {
viewModel.bankAccountType.set(Localisation.get(bankAccount.getBankAccountType().toString()));
viewModel.bankAccountCurrency.set(bankAccount.getCurrency().getCurrencyCode());
viewModel.bankAccountCounty.set(bankAccount.getCountry().getName());
@ -116,16 +117,14 @@ public class CreateOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
setupBindings();
setupValidation();
//TODO just for dev testing
if (BitSquare.fillFormsWithDummyData)
{
if (BitSquare.fillFormsWithDummyData) {
amountTextField.setText("1.0");
minAmountTextField.setText("0.1");
priceTextField.setText("" + (int) (499 - new Random().nextDouble() * 1000 / 100));
@ -133,8 +132,7 @@ public class CreateOfferController extends CachedViewController
//TODO
if (walletFacade.getWallet() != null)
{
if (walletFacade.getWallet() != null) {
addressEntry = walletFacade.getAddressInfoByTradeID(offerId);
addressTextField.setAddress(addressEntry.getAddress().toString());
@ -144,15 +142,13 @@ public class CreateOfferController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
((TradeController) parentController).onCreateOfferViewRemoved();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -161,8 +157,7 @@ public class CreateOfferController extends CachedViewController
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setOrderBookFilter(OrderBookFilter orderBookFilter)
{
public void setOrderBookFilter(OrderBookFilter orderBookFilter) {
direction = orderBookFilter.getDirection();
viewModel.directionLabel.set(BitSquareFormatter.formatDirection(direction, false) + ":");
@ -176,8 +171,7 @@ public class CreateOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onPlaceOffer()
{
public void onPlaceOffer() {
amountTextField.reValidate();
minAmountTextField.reValidate();
volumeTextField.reValidate();
@ -185,29 +179,27 @@ public class CreateOfferController extends CachedViewController
//balanceTextField.getBalance()
if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() && amountTextField.getIsValid())
{
if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() && amountTextField.getIsValid()) {
viewModel.isPlaceOfferButtonDisabled.set(true);
tradeManager.requestPlaceOffer(offerId,
direction,
BitSquareFormatter.parseToDouble(viewModel.price.get()),
BitSquareFormatter.parseToCoin(viewModel.amount.get()),
BitSquareFormatter.parseToCoin(viewModel.minAmount.get()),
(transaction) -> {
viewModel.isOfferPlacedScreen.set(true);
viewModel.transactionId.set(transaction.getHashAsString());
},
errorMessage -> {
Popups.openErrorPopup("An error occurred", errorMessage);
viewModel.isPlaceOfferButtonDisabled.set(false);
});
direction,
BitSquareFormatter.parseToDouble(viewModel.price.get()),
BitSquareFormatter.parseToCoin(viewModel.amount.get()),
BitSquareFormatter.parseToCoin(viewModel.minAmount.get()),
(transaction) -> {
viewModel.isOfferPlacedScreen.set(true);
viewModel.transactionId.set(transaction.getHashAsString());
},
errorMessage -> {
Popups.openErrorPopup("An error occurred", errorMessage);
viewModel.isPlaceOfferButtonDisabled.set(false);
});
}
}
@FXML
public void onClose()
{
public void onClose() {
TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
}
@ -217,8 +209,7 @@ public class CreateOfferController extends CachedViewController
// Private Methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupBindings()
{
private void setupBindings() {
// TODO check that entered decimal places are nto exceeded supported
viewModel.amount.addListener((ov, oldValue, newValue) -> {
@ -240,8 +231,7 @@ public class CreateOfferController extends CachedViewController
viewModel.volume.addListener((ov, oldValue, newValue) -> {
double volume = BitSquareFormatter.parseToDouble(newValue);
double price = BitSquareFormatter.parseToDouble(viewModel.price.get());
if (price != 0)
{
if (price != 0) {
double amount = volume / price;
viewModel.amount.set(BitSquareFormatter.formatVolume(amount));
viewModel.totals.set(BitSquareFormatter.formatTotalsAsBtc(viewModel.amount.get(), collateral, FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE)));
@ -250,10 +240,8 @@ public class CreateOfferController extends CachedViewController
});
volumeTextField.focusedProperty().addListener((observableValue, oldValue, newValue) -> {
if (oldValue && !newValue)
{
if (!volumeTextField.getText().equals(viewModel.volume.get()))
{
if (oldValue && !newValue) {
if (!volumeTextField.getText().equals(viewModel.volume.get())) {
Popups.openWarningPopup("Warning", "The total volume you have entered leads to invalid fractional Bitcoin amounts.\nThe amount has been adjusted and a new total volume be calculated from it.");
volumeTextField.setText(viewModel.volume.get());
}
@ -290,13 +278,12 @@ public class CreateOfferController extends CachedViewController
*/
placeOfferButton.disableProperty().bind(amountTextField.isValidProperty()
.and(minAmountTextField.isValidProperty())
.and(volumeTextField.isValidProperty())
.and(priceTextField.isValidProperty()).not());
.and(minAmountTextField.isValidProperty())
.and(volumeTextField.isValidProperty())
.and(priceTextField.isValidProperty()).not());
}
private void setupValidation()
{
private void setupValidation() {
BtcValidator amountValidator = new BtcValidator();
amountTextField.setNumberValidator(amountValidator);
amountTextField.setErrorPopupLayoutReference((Region) amountTextField.getParent());
@ -312,11 +299,11 @@ public class CreateOfferController extends CachedViewController
minAmountTextField.setNumberValidator(minAmountValidator);
ValidationHelper.setupMinAmountInRangeOfAmountValidation(amountTextField,
minAmountTextField,
viewModel.amount,
viewModel.minAmount,
amountValidator,
minAmountValidator);
minAmountTextField,
viewModel.amount,
viewModel.minAmount,
amountValidator,
minAmountValidator);
amountTextField.focusedProperty().addListener((ov, oldValue, newValue) -> {
// only on focus out and ignore focus loss from window
@ -339,8 +326,7 @@ public class CreateOfferController extends CachedViewController
/**
* Represents the visible state of the view
*/
class ViewModel
{
class ViewModel {
final StringProperty amount = new SimpleStringProperty();
final StringProperty minAmount = new SimpleStringProperty();
final StringProperty price = new SimpleStringProperty();

View File

@ -45,6 +45,7 @@ import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User;
import io.bitsquare.util.Utilities;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.ParseException;
@ -52,6 +53,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import javafx.animation.AnimationTimer;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.transformation.SortedList;
@ -62,15 +64,16 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.util.Callback;
import javax.inject.Inject;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.Dialogs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderBookController extends CachedViewController
{
public class OrderBookController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(OrderBookController.class);
private final OrderBook orderBook;
@ -100,8 +103,7 @@ public class OrderBookController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private OrderBookController(OrderBook orderBook, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Persistence persistence)
{
private OrderBookController(OrderBook orderBook, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Persistence persistence) {
this.orderBook = orderBook;
this.user = user;
this.messageFacade = messageFacade;
@ -118,8 +120,7 @@ public class OrderBookController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
// init table
@ -129,8 +130,7 @@ public class OrderBookController extends CachedViewController
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
orderBook.cleanup();
@ -139,16 +139,14 @@ public class OrderBookController extends CachedViewController
orderBookTable.getSortOrder().clear();
offerList.comparatorProperty().unbind();
if (pollingTimer != null)
{
if (pollingTimer != null) {
pollingTimer.stop();
pollingTimer = null;
}
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -158,14 +156,12 @@ public class OrderBookController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setParentController(ViewController parentController)
{
public void setParentController(ViewController parentController) {
super.setParentController(parentController);
}
@Override
public ViewController loadViewAndGetChildController(NavigationItem navigationItem)
{
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
return null;
}
@ -174,8 +170,7 @@ public class OrderBookController extends CachedViewController
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void init()
{
private void init() {
orderBook.init();
offerList = orderBook.getOfferList();
offerList.comparatorProperty().bind(orderBookTable.comparatorProperty());
@ -211,8 +206,7 @@ public class OrderBookController extends CachedViewController
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void applyDirection(Direction direction)
{
public void applyDirection(Direction direction) {
init();
orderBookTable.getSelectionModel().clearSelection();
price.setText("");
@ -225,17 +219,13 @@ public class OrderBookController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void createOffer()
{
if (isRegistered())
{
public void createOffer() {
if (isRegistered()) {
createOfferButton.setDisable(true);
ViewController nextController = parentController.loadViewAndGetChildController(NavigationItem.CREATE_OFFER);
if (nextController != null)
((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
}
else
{
} else {
showRegistrationDialog();
}
}
@ -244,180 +234,134 @@ public class OrderBookController extends CachedViewController
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private boolean isRegistered()
{
private boolean isRegistered() {
return user.getAccountId() != null;
}
private boolean areSettingsValid()
{
private boolean areSettingsValid() {
return !settings.getAcceptedLanguageLocales().isEmpty() &&
!settings.getAcceptedCountries().isEmpty() &&
!settings.getAcceptedArbitrators().isEmpty() &&
user.getCurrentBankAccount() != null;
}
private void showRegistrationDialog()
{
private void showRegistrationDialog() {
int selectedIndex = -1;
if (areSettingsValid())
{
if (walletFacade.isRegistrationFeeBalanceNonZero())
{
if (walletFacade.isRegistrationFeeBalanceSufficient())
{
if (walletFacade.isRegistrationFeeConfirmed())
{
if (areSettingsValid()) {
if (walletFacade.isRegistrationFeeBalanceNonZero()) {
if (walletFacade.isRegistrationFeeBalanceSufficient()) {
if (walletFacade.isRegistrationFeeConfirmed()) {
selectedIndex = 2;
}
else
{
} 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)
{
"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
{
} else {
Action response = Popups.openErrorPopup("Missing registration fee",
"You have not funded the full registration fee of " + BitSquareFormatter.formatCoinWithCode(FeePolicy.ACCOUNT_REGISTRATION_FEE) + " BTC.");
if (response == Dialog.Actions.OK)
{
"You have not funded the full registration fee of " + BitSquareFormatter.formatCoinWithCode(FeePolicy.ACCOUNT_REGISTRATION_FEE) + " BTC.");
if (response == Dialog.Actions.OK) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
}
}
}
else
{
} else {
selectedIndex = 1;
}
}
else
{
} else {
selectedIndex = 0;
}
if (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.");
"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.");
"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)
{
"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);
}
else if (registrationMissingAction == depositFeeCommandLink)
{
} else if (registrationMissingAction == depositFeeCommandLink) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
}
else if (registrationMissingAction == sendRegistrationCommandLink)
{
} else if (registrationMissingAction == sendRegistrationCommandLink) {
payRegistrationFee();
}
}
}
private void payRegistrationFee()
{
FutureCallback<Transaction> callback = new FutureCallback<Transaction>()
{
private void payRegistrationFee() {
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
@Override
public void onSuccess(@javax.annotation.Nullable Transaction transaction)
{
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
log.debug("payRegistrationFee onSuccess");
if (transaction != null)
{
if (transaction != null) {
log.info("payRegistrationFee onSuccess tx id:" + transaction.getHashAsString());
}
}
@Override
public void onFailure(Throwable t)
{
public void onFailure(Throwable t) {
log.debug("payRegistrationFee onFailure");
}
};
try
{
try {
walletFacade.payRegistrationFee(user.getStringifiedBankAccounts(), callback);
if (walletFacade.getRegistrationAddressEntry() != null)
{
if (walletFacade.getRegistrationAddressEntry() != null) {
user.setAccountID(walletFacade.getRegistrationAddressEntry().toString());
}
persistence.write(user.getClass().getName(), user);
} catch (InsufficientMoneyException e1)
{
} catch (InsufficientMoneyException e1) {
Popups.openInsufficientMoneyPopup();
}
}
private void takeOffer(Offer offer)
{
if (isRegistered())
{
private void takeOffer(Offer offer) {
if (isRegistered()) {
TakerOfferController takerOfferController = (TakerOfferController) parentController.loadViewAndGetChildController(NavigationItem.TAKE_OFFER);
Coin requestedAmount;
if (!"".equals(amount.getText()))
{
if (!"".equals(amount.getText())) {
requestedAmount = BitSquareFormatter.parseToCoin(amount.getText());
}
else
{
} else {
requestedAmount = offer.getAmount();
}
if (takerOfferController != null)
{
if (takerOfferController != null) {
takerOfferController.initWithData(offer, requestedAmount);
}
}
else
{
} else {
showRegistrationDialog();
}
}
private void removeOffer(Offer offer)
{
private void removeOffer(Offer offer) {
orderBook.removeOffer(offer);
}
private void applyOffers()
{
private void applyOffers() {
orderBook.applyFilter(orderBookFilter);
priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING);
orderBookTable.sort();
if (orderBookTable.getItems() != null)
{
if (orderBookTable.getItems() != null) {
createOfferButton.setDefaultButton(orderBookTable.getItems().isEmpty());
}
}
private void setupPolling()
{
private void setupPolling() {
pollingTimer = Utilities.setInterval(1000, (animationTimer) -> {
if (user.getCurrentBankAccount() != null)
{
if (user.getCurrentBankAccount() != null) {
messageFacade.getDirtyFlag(user.getCurrentBankAccount().getCurrency());
}
else
{
} else {
messageFacade.getDirtyFlag(CurrencyUtil.getDefaultCurrency());
}
return null;
@ -431,17 +375,13 @@ public class OrderBookController extends CachedViewController
// Table columns
///////////////////////////////////////////////////////////////////////////////////////////
private void setDirectionColumnCellFactory()
{
private void setDirectionColumnCellFactory() {
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
directionColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
{
directionColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() {
@Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
{
return new TableCell<String, OrderBookListItem>()
{
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) {
return new TableCell<String, OrderBookListItem>() {
final ImageView iconView = new ImageView();
final Button button = new Button();
@ -451,31 +391,23 @@ public class OrderBookController extends CachedViewController
}
@Override
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
{
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
super.updateItem(orderBookListItem, empty);
if (orderBookListItem != null)
{
if (orderBookListItem != null) {
String title;
Image icon;
Offer offer = orderBookListItem.getOffer();
if (offer.getMessagePublicKey().equals(user.getMessagePublicKey()))
{
if (offer.getMessagePublicKey().equals(user.getMessagePublicKey())) {
icon = ImageUtil.getIconImage(ImageUtil.REMOVE);
title = "Remove";
button.setOnAction(event -> removeOffer(orderBookListItem.getOffer()));
}
else
{
if (offer.getDirection() == Direction.SELL)
{
} else {
if (offer.getDirection() == Direction.SELL) {
icon = buyIcon;
title = BitSquareFormatter.formatDirection(Direction.BUY, true);
}
else
{
} else {
icon = sellIcon;
title = BitSquareFormatter.formatDirection(Direction.SELL, true);
}
@ -488,9 +420,7 @@ public class OrderBookController extends CachedViewController
iconView.setImage(icon);
button.setText(title);
setGraphic(button);
}
else
{
} else {
setGraphic(null);
}
}
@ -499,17 +429,13 @@ public class OrderBookController extends CachedViewController
});
}
private void setCountryColumnCellFactory()
{
private void setCountryColumnCellFactory() {
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
countryColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
{
countryColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() {
@Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
{
return new TableCell<String, OrderBookListItem>()
{
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) {
return new TableCell<String, OrderBookListItem>() {
final HBox hBox = new HBox();
{
@ -519,20 +445,16 @@ public class OrderBookController extends CachedViewController
}
@Override
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
{
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
super.updateItem(orderBookListItem, empty);
hBox.getChildren().clear();
if (orderBookListItem != null)
{
if (orderBookListItem != null) {
Country country = orderBookListItem.getOffer().getBankAccountCountry();
try
{
try {
hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png"));
} catch (Exception e)
{
} catch (Exception e) {
log.warn("Country icon not found: " + "/images/countries/" + country.getCode().toLowerCase() + ".png country name: " + country.getName());
}
Tooltip.install(this, new Tooltip(country.getName()));
@ -543,29 +465,21 @@ public class OrderBookController extends CachedViewController
});
}
private void setBankAccountTypeColumnCellFactory()
{
private void setBankAccountTypeColumnCellFactory() {
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>()
{
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() {
@Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn)
{
return new TableCell<String, OrderBookListItem>()
{
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) {
return new TableCell<String, OrderBookListItem>() {
@Override
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty)
{
public void updateItem(final OrderBookListItem orderBookListItem, boolean empty) {
super.updateItem(orderBookListItem, empty);
if (orderBookListItem != null)
{
if (orderBookListItem != null) {
BankAccountType bankAccountType = orderBookListItem.getOffer().getBankAccountType();
setText(Localisation.get(bankAccountType.toString()));
}
else
{
} else {
setText("");
}
}
@ -580,18 +494,14 @@ public class OrderBookController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
private double textInputToNumber(String oldValue, String newValue)
{
private double textInputToNumber(String oldValue, String newValue) {
//TODO use regex.... or custom textfield component
double d = 0.0;
if (!"".equals(newValue))
{
try
{
if (!"".equals(newValue)) {
try {
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
d = decimalFormat.parse(newValue).doubleValue();
} catch (ParseException e)
{
} catch (ParseException e) {
amount.setText(oldValue);
d = BitSquareFormatter.parseToDouble(oldValue);
}
@ -599,16 +509,14 @@ public class OrderBookController extends CachedViewController
return d;
}
private void updateVolume()
{
private void updateVolume() {
double a = textInputToNumber(amount.getText(), amount.getText());
double p = textInputToNumber(price.getText(), price.getText());
volume.setText(BitSquareFormatter.formatPrice(a * p));
}
public void onCreateOfferViewRemoved()
{
public void onCreateOfferViewRemoved() {
createOfferButton.setDisable(false);
}

View File

@ -22,8 +22,7 @@ import io.bitsquare.trade.Offer;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class OrderBookListItem
{
public class OrderBookListItem {
private final StringProperty price = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty();
private final StringProperty volume = new SimpleStringProperty();
@ -32,8 +31,7 @@ public class OrderBookListItem
private final Offer offer;
public OrderBookListItem(Offer offer)
{
public OrderBookListItem(Offer offer) {
this.offer = offer;
this.price.set(BitSquareFormatter.formatPrice(offer.getPrice()));
this.amount.set(BitSquareFormatter.formatCoin(offer.getAmount()) + " (" + BitSquareFormatter.formatCoin(offer.getMinAmount()) + ")");
@ -41,27 +39,23 @@ public class OrderBookListItem
}
public Offer getOffer()
{
public Offer getOffer() {
return offer;
}
// called form table columns
public final StringProperty priceProperty()
{
public final StringProperty priceProperty() {
return this.price;
}
public final StringProperty amountProperty()
{
public final StringProperty amountProperty() {
return this.amount;
}
public final StringProperty volumeProperty()
{
public final StringProperty volumeProperty() {
return this.volume;
}
}

View File

@ -32,16 +32,19 @@ import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.protocol.taker.ProtocolForTakerAsSeller;
import io.bitsquare.trade.protocol.taker.ProtocolForTakerAsSellerListener;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TakerOfferController extends CachedViewController
{
public class TakerOfferController extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(TakerOfferController.class);
private final TradeManager tradeManager;
@ -73,8 +76,7 @@ public class TakerOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private TakerOfferController(TradeManager tradeManager, WalletFacade walletFacade)
{
private TakerOfferController(TradeManager tradeManager, WalletFacade walletFacade) {
this.tradeManager = tradeManager;
this.walletFacade = walletFacade;
}
@ -85,23 +87,20 @@ public class TakerOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void initialize(URL url, ResourceBundle rb)
{
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
accordion.setExpandedPane(takeOfferTitledPane);
}
@Override
public void deactivate()
{
public void deactivate() {
super.deactivate();
((TradeController) parentController).onTakeOfferViewRemoved();
}
@Override
public void activate()
{
public void activate() {
super.activate();
}
@ -110,19 +109,16 @@ public class TakerOfferController extends CachedViewController
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void initWithData(Offer offer, Coin requestedAmount)
{
public void initWithData(Offer offer, Coin requestedAmount) {
this.offer = offer;
this.requestedAmount = requestedAmount.compareTo(Coin.ZERO) == 0 ? offer.getAmount() : requestedAmount;
if (amountTextField != null)
{
if (amountTextField != null) {
applyData();
}
}
public void applyData()
{
public void applyData() {
amountTextField.setText(requestedAmount.toPlainString());
amountTextField.setPromptText(BitSquareFormatter.formatCoinWithCode(offer.getMinAmount()) + " - " + BitSquareFormatter.formatCoinWithCode(offer.getAmount()));
priceTextField.setText(BitSquareFormatter.formatPrice(offer.getPrice()));
@ -155,47 +151,34 @@ public class TakerOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onTakeOffer()
{
public void onTakeOffer() {
AddressEntry addressEntry = walletFacade.getAddressInfoByTradeID(offer.getId());
Coin amount = BitSquareFormatter.parseToCoin(getAmountString());
// TODO more validation (fee payment, blacklist,...)
if (amountTextField.isInvalid())
{
if (amountTextField.isInvalid()) {
Popups.openErrorPopup("Invalid input", "The requested amount you entered is not a valid amount.");
}
else if (BitSquareValidator.tradeAmountOutOfRange(amount, offer))
{
} else if (BitSquareValidator.tradeAmountOutOfRange(amount, offer)) {
Popups.openErrorPopup("Invalid input", "The requested amount you entered is outside of the range of the offered amount.");
}
else if (addressEntry == null || getTotal().compareTo(walletFacade.getBalanceForAddress(addressEntry.getAddress())) > 0)
{
} else if (addressEntry == null || getTotal().compareTo(walletFacade.getBalanceForAddress(addressEntry.getAddress())) > 0) {
Popups.openErrorPopup("Insufficient money", "You don't have enough funds for that trade.");
}
else if (tradeManager.isOfferAlreadyInTrades(offer))
{
} else if (tradeManager.isOfferAlreadyInTrades(offer)) {
Popups.openErrorPopup("Offer previously accepted", "You have that offer already taken. Open the offer section to find that trade.");
}
else
{
} else {
takeOfferButton.setDisable(true);
amountTextField.setEditable(false);
tradeManager.takeOffer(amount, offer, new ProtocolForTakerAsSellerListener()
{
tradeManager.takeOffer(amount, offer, new ProtocolForTakerAsSellerListener() {
@Override
public void onDepositTxPublished(String depositTxId)
{
public void onDepositTxPublished(String depositTxId) {
setDepositTxId(depositTxId);
accordion.setExpandedPane(waitBankTxTitledPane);
infoLabel.setText("Deposit transaction published by offerer.\n" +
"As soon as the offerer starts the \n" +
"Bank transfer, you will get informed.");
"As soon as the offerer starts the \n" +
"Bank transfer, you will get informed.");
depositTxIdTextField.setText(depositTxId);
}
@Override
public void onBankTransferInited(String tradeId)
{
public void onBankTransferInited(String tradeId) {
setTradeId(tradeId);
headLineLabel.setText("Bank transfer initiated");
infoLabel.setText("Check your bank account and continue \n" + "when you have received the money.");
@ -203,8 +186,7 @@ public class TakerOfferController extends CachedViewController
}
@Override
public void onPayoutTxPublished(Trade trade, String payoutTxId)
{
public void onPayoutTxPublished(Trade trade, String payoutTxId) {
accordion.setExpandedPane(summaryTitledPane);
summaryPaidTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getTradeAmount()));
@ -216,30 +198,26 @@ public class TakerOfferController extends CachedViewController
}
@Override
public void onFault(Throwable throwable, ProtocolForTakerAsSeller.State state)
{
public void onFault(Throwable throwable, ProtocolForTakerAsSeller.State state) {
log.error("Error while executing trade process at state: " + state + " / " + throwable);
Popups.openErrorPopup("Error while executing trade process", "Error while executing trade process at state: " + state + " / " + throwable);
}
@Override
public void onWaitingForPeerResponse(ProtocolForTakerAsSeller.State state)
{
public void onWaitingForPeerResponse(ProtocolForTakerAsSeller.State state) {
log.debug("Waiting for peers response at state " + state);
}
@Override
public void onCompleted(ProtocolForTakerAsSeller.State state)
{
public void onCompleted(ProtocolForTakerAsSeller.State state) {
log.debug("Trade protocol completed at state " + state);
}
@Override
public void onTakeOfferRequestRejected(Trade trade)
{
public void onTakeOfferRequestRejected(Trade trade) {
log.error("Take offer request rejected");
Popups.openErrorPopup("Take offer request rejected",
"Your take offer request has been rejected. It might be that the offerer got another request shortly before your request arrived.");
"Your take offer request has been rejected. It might be that the offerer got another request shortly before your request arrived.");
}
});
}
@ -247,14 +225,12 @@ public class TakerOfferController extends CachedViewController
@FXML
public void onReceivedFiat()
{
public void onReceivedFiat() {
tradeManager.onFiatReceived(tradeId);
}
@FXML
public void onClose()
{
public void onClose() {
TabPane tabPane = ((TabPane) (root.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
}
@ -264,102 +240,83 @@ public class TakerOfferController extends CachedViewController
///////////////////////////////////////////////////////////////////////////////////////////
private void applyCollateral()
{
private void applyCollateral() {
collateralTextField.setText(getFormattedCollateralAsBtc());
}
private void applyVolume()
{
private void applyVolume() {
volumeTextField.setText(getFormattedVolume());
}
private void applyTotal()
{
private void applyTotal() {
totalTextField.setText(getFormattedTotal());
}
// formatted
private String getFormattedVolume()
{
private String getFormattedVolume() {
return BitSquareFormatter.formatVolume(getVolume());
}
private String getFormattedTotal()
{
private String getFormattedTotal() {
return BitSquareFormatter.formatCoinWithCode(getTotal());
}
// values
private double getAmountAsDouble()
{
private double getAmountAsDouble() {
return BitSquareFormatter.parseToDouble(getAmountString());
}
private Coin getAmountInSatoshis()
{
private Coin getAmountInSatoshis() {
return BitSquareFormatter.parseToCoin(getAmountString());
}
private String getAmountString()
{
try
{
private String getAmountString() {
try {
BitSquareValidator.textFieldsHasPositiveDoubleValueWithReset(amountTextField);
return amountTextField.getText();
} catch (BitSquareValidator.ValidationException e)
{
} catch (BitSquareValidator.ValidationException e) {
return "0";
}
}
private double getVolume()
{
private double getVolume() {
return offer.getPrice() * getAmountAsDouble();
}
private Coin getFee()
{
private Coin getFee() {
return FeePolicy.TAKE_OFFER_FEE.add(FeePolicy.TX_FEE);
}
private Coin getTotal()
{
private Coin getTotal() {
return getFee().add(getAmountInSatoshis()).add(getCollateralAsCoin());
}
private Coin getCollateralAsCoin()
{
private Coin getCollateralAsCoin() {
Coin amountAsCoin = BitSquareFormatter.parseToCoin(getAmountString());
return amountAsCoin.divide((long) (1d / offer.getCollateral()));
}
private String getFormattedCollateralAsBtc()
{
private String getFormattedCollateralAsBtc() {
Coin amountAsCoin = BitSquareFormatter.parseToCoin(getAmountString());
Coin collateralAsCoin = amountAsCoin.divide((long) (1d / getCollateral()));
return BitSquareFormatter.formatCoin(collateralAsCoin);
}
private String getCollateralAsPercent()
{
private String getCollateralAsPercent() {
return BitSquareFormatter.formatCollateralPercent(getCollateral());
}
private double getCollateral()
{
private double getCollateral() {
// TODO
return offer.getCollateral();
}
public void setTradeId(String tradeId)
{
public void setTradeId(String tradeId) {
this.tradeId = tradeId;
}
public void setDepositTxId(String depositTxId)
{
public void setDepositTxId(String depositTxId) {
this.depositTxId = depositTxId;
}
}

View File

@ -22,11 +22,13 @@ import io.bitsquare.locale.Country;
import io.bitsquare.locale.Localisation;
import io.bitsquare.trade.Direction;
import io.bitsquare.user.Arbitrator;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,16 +36,14 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
//TODO cleanup...
public class BitSquareFormatter
{
public class BitSquareFormatter {
private static final Logger log = LoggerFactory.getLogger(BitSquareFormatter.class);
///////////////////////////////////////////////////////////////////////////////////////////
// BTC
///////////////////////////////////////////////////////////////////////////////////////////
public static String formatCoin(Coin coin)
{
public static String formatCoin(Coin coin) {
return coin != null ? coin.toPlainString() : "";
}
@ -53,8 +53,7 @@ public class BitSquareFormatter
return "฿ " + coin.toPlainString();
} */
public static String formatCoinWithCode(Coin coin)
{
public static String formatCoinWithCode(Coin coin) {
return coin != null ? coin.toFriendlyString() : "";
}
@ -63,16 +62,13 @@ public class BitSquareFormatter
* If input has an incorrect format it returns a zero value coin.
* @return
*/
public static Coin parseToCoin(String input)
{
public static Coin parseToCoin(String input) {
Coin result;
try
{
try {
input = input.replace(",", ".");
Double.parseDouble(input);
result = Coin.parseCoin(input);
} catch (Exception e)
{
} catch (Exception e) {
//log.warn("Exception at parseBtcToCoin: " + e.toString());
result = Coin.ZERO;
}
@ -84,18 +80,15 @@ public class BitSquareFormatter
// FIAT
///////////////////////////////////////////////////////////////////////////////////////////
public static String formatPrice(double price)
{
public static String formatPrice(double price) {
return formatDouble(price);
}
public static String formatVolume(double volume)
{
public static String formatVolume(double volume) {
return formatDouble(volume);
}
public static String formatVolumeWithMinVolume(double volume, double minVolume)
{
public static String formatVolumeWithMinVolume(double volume, double minVolume) {
return formatDouble(volume) + " (" + formatDouble(minVolume) + ")";
}
@ -108,58 +101,48 @@ public class BitSquareFormatter
* @param input String to be converted to a double. Both decimal points "." and "," are supported. Thousands separator is not supported.
* @return Returns a double value. Any invalid value returns Double.NEGATIVE_INFINITY.
*/
public static double parseToDouble(String input)
{
try
{
public static double parseToDouble(String input) {
try {
checkNotNull(input);
checkArgument(input.length() > 0);
input = input.replace(",", ".").trim();
return Double.parseDouble(input);
} catch (Exception e)
{
} catch (Exception e) {
return 0;
}
}
public static String formatCollateralAsBtc(String amount, double collateral)
{
public static String formatCollateralAsBtc(String amount, double collateral) {
Coin amountAsCoin = BitSquareFormatter.parseToCoin(amount);
Coin collateralAsCoin = amountAsCoin.divide((long) (1d / collateral));
return formatCoinWithCode(collateralAsCoin);
}
public static String formatTotalsAsBtc(String amount, double collateral, Coin fees)
{
public static String formatTotalsAsBtc(String amount, double collateral, Coin fees) {
Coin amountAsCoin = BitSquareFormatter.parseToCoin(amount);
Coin collateralAsCoin = amountAsCoin.divide((long) (1d / collateral));
Coin totals = collateralAsCoin.add(fees);
return formatCoinWithCode(totals);
}
public static String formatDirection(Direction direction, boolean allUpperCase)
{
public static String formatDirection(Direction direction, boolean allUpperCase) {
String result = (direction == Direction.BUY) ? "Buy" : "Sell";
if (allUpperCase)
{
if (allUpperCase) {
result = result.toUpperCase();
}
return result;
}
public static String formatDouble(double value)
{
public static String formatDouble(double value) {
return formatDouble(value, 4);
}
public static String formatDouble(double value, int fractionDigits)
{
public static String formatDouble(double value, int fractionDigits) {
DecimalFormat decimalFormat = getDecimalFormat(fractionDigits);
return decimalFormat.format(value);
}
public static DecimalFormat getDecimalFormat(int fractionDigits)
{
public static DecimalFormat getDecimalFormat(int fractionDigits) {
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
decimalFormat.setMinimumFractionDigits(fractionDigits);
decimalFormat.setMaximumFractionDigits(fractionDigits);
@ -167,32 +150,26 @@ public class BitSquareFormatter
return decimalFormat;
}
public static String countryLocalesToString(List<Country> countries)
{
public static String countryLocalesToString(List<Country> countries) {
String result = "";
int i = 0;
for (Country country : countries)
{
for (Country country : countries) {
result += country.getName();
i++;
if (i < countries.size())
{
if (i < countries.size()) {
result += ", ";
}
}
return result;
}
public static String languageLocalesToString(List<Locale> languageLocales)
{
public static String languageLocalesToString(List<Locale> languageLocales) {
String result = "";
int i = 0;
for (Locale locale : languageLocales)
{
for (Locale locale : languageLocales) {
result += locale.getDisplayLanguage();
i++;
if (i < languageLocales.size())
{
if (i < languageLocales.size()) {
result += ", ";
}
}
@ -200,16 +177,13 @@ public class BitSquareFormatter
}
public static String arbitrationMethodsToString(List<Arbitrator.METHOD> items)
{
public static String arbitrationMethodsToString(List<Arbitrator.METHOD> items) {
String result = "";
int i = 0;
for (Arbitrator.METHOD item : items)
{
for (Arbitrator.METHOD item : items) {
result += Localisation.get(item.toString());
i++;
if (i < items.size())
{
if (i < items.size()) {
result += ", ";
}
}
@ -217,31 +191,26 @@ public class BitSquareFormatter
}
public static String arbitrationIDVerificationsToString(List<Arbitrator.ID_VERIFICATION> items)
{
public static String arbitrationIDVerificationsToString(List<Arbitrator.ID_VERIFICATION> items) {
String result = "";
int i = 0;
for (Arbitrator.ID_VERIFICATION item : items)
{
for (Arbitrator.ID_VERIFICATION item : items) {
result += Localisation.get(item.toString());
i++;
if (i < items.size())
{
if (i < items.size()) {
result += ", ";
}
}
return result;
}
public static String formatDateTime(Date date)
{
public static String formatDateTime(Date date) {
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.getDefault());
DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.getDefault());
return dateFormatter.format(date) + " " + timeFormatter.format(date);
}
public static String formatCollateralPercent(double collateral)
{
public static String formatCollateralPercent(double collateral) {
return getDecimalFormat(2).format(collateral * 100) + " %";
}
}

View File

@ -28,72 +28,57 @@ import javafx.scene.paint.Color;
//TODO to be removed
@Deprecated
public class BitSquareValidator
{
public class BitSquareValidator {
private static final Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
private static final String invalidStyle = "-fx-border-color: red";
public static boolean tradeAmountOutOfRange(Coin tradeAmount, Offer offer)
{
public static boolean tradeAmountOutOfRange(Coin tradeAmount, Offer offer) {
return tradeAmount.compareTo(offer.getAmount()) > 0 || tradeAmount.compareTo(offer.getMinAmount()) < 0;
}
public static boolean greaterThanZero(Coin value)
{
public static boolean greaterThanZero(Coin value) {
return value.compareTo(Coin.ZERO) > 0;
}
public static void textFieldsNotEmptyWithReset(TextField... textFields) throws ValidationException
{
public static void textFieldsNotEmptyWithReset(TextField... textFields) throws ValidationException {
resetTextFields(textFields);
textFieldsNotEmpty(textFields);
}
public static void resetTextFields(TextField... textFields)
{
for (TextField textField : textFields)
{
public static void resetTextFields(TextField... textFields) {
for (TextField textField : textFields) {
textField.setStyle("-fx-border-color: null");
textField.setEffect(null);
}
}
public static void textFieldsNotEmpty(TextField... textFields) throws ValidationException
{
for (TextField textField : textFields)
{
public static void textFieldsNotEmpty(TextField... textFields) throws ValidationException {
for (TextField textField : textFields) {
textFieldNotEmpty(textField);
}
}
public static void textFieldNotEmpty(TextField textField) throws ValidationException
{
if (!validateStringNotEmpty(textField.getText()))
{
public static void textFieldNotEmpty(TextField textField) throws ValidationException {
if (!validateStringNotEmpty(textField.getText())) {
textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle);
throw new ValidationException();
}
}
public static void textFieldsHasDoubleValueWithReset(TextField... textFields) throws ValidationException
{
public static void textFieldsHasDoubleValueWithReset(TextField... textFields) throws ValidationException {
resetTextFields(textFields);
textFieldsHasDoubleValue(textFields);
}
public static void textFieldsHasDoubleValue(TextField... textFields) throws ValidationException
{
for (TextField textField : textFields)
{
public static void textFieldsHasDoubleValue(TextField... textFields) throws ValidationException {
for (TextField textField : textFields) {
textFieldHasDoubleValue(textField);
}
}
public static void textFieldHasDoubleValue(TextField textField) throws ValidationException
{
if (!validateStringAsDouble(textField.getText().replace(",", ".")))
{
public static void textFieldHasDoubleValue(TextField textField) throws ValidationException {
if (!validateStringAsDouble(textField.getText().replace(",", "."))) {
textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle);
throw new ValidationException();
@ -101,34 +86,26 @@ public class BitSquareValidator
}
public static void textFieldsHasPositiveDoubleValueWithReset(TextField... textFields) throws ValidationException
{
public static void textFieldsHasPositiveDoubleValueWithReset(TextField... textFields) throws ValidationException {
resetTextFields(textFields);
textFieldsHasPositiveDoubleValue(textFields);
}
public static void textFieldsHasPositiveDoubleValue(TextField... textFields) throws ValidationException
{
for (TextField textField : textFields)
{
public static void textFieldsHasPositiveDoubleValue(TextField... textFields) throws ValidationException {
for (TextField textField : textFields) {
textFieldHasPositiveDoubleValue(textField);
}
}
public static void textFieldHasPositiveDoubleValue(TextField textField) throws ValidationException
{
public static void textFieldHasPositiveDoubleValue(TextField textField) throws ValidationException {
String input = textField.getText().replace(",", ".");
if (!validateStringAsDouble(input))
{
if (!validateStringAsDouble(input)) {
textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle);
throw new ValidationException();
}
else
{
} else {
double val = Double.parseDouble(input);
if (val <= 0)
{
if (val <= 0) {
textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle);
throw new ValidationException();
@ -138,10 +115,8 @@ public class BitSquareValidator
//TODO
@SuppressWarnings("UnusedParameters")
public static void textFieldBankAccountPrimaryIDIsValid(TextField textField, BankAccountType bankAccountType) throws ValidationException
{
if (!validateStringNotEmpty(textField.getText()))
{
public static void textFieldBankAccountPrimaryIDIsValid(TextField textField, BankAccountType bankAccountType) throws ValidationException {
if (!validateStringNotEmpty(textField.getText())) {
textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle);
throw new ValidationException();
@ -150,57 +125,46 @@ public class BitSquareValidator
//TODO
@SuppressWarnings("UnusedParameters")
public static void textFieldBankAccountSecondaryIDIsValid(TextField textField, BankAccountType bankAccountType) throws ValidationException
{
if (!validateStringNotEmpty(textField.getText()))
{
public static void textFieldBankAccountSecondaryIDIsValid(TextField textField, BankAccountType bankAccountType) throws ValidationException {
if (!validateStringNotEmpty(textField.getText())) {
textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle);
throw new ValidationException();
}
}
public static boolean validateStringsAsDouble(String... inputs)
{
public static boolean validateStringsAsDouble(String... inputs) {
boolean result = true;
for (String input : inputs)
{
for (String input : inputs) {
result &= validateStringAsDouble(input);
}
return result;
}
public static boolean validateStringAsDouble(String input)
{
try
{
public static boolean validateStringAsDouble(String input) {
try {
input = input.replace(",", ".");
//noinspection ResultOfMethodCallIgnored
Double.parseDouble(input);
return true;
} catch (NumberFormatException | NullPointerException e)
{
} catch (NumberFormatException | NullPointerException e) {
return false;
}
}
public static boolean validateStringsNotEmpty(String... inputs)
{
public static boolean validateStringsNotEmpty(String... inputs) {
boolean result = true;
for (String input : inputs)
{
for (String input : inputs) {
result &= validateStringNotEmpty(input);
}
return result;
}
public static boolean validateStringNotEmpty(String input)
{
public static boolean validateStringNotEmpty(String input) {
return input != null && !input.isEmpty() && !" ".equals(input);
}
public static class ValidationException extends Exception
{
public static class ValidationException extends Exception {
private static final long serialVersionUID = -5583980308504568844L;
}

View File

@ -18,17 +18,18 @@
package io.bitsquare.gui.util;
import com.google.bitcoin.core.NetworkParameters;
import java.math.BigDecimal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* BtcValidator for validating BTC values.
* <p>
* <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 class BtcValidator extends NumberValidator {
private static final Logger log = LoggerFactory.getLogger(BtcValidator.class);
private ValidationResult externalValidationResult;
@ -38,20 +39,17 @@ public class BtcValidator extends NumberValidator
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ValidationResult validate(String input)
{
public ValidationResult validate(String input) {
if (externalValidationResult != null)
return externalValidationResult;
ValidationResult result = validateIfNotEmpty(input);
if (result.isValid)
{
if (result.isValid) {
input = cleanInput(input);
result = validateIfNumber(input);
}
if (result.isValid)
{
if (result.isValid) {
result = validateIfNotZero(input)
.and(validateIfNotNegative(input))
.and(validateIfNotFractionalBtcValue(input))
@ -67,8 +65,7 @@ public class BtcValidator extends NumberValidator
*
* @param externalValidationResult
*/
public void overrideResult(ValidationResult externalValidationResult)
{
public void overrideResult(ValidationResult externalValidationResult) {
this.externalValidationResult = externalValidationResult;
}
@ -77,8 +74,7 @@ public class BtcValidator extends NumberValidator
// Protected methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateIfNotFractionalBtcValue(String input)
{
protected ValidationResult validateIfNotFractionalBtcValue(String input) {
BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.scale() > 0)
@ -87,8 +83,7 @@ public class BtcValidator extends NumberValidator
return new ValidationResult(true);
}
protected ValidationResult validateIfNotExceedsMaxBtcValue(String input)
{
protected ValidationResult validateIfNotExceedsMaxBtcValue(String input) {
BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.longValue() > NetworkParameters.MAX_MONEY.longValue())

View File

@ -20,8 +20,7 @@ package io.bitsquare.gui.util;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
public class Colors
{
public class Colors {
public static final Paint YELLOW = Color.valueOf("#edc035");
public static final Paint BLUE = Color.valueOf("#0096c9");
public static final Paint LIGHT_GREY = Color.valueOf("#f4f4f4");

View File

@ -20,16 +20,17 @@ package io.bitsquare.gui.util;
import com.google.bitcoin.core.*;
import com.google.bitcoin.script.Script;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import java.util.List;
import java.util.Set;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("CanBeFinal")
public class ConfidenceDisplay
{
public class ConfidenceDisplay {
private static final Logger log = LoggerFactory.getLogger(ConfidenceDisplay.class);
private WalletEventListener walletEventListener;
@ -44,8 +45,7 @@ public class ConfidenceDisplay
private ConfidenceProgressIndicator progressIndicator;
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, TextField balanceTextField, ConfidenceProgressIndicator progressIndicator)
{
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, TextField balanceTextField, ConfidenceProgressIndicator progressIndicator) {
this.wallet = wallet;
this.confirmationLabel = confirmationLabel;
this.balanceTextField = balanceTextField;
@ -57,57 +57,48 @@ public class ConfidenceDisplay
progressIndicator.setProgress(0);
updateBalance(wallet.getBalance());
walletEventListener = new WalletEventListener()
{
walletEventListener = new WalletEventListener() {
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
updateBalance(newBalance);
// log.debug("onCoinsReceived " + newBalance);
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
updateBalance(newBalance);
}
@Override
public void onReorganize(Wallet wallet)
{
public void onReorganize(Wallet wallet) {
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
{
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
updateConfidence(tx);
// log.debug("onTransactionConfidenceChanged tx " + tx.getHashAsString());
}
@Override
public void onWalletChanged(Wallet wallet)
{
public void onWalletChanged(Wallet wallet) {
}
@Override
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
{
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
}
@Override
public void onKeysAdded(List<ECKey> keys)
{
public void onKeysAdded(List<ECKey> keys) {
}
};
wallet.addEventListener(walletEventListener);
}
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, final Transaction transaction, ConfidenceProgressIndicator progressIndicator)
{
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, final Transaction transaction, ConfidenceProgressIndicator progressIndicator) {
this.wallet = wallet;
this.confirmationLabel = confirmationLabel;
this.transaction = transaction;
@ -120,118 +111,94 @@ public class ConfidenceDisplay
updateBalance(wallet.getBalance());
updateConfidence(transaction);
walletEventListener = new WalletEventListener()
{
walletEventListener = new WalletEventListener() {
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
if (tx.getHashAsString().equals(transaction.getHashAsString()))
{
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
if (tx.getHashAsString().equals(transaction.getHashAsString())) {
updateBalance(newBalance);
}
// log.debug("onCoinsReceived " + newBalance);
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance)
{
if (tx.getHashAsString().equals(transaction.getHashAsString()))
{
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
if (tx.getHashAsString().equals(transaction.getHashAsString())) {
updateBalance(newBalance);
}
}
@Override
public void onReorganize(Wallet wallet)
{
public void onReorganize(Wallet wallet) {
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
{
if (tx.getHashAsString().equals(transaction.getHashAsString()))
{
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
if (tx.getHashAsString().equals(transaction.getHashAsString())) {
updateConfidence(transaction);
}
// log.debug("onTransactionConfidenceChanged newTransaction " + newTransaction.getHashAsString());
}
@Override
public void onWalletChanged(Wallet wallet)
{
public void onWalletChanged(Wallet wallet) {
}
@Override
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
{
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
}
@Override
public void onKeysAdded(List<ECKey> keys)
{
public void onKeysAdded(List<ECKey> keys) {
}
};
wallet.addEventListener(walletEventListener);
}
public void destroy()
{
public void destroy() {
wallet.removeEventListener(walletEventListener);
progressIndicator.setProgress(0);
confirmationLabel.setText("");
if (balanceTextField != null)
{
if (balanceTextField != null) {
balanceTextField.setText("");
}
}
private void updateBalance(Coin balance)
{
if (balance.compareTo(Coin.ZERO) > 0)
{
private void updateBalance(Coin balance) {
if (balance.compareTo(Coin.ZERO) > 0) {
confirmationLabel.setVisible(true);
progressIndicator.setVisible(true);
progressIndicator.setProgress(-1);
Set<Transaction> transactions = wallet.getTransactions(false);
Transaction latestTransaction = null;
for (Transaction transaction : transactions)
{
if (latestTransaction != null)
{
if (transaction.getUpdateTime().compareTo(latestTransaction.getUpdateTime()) > 0)
{
for (Transaction transaction : transactions) {
if (latestTransaction != null) {
if (transaction.getUpdateTime().compareTo(latestTransaction.getUpdateTime()) > 0) {
latestTransaction = transaction;
}
}
else
{
} else {
latestTransaction = transaction;
}
}
if (latestTransaction != null && (transaction == null || latestTransaction.getHashAsString().equals(transaction.getHashAsString())))
{
if (latestTransaction != null && (transaction == null || latestTransaction.getHashAsString().equals(transaction.getHashAsString()))) {
updateConfidence(latestTransaction);
}
}
if (balanceTextField != null)
{
if (balanceTextField != null) {
//TODO
balanceTextField.setText(balance.toFriendlyString());
}
}
private void updateConfidence(Transaction tx)
{
private void updateConfidence(Transaction tx) {
TransactionConfidence confidence = tx.getConfidence();
double progressIndicatorSize = 50;
switch (confidence.getConfidenceType())
{
switch (confidence.getConfidenceType()) {
case UNKNOWN:
confirmationLabel.setText("");
progressIndicator.setProgress(0);

View File

@ -22,11 +22,10 @@ import org.slf4j.LoggerFactory;
/**
* FiatNumberValidator for validating fiat values.
* <p>
* <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 class FiatValidator extends NumberValidator {
private static final Logger log = LoggerFactory.getLogger(FiatValidator.class);
//TODO Find appropriate values - depends on currencies
@ -39,17 +38,14 @@ public class FiatValidator extends NumberValidator
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ValidationResult validate(String input)
{
public ValidationResult validate(String input) {
ValidationResult result = validateIfNotEmpty(input);
if (result.isValid)
{
if (result.isValid) {
input = cleanInput(input);
result = validateIfNumber(input);
}
if (result.isValid)
{
if (result.isValid) {
result = validateIfNotZero(input)
.and(validateIfNotNegative(input))
.and(validateIfNotExceedsMinFiatValue(input))
@ -64,8 +60,7 @@ public class FiatValidator extends NumberValidator
// Protected methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateIfNotExceedsMinFiatValue(String input)
{
protected ValidationResult validateIfNotExceedsMinFiatValue(String input) {
double d = Double.parseDouble(input);
if (d < MIN_FIAT_VALUE)
return new ValidationResult(false, "Input smaller as minimum possible Fiat value is not allowed..", ErrorType.UNDERCUT_MIN_FIAT_VALUE);
@ -73,8 +68,7 @@ public class FiatValidator extends NumberValidator
return new ValidationResult(true);
}
protected ValidationResult validateIfNotExceedsMaxFiatValue(String input)
{
protected ValidationResult validateIfNotExceedsMaxFiatValue(String input) {
double d = Double.parseDouble(input);
if (d > MAX_FIAT_VALUE)
return new ValidationResult(false, "Input larger as maximum possible Fiat value is not allowed.", ErrorType.EXCEEDS_MAX_FIAT_VALUE);

View File

@ -20,8 +20,7 @@ package io.bitsquare.gui.util;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class ImageUtil
{
public class ImageUtil {
public static final String SPLASH_LOGO = "/images/logo_200_270.png";
public static final String SPLASH_LABEL = "/images/bitsquare_logo_label_300_69.png";
@ -50,14 +49,12 @@ public class ImageUtil
public static final String REMOVE = "/images/removeOffer.png";
public static Image getIconImage(String iconName)
{
public static Image getIconImage(String iconName) {
return new Image(ImageUtil.class.getResourceAsStream(iconName));
}
public static ImageView getIconImageView(String iconName)
{
public static ImageView getIconImageView(String iconName) {
return new ImageView(new Image(ImageUtil.class.getResourceAsStream(iconName)));
}
}

View File

@ -24,11 +24,10 @@ 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>
* <p/>
* That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/
public abstract class NumberValidator
{
public abstract class NumberValidator {
private static final Logger log = LoggerFactory.getLogger(NumberValidator.class);
///////////////////////////////////////////////////////////////////////////////////////////
@ -42,42 +41,35 @@ public abstract class NumberValidator
// Protected methods
///////////////////////////////////////////////////////////////////////////////////////////
protected ValidationResult validateIfNotEmpty(String input)
{
protected ValidationResult validateIfNotEmpty(String input) {
if (input == null || input.length() == 0)
return new ValidationResult(false, "Empty input is not allowed.", ErrorType.EMPTY_INPUT);
else
return new ValidationResult(true);
}
protected String cleanInput(String input)
{
protected String cleanInput(String input) {
return input.replace(",", ".").trim();
}
protected ValidationResult validateIfNumber(String input)
{
try
{
protected ValidationResult validateIfNumber(String input) {
try {
//noinspection ResultOfMethodCallIgnored
Double.parseDouble(input);
return new ValidationResult(true);
} catch (Exception e)
{
} catch (Exception e) {
return new ValidationResult(false, "Input is not a valid number.", ErrorType.NOT_A_NUMBER);
}
}
protected ValidationResult validateIfNotZero(String input)
{
protected ValidationResult validateIfNotZero(String input) {
if (Double.parseDouble(input) == 0)
return new ValidationResult(false, "Input of 0 is not allowed.", ErrorType.ZERO_NUMBER);
else
return new ValidationResult(true);
}
protected ValidationResult validateIfNotNegative(String input)
{
protected ValidationResult validateIfNotNegative(String input) {
if (Double.parseDouble(input) < 0)
return new ValidationResult(false, "A negative value is not allowed.", ErrorType.NEGATIVE_NUMBER);
else
@ -89,8 +81,7 @@ public abstract class NumberValidator
// ErrorType
///////////////////////////////////////////////////////////////////////////////////////////
public enum ErrorType
{
public enum ErrorType {
EMPTY_INPUT,
NOT_A_NUMBER,
ZERO_NUMBER,
@ -104,26 +95,22 @@ public abstract class NumberValidator
// ValidationResult
///////////////////////////////////////////////////////////////////////////////////////////
public static class ValidationResult
{
public static class ValidationResult {
public final boolean isValid;
public final String errorMessage;
public final ErrorType errorType;
public ValidationResult(boolean isValid, String errorMessage, ErrorType errorType)
{
public ValidationResult(boolean isValid, String errorMessage, ErrorType errorType) {
this.isValid = isValid;
this.errorMessage = errorMessage;
this.errorType = errorType;
}
ValidationResult(boolean isValid)
{
ValidationResult(boolean isValid) {
this(isValid, null, null);
}
public ValidationResult and(ValidationResult next)
{
public ValidationResult and(ValidationResult next) {
if (this.isValid)
return next;
else
@ -131,8 +118,7 @@ public abstract class NumberValidator
}
@Override
public String toString()
{
public String toString() {
return "ValidationResult{" +
"isValid=" + isValid +
", errorMessage='" + errorMessage + '\'' +

View File

@ -18,13 +18,14 @@
package io.bitsquare.gui.util;
import com.google.common.base.Stopwatch;
import java.util.concurrent.TimeUnit;
import javafx.animation.AnimationTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Profiler
{
public class Profiler {
private static final Logger log = LoggerFactory.getLogger(Profiler.class);
private static final Stopwatch globalStopwatch = Stopwatch.createStarted();
@ -34,26 +35,22 @@ public class Profiler
private static long lastFPSTime = System.currentTimeMillis();
private static long counter = 0;
public static void printMsgWithTime(String msg)
{
public static void printMsgWithTime(String msg) {
final long elapsed = threadStopwatch.get().elapsed(TimeUnit.MILLISECONDS);
log.trace("Msg: {} elapsed: {}ms / total time:[globalStopwatch: {}ms / threadStopwatch: {}ms / currentTimeMillis: {}ms]",
msg,
elapsed - last.get(),
globalStopwatch.elapsed(TimeUnit.MILLISECONDS),
elapsed,
System.currentTimeMillis() - lastCurrentTimeMillis);
msg,
elapsed - last.get(),
globalStopwatch.elapsed(TimeUnit.MILLISECONDS),
elapsed,
System.currentTimeMillis() - lastCurrentTimeMillis);
lastCurrentTimeMillis = System.currentTimeMillis();
last.set(elapsed);
}
public static void init()
{
AnimationTimer fpsTimer = new AnimationTimer()
{
public static void init() {
AnimationTimer fpsTimer = new AnimationTimer() {
@Override
public void handle(long l)
{
public void handle(long l) {
counter++;
long elapsed = (System.currentTimeMillis() - lastFPSTime);
if (elapsed > 19)

View File

@ -29,33 +29,28 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkState;
@SuppressWarnings("WeakerAccess")
public class Transitions
{
public class Transitions {
private static final Logger log = LoggerFactory.getLogger(Transitions.class);
public static final int UI_ANIMATION_TIME = 800;
public static void fadeIn(Node node)
{
public static void fadeIn(Node node) {
fadeIn(node, UI_ANIMATION_TIME);
}
@SuppressWarnings("SameParameterValue")
public static void fadeIn(Node node, int duration)
{
public static void fadeIn(Node node, int duration) {
FadeTransition ft = new FadeTransition(Duration.millis(duration), node);
ft.setFromValue(0.0);
ft.setToValue(1.0);
ft.play();
}
public static Animation fadeOut(Node node)
{
public static Animation fadeOut(Node node) {
return fadeOut(node, UI_ANIMATION_TIME);
}
public static Animation fadeOut(Node node, int duration)
{
public static Animation fadeOut(Node node, int duration) {
FadeTransition ft = new FadeTransition(Duration.millis(duration), node);
ft.setFromValue(node.getOpacity());
ft.setToValue(0.0);
@ -64,13 +59,11 @@ public class Transitions
}
@SuppressWarnings("UnusedReturnValue")
public static Animation fadeOutAndRemove(Node node)
{
public static Animation fadeOutAndRemove(Node node) {
return fadeOutAndRemove(node, UI_ANIMATION_TIME);
}
public static Animation fadeOutAndRemove(Node node, int duration)
{
public static Animation fadeOutAndRemove(Node node, int duration) {
Animation animation = fadeOut(node, duration);
animation.setOnFinished(actionEvent -> {
((Pane) (node.getParent())).getChildren().remove(node);
@ -79,13 +72,11 @@ public class Transitions
return animation;
}
public static Timeline blurOutAndRemove(Node node)
{
public static Timeline blurOutAndRemove(Node node) {
return blurOutAndRemove(node, UI_ANIMATION_TIME);
}
public static Timeline blurOutAndRemove(Node node, int duration)
{
public static Timeline blurOutAndRemove(Node node, int duration) {
Timeline timeline = blurOut(node, duration);
timeline.setOnFinished(actionEvent -> {
((Pane) (node.getParent())).getChildren().remove(node);
@ -94,14 +85,12 @@ public class Transitions
return timeline;
}
public static void blurOut(Node node)
{
public static void blurOut(Node node) {
blurOut(node, UI_ANIMATION_TIME);
}
@SuppressWarnings("SameParameterValue")
public static Timeline blurOut(Node node, int duration)
{
public static Timeline blurOut(Node node, int duration) {
GaussianBlur blur = new GaussianBlur(0.0);
node.setEffect(blur);
Timeline timeline = new Timeline();
@ -112,8 +101,7 @@ public class Transitions
return timeline;
}
public static void blurIn(Node node)
{
public static void blurIn(Node node) {
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline durationline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
@ -123,8 +111,7 @@ public class Transitions
durationline.play();
}
public static void checkGuiThread()
{
public static void checkGuiThread() {
checkState(Platform.isFxApplicationThread());
}
}

View File

@ -27,8 +27,7 @@ import org.slf4j.LoggerFactory;
* Helper class for setting up the validation and dependencies for minAmount and Amount.
* TODO Might be improved but does the job for now...
*/
public class ValidationHelper
{
public class ValidationHelper {
private static final Logger log = LoggerFactory.getLogger(ValidationHelper.class);
/**
@ -39,32 +38,31 @@ public class ValidationHelper
StringProperty amount,
StringProperty minAmount,
BtcValidator amountValidator,
BtcValidator minAmountValidator)
{
BtcValidator minAmountValidator) {
amountTextField.focusedProperty().addListener((ov, oldValue, newValue) -> {
// only on focus out and ignore focus loss from window
if (!newValue && amountTextField.getScene() != null && amountTextField.getScene().getWindow().isFocused())
validateMinAmount(amountTextField,
minAmountTextField,
amount,
minAmount,
amountValidator,
minAmountValidator,
amountTextField);
minAmountTextField,
amount,
minAmount,
amountValidator,
minAmountValidator,
amountTextField);
});
minAmountTextField.focusedProperty().addListener((ov, oldValue, newValue) -> {
// only on focus out and ignore focus loss from window
if (!newValue && minAmountTextField.getScene() != null && minAmountTextField.getScene().getWindow().isFocused())
validateMinAmount(amountTextField,
minAmountTextField,
amount,
minAmount,
amountValidator,
minAmountValidator,
minAmountTextField);
minAmountTextField,
amount,
minAmount,
amountValidator,
minAmountValidator,
minAmountTextField);
});
}
@ -74,8 +72,7 @@ public class ValidationHelper
StringProperty minAmount,
BtcValidator amountValidator,
BtcValidator minAmountValidator,
TextField currentTextField)
{
TextField currentTextField) {
amountValidator.overrideResult(null);
String amountCleaned = amount.get() != null ? amount.get().replace(",", ".").trim() : "0";
String minAmountCleaned = minAmount.get() != null ? minAmount.get().replace(",", ".").trim() : "0";
@ -87,28 +84,19 @@ public class ValidationHelper
if (!minAmountValidator.validate(minAmountCleaned).isValid)
return;
if (currentTextField == amountTextField)
{
if (Double.parseDouble(amountCleaned) < Double.parseDouble(minAmountCleaned))
{
if (currentTextField == amountTextField) {
if (Double.parseDouble(amountCleaned) < Double.parseDouble(minAmountCleaned)) {
amountValidator.overrideResult(new NumberValidator.ValidationResult(false, "Amount cannot be smaller than minimum amount.", NumberValidator.ErrorType.AMOUNT_LESS_THAN_MIN_AMOUNT));
amountTextField.reValidate();
}
else
{
} else {
amountValidator.overrideResult(null);
minAmountTextField.reValidate();
}
}
else if (currentTextField == minAmountTextField)
{
if (Double.parseDouble(minAmountCleaned) > Double.parseDouble(amountCleaned))
{
} else if (currentTextField == minAmountTextField) {
if (Double.parseDouble(minAmountCleaned) > Double.parseDouble(amountCleaned)) {
minAmountValidator.overrideResult(new NumberValidator.ValidationResult(false, "Minimum amount cannot be larger than amount.", NumberValidator.ErrorType.MIN_AMOUNT_LARGER_THAN_MIN_AMOUNT));
minAmountTextField.reValidate();
}
else
{
} else {
minAmountValidator.overrideResult(null);
amountTextField.reValidate();
}

View File

@ -20,8 +20,7 @@ package io.bitsquare.locale;
import java.io.Serializable;
import java.util.Objects;
public class Country implements Serializable
{
public class Country implements Serializable {
private static final long serialVersionUID = -5930294199097793187L;
@ -31,26 +30,21 @@ public class Country implements Serializable
private final Region region;
public Country(String code, String name, Region region)
{
public Country(String code, String name, Region region) {
this.code = code;
this.name = name;
this.region = region;
}
public int hashCode()
{
public int hashCode() {
return Objects.hashCode(code);
}
public boolean equals(Object obj)
{
if (!(obj instanceof Country))
{
public boolean equals(Object obj) {
if (!(obj instanceof Country)) {
return false;
}
if (obj == this)
{
if (obj == this) {
return true;
}
@ -59,27 +53,23 @@ public class Country implements Serializable
}
public String getCode()
{
public String getCode() {
return code;
}
public String getName()
{
public String getName() {
return name;
}
public Region getRegion()
{
public Region getRegion() {
return region;
}
@Override
public String toString()
{
public String toString() {
return "code='" + code + '\'' +
", name='" + name + '\'' +
", getRegion='" + region;

View File

@ -19,11 +19,11 @@ package io.bitsquare.locale;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import java.util.*;
import java.util.stream.Collectors;
public class CountryUtil
{
public class CountryUtil {
private static final String[] countryCodes = new String[]{"AE", "AL", "AR", "AT", "AU", "BA", "BE", "BG", "BH", "BO", "BR", "BY", "CA", "CH", "CL", "CN", "CO", "CR", "CS", "CU", "CY", "CZ",
"DE", "DK", "DO", "DZ", "EC", "EE", "EG", "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HR", "HU", "ID", "IE", "IL", "IN", "IQ", "IS", "IT", "JO", "JP", "KR", "KW", "LB", "LT", "LU",
"LV", "LY", "MA", "ME", "MK", "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "OM", "PA", "PE", "PH", "PL", "PR", "PT", "PY", "QA", "RO", "RS", "RU", "SA", "SD", "SE", "SG", "SI", "SK", "SV",
@ -37,8 +37,7 @@ public class CountryUtil
private static final String[][] regionCodeToName = new String[][]{{"NA", "North America"}, {"SA", "South America"}, {"AF", "Africa"}, {"EU", "Europe"}, {"AS", "Asia"}, {"OC", "Oceania"}};
public static List<Region> getAllRegions()
{
public static List<Region> getAllRegions() {
final List<Region> allRegions = new ArrayList<>();
String regionCode = "NA";
@ -68,17 +67,14 @@ public class CountryUtil
return allRegions;
}
public static List<Country> getAllCountriesFor(Region selectedRegion)
{
public static List<Country> getAllCountriesFor(Region selectedRegion) {
return Lists.newArrayList(Collections2.filter(getAllCountries(), country -> selectedRegion != null && country != null && selectedRegion.equals(country.getRegion())));
}
private static List<Country> getAllCountries()
{
private static List<Country> getAllCountries() {
final List<Country> allCountries = new ArrayList<>();
for (final Locale locale : getAllCountryLocales())
{
for (final Locale locale : getAllCountryLocales()) {
String regionCode = getRegionCode(locale.getCountry());
final Region region = new Region(regionCode, getRegionName(regionCode));
final Country country = new Country(locale.getCountry(), locale.getDisplayCountry(), region);
@ -88,8 +84,7 @@ public class CountryUtil
}
public static Country getDefaultCountry()
{
public static Country getDefaultCountry() {
final Locale locale = new Locale("", Locale.getDefault().getCountry());
String regionCode = getRegionCode(locale.getCountry());
final Region region = new Region(regionCode, getRegionName(regionCode));
@ -97,12 +92,9 @@ public class CountryUtil
}
private static String getRegionName(final String regionCode)
{
for (final String[] regionName : regionCodeToName)
{
if (regionName[0].equals(regionCode))
{
private static String getRegionName(final String regionCode) {
for (final String[] regionName : regionCodeToName) {
if (regionName[0].equals(regionCode)) {
return regionName[1];
}
}
@ -110,8 +102,7 @@ public class CountryUtil
}
private static List<Locale> getAllCountryLocales()
{
private static List<Locale> getAllCountryLocales() {
List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getCountry())).map(locale -> new Locale("", locale.getCountry(), "")).collect(Collectors.toSet());
/*
@ -132,14 +123,10 @@ public class CountryUtil
}
private static String getRegionCode(String countryCode)
{
if (!countryCode.isEmpty() && countryCodeList.contains(countryCode))
{
private static String getRegionCode(String countryCode) {
if (!countryCode.isEmpty() && countryCodeList.contains(countryCode)) {
return regionCodeList.get(countryCodeList.indexOf(countryCode));
}
else
{
} else {
return "Undefined";
}
}

View File

@ -20,11 +20,9 @@ package io.bitsquare.locale;
import java.text.NumberFormat;
import java.util.*;
public class CurrencyUtil
{
public class CurrencyUtil {
public static List<Currency> getAllCurrencies()
{
public static List<Currency> getAllCurrencies() {
final ArrayList<Currency> mainCurrencies = new ArrayList<>();
mainCurrencies.add(Currency.getInstance("USD"));
mainCurrencies.add(Currency.getInstance("EUR"));
@ -54,8 +52,7 @@ public class CurrencyUtil
}
public static Currency getDefaultCurrency()
{
public static Currency getDefaultCurrency() {
return NumberFormat.getNumberInstance(Locale.getDefault()).getCurrency();
}
}

View File

@ -20,8 +20,7 @@ package io.bitsquare.locale;
import java.util.*;
import java.util.stream.Collectors;
public class LanguageUtil
{
public class LanguageUtil {
/*public static List<Locale> getPopularLanguages()
{
@ -40,8 +39,7 @@ public class LanguageUtil
} */
public static List<Locale> getAllLanguageLocales()
{
public static List<Locale> getAllLanguageLocales() {
List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
final Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getLanguage())).map(locale -> new Locale(locale.getLanguage(), "")).collect(Collectors.toSet());
allLocales = new ArrayList<>();
@ -50,13 +48,11 @@ public class LanguageUtil
return allLocales;
}
public static Locale getDefaultLanguageLocale()
{
public static Locale getDefaultLanguageLocale() {
return new Locale(Locale.getDefault().getLanguage(), "");
}
public static Locale getEnglishLanguageLocale()
{
public static Locale getEnglishLanguageLocale() {
return new Locale(Locale.ENGLISH.getLanguage(), "");
}
}

View File

@ -27,74 +27,59 @@ import java.util.Locale;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Localisation
{
public class Localisation {
private static final Logger log = LoggerFactory.getLogger(Localisation.class);
public static ResourceBundle getResourceBundle()
{
public static ResourceBundle getResourceBundle() {
return ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control());
}
public static String get(String key)
{
try
{
public static String get(String key) {
try {
return Localisation.getResourceBundle().getString(key);
} catch (MissingResourceException e)
{
} catch (MissingResourceException e) {
log.error("MissingResourceException for key: " + key);
return key + " is missing";
}
}
public static String get(String key, String... arguments)
{
public static String get(String key, String... arguments) {
return MessageFormat.format(Localisation.get(key), arguments);
}
}
class UTF8Control extends ResourceBundle.Control
{
class UTF8Control extends ResourceBundle.Control {
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException
{
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
// The below is a copy of the default implementation.
final String bundleName = toBundleName(baseName, locale);
final String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
if (reload)
{
if (reload) {
final URL url = loader.getResource(resourceName);
if (url != null)
{
if (url != null) {
final URLConnection connection = url.openConnection();
if (connection != null)
{
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
}
else
{
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null)
{
try
{
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
} finally
{
} finally {
stream.close();
}
}

View File

@ -20,8 +20,7 @@ package io.bitsquare.locale;
import java.io.Serializable;
import java.util.Objects;
public class Region implements Serializable
{
public class Region implements Serializable {
private static final long serialVersionUID = -5930294199097793187L;
@ -29,25 +28,20 @@ public class Region implements Serializable
private final String name;
public Region(String code, String name)
{
public Region(String code, String name) {
this.code = code;
this.name = name;
}
public int hashCode()
{
public int hashCode() {
return Objects.hashCode(code);
}
public boolean equals(Object obj)
{
if (!(obj instanceof Region))
{
public boolean equals(Object obj) {
if (!(obj instanceof Region)) {
return false;
}
if (obj == this)
{
if (obj == this) {
return true;
}
@ -56,21 +50,18 @@ public class Region implements Serializable
}
String getCode()
{
String getCode() {
return code;
}
public String getName()
{
public String getName() {
return name;
}
@Override
public String toString()
{
public String toString() {
return "regionCode='" + code + '\'' +
", continentName='" + name;
}

View File

@ -17,8 +17,7 @@
package io.bitsquare.msg;
public interface BootstrapListener
{
public interface BootstrapListener {
public void onCompleted();
public void onFailed(Throwable throwable);

View File

@ -21,12 +21,14 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.inject.name.Named;
import io.bitsquare.storage.Persistence;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyPair;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import net.tomp2p.connection.Ports;
import net.tomp2p.dht.PeerBuilderDHT;
import net.tomp2p.dht.PeerDHT;
@ -55,8 +57,7 @@ import org.slf4j.LoggerFactory;
* Creates a DHT peer and bootstrap to a seed node
*/
@Immutable
public class BootstrappedPeerFactory
{
public class BootstrappedPeerFactory {
private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerFactory.class);
private KeyPair keyPair;
@ -72,8 +73,7 @@ public class BootstrappedPeerFactory
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public BootstrappedPeerFactory(Persistence persistence, @Named("defaultSeedNode") SeedNodeAddress.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses)
{
public BootstrappedPeerFactory(Persistence persistence, @Named("defaultSeedNode") SeedNodeAddress.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses) {
this.persistence = persistence;
this.seedNodeAddress = new SeedNodeAddress(defaultStaticSeedNodeAddresses);
}
@ -83,13 +83,11 @@ public class BootstrappedPeerFactory
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setKeyPair(@NotNull KeyPair keyPair)
{
public void setKeyPair(@NotNull KeyPair keyPair) {
this.keyPair = keyPair;
}
public void setStorage(@NotNull Storage storage)
{
public void setStorage(@NotNull Storage storage) {
this.storage = storage;
}
@ -98,19 +96,15 @@ public class BootstrappedPeerFactory
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public ListenableFuture<PeerDHT> start()
{
try
{
public ListenableFuture<PeerDHT> start() {
try {
int randomPort = new Ports().tcpPort();
Peer peer = new PeerBuilder(keyPair).ports(randomPort).start();
PeerDHT peerDHT = new PeerBuilderDHT(peer).storageLayer(new StorageLayer(storage)).start();
peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener()
{
peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() {
@Override
public void peerInserted(PeerAddress peerAddress, boolean verified)
{
public void peerInserted(PeerAddress peerAddress, boolean verified) {
log.debug("Peer inserted: peerAddress=" + peerAddress + ", verified=" + verified);
/* NavigableSet<PeerAddress> closePeers = peer.peerBean().peerMap().closePeers(2);
@ -125,14 +119,12 @@ public class BootstrappedPeerFactory
}
@Override
public void peerRemoved(PeerAddress peerAddress, PeerStatatistic peerStatistics)
{
public void peerRemoved(PeerAddress peerAddress, PeerStatatistic peerStatistics) {
log.debug("Peer removed: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
}
@Override
public void peerUpdated(PeerAddress peerAddress, PeerStatatistic peerStatistics)
{
public void peerUpdated(PeerAddress peerAddress, PeerStatatistic peerStatistics) {
// log.debug("Peer updated: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
}
});
@ -155,8 +147,7 @@ public class BootstrappedPeerFactory
lastSuccessfulBootstrap = "default";
log.debug("lastSuccessfulBootstrap = " + lastSuccessfulBootstrap);
switch (lastSuccessfulBootstrap)
{
switch (lastSuccessfulBootstrap) {
case "relay":
PeerNAT nodeBehindNat = new PeerBuilderNAT(peerDHT.peer()).start();
bootstrapWithRelay(peerDHT, nodeBehindNat);
@ -170,8 +161,7 @@ public class BootstrappedPeerFactory
bootstrap(peerDHT);
break;
}
} catch (IOException e)
{
} catch (IOException e) {
log.error("Exception: " + e);
settableFuture.setException(e);
}
@ -179,42 +169,33 @@ public class BootstrappedPeerFactory
return settableFuture;
}
private PeerAddress getBootstrapAddress()
{
try
{
private PeerAddress getBootstrapAddress() {
try {
return new PeerAddress(Number160.createHash(seedNodeAddress.getId()),
InetAddress.getByName(seedNodeAddress.getIp()),
seedNodeAddress.getPort(),
seedNodeAddress.getPort());
} catch (UnknownHostException e)
{
InetAddress.getByName(seedNodeAddress.getIp()),
seedNodeAddress.getPort(),
seedNodeAddress.getPort());
} catch (UnknownHostException e) {
log.error("getBootstrapAddress failed: " + e.getMessage());
return null;
}
}
private void bootstrap(PeerDHT peerDHT)
{
private void bootstrap(PeerDHT peerDHT) {
// Check if peer is reachable from outside
FutureDiscover futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress()).start();
BootstrappedPeerFactory ref = this;
futureDiscover.addListener(new BaseFutureListener<BaseFuture>()
{
futureDiscover.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
// We are not behind a NAT and reachable to other peers
log.debug("We are not behind a NAT and reachable to other peers: My address visible to the outside is " + futureDiscover.peerAddress());
requestBootstrapPeerMap();
settableFuture.set(peerDHT);
persistence.write(ref, "lastSuccessfulBootstrap", "default");
}
else
{
} else {
log.warn("Discover has failed. Reason: " + futureDiscover.failedReason());
log.warn("We are probably behind a NAT and not reachable to other peers. We try port forwarding as next step.");
@ -223,38 +204,31 @@ public class BootstrappedPeerFactory
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("Exception at discover: " + t);
settableFuture.setException(t);
}
});
}
private void bootstrapWithPortForwarding(PeerDHT peerDHT, FutureDiscover futureDiscover)
{
private void bootstrapWithPortForwarding(PeerDHT peerDHT, FutureDiscover futureDiscover) {
// Assume we are behind a NAT device
PeerNAT nodeBehindNat = new PeerBuilderNAT(peerDHT.peer()).start();
// Try to set up port forwarding with UPNP and NATPMP if peer is not reachable
FutureNAT futureNAT = nodeBehindNat.startSetupPortforwarding(futureDiscover);
BootstrappedPeerFactory ref = this;
futureNAT.addListener(new BaseFutureListener<BaseFuture>()
{
futureNAT.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
// Port forwarding has succeed
log.debug("Port forwarding was successful. My address visible to the outside is " + futureNAT.peerAddress());
requestBootstrapPeerMap();
settableFuture.set(peerDHT);
persistence.write(ref, "lastSuccessfulBootstrap", "portForwarding");
}
else
{
} else {
log.warn("Port forwarding has failed. Reason: " + futureNAT.failedReason());
log.warn("We try to use a relay as next step.");
@ -263,16 +237,14 @@ public class BootstrappedPeerFactory
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("Exception at port forwarding: " + t);
settableFuture.setException(t);
}
});
}
private void bootstrapWithRelay(PeerDHT peerDHT, PeerNAT nodeBehindNat)
{
private void bootstrapWithRelay(PeerDHT peerDHT, PeerNAT nodeBehindNat) {
// Last resort: we try to use other peers as relays
// The firewalled flags have to be set, so that other peers dont add the unreachable peer to their peer maps.
@ -283,50 +255,38 @@ public class BootstrappedPeerFactory
// Find neighbors
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(getBootstrapAddress()).start();
futureBootstrap.addListener(new BaseFutureListener<BaseFuture>()
{
futureBootstrap.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
log.debug("Bootstrap was successful. bootstrapTo = " + futureBootstrap.bootstrapTo());
setupRelay(peerDHT, nodeBehindNat, getBootstrapAddress());
}
else
{
} else {
log.error("Bootstrap failed. Reason:" + futureBootstrap.failedReason());
settableFuture.setException(new Exception(futureBootstrap.failedReason()));
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("Exception at bootstrap: " + t);
settableFuture.setException(t);
}
});
}
private void setupRelay(PeerDHT peerDHT, PeerNAT nodeBehindNat, PeerAddress bootstrapAddress)
{
private void setupRelay(PeerDHT peerDHT, PeerNAT nodeBehindNat, PeerAddress bootstrapAddress) {
FutureRelay futureRelay = new FutureRelay();
futureRelay.addListener(new BaseFutureListener<BaseFuture>()
{
futureRelay.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
log.debug("Start setup relay was successful.");
futureRelay.relays().forEach(e -> log.debug("remotePeer = " + e.remotePeer()));
findNeighbors2(peerDHT, nodeBehindNat, bootstrapAddress);
}
else
{
} else {
log.error("setupRelay failed. Reason: " + futureRelay.failedReason());
log.error("Bootstrap failed. We give up...");
settableFuture.setException(new Exception(futureRelay.failedReason()));
@ -334,8 +294,7 @@ public class BootstrappedPeerFactory
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("Exception at setup relay: " + t);
}
});
@ -347,26 +306,20 @@ public class BootstrappedPeerFactory
});
}
private void findNeighbors2(PeerDHT peerDHT, PeerNAT nodeBehindNat, PeerAddress bootstrapAddress)
{
private void findNeighbors2(PeerDHT peerDHT, PeerNAT nodeBehindNat, PeerAddress bootstrapAddress) {
// find neighbors again
FutureBootstrap futureBootstrap2 = peerDHT.peer().bootstrap().peerAddress(bootstrapAddress).start();
BootstrappedPeerFactory ref = this;
futureBootstrap2.addListener(new BaseFutureListener<BaseFuture>()
{
futureBootstrap2.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
log.debug("Final bootstrap was successful. bootstrapTo = " + futureBootstrap2.bootstrapTo());
requestBootstrapPeerMap();
settableFuture.set(peerDHT);
persistence.write(ref, "lastSuccessfulBootstrap", "relay");
}
else
{
} else {
log.error("Bootstrap 2 failed. Reason:" + futureBootstrap2.failedReason());
log.error("We give up...");
settableFuture.setException(new Exception(futureBootstrap2.failedReason()));
@ -374,8 +327,7 @@ public class BootstrappedPeerFactory
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("Exception at bootstrap 2: " + t);
settableFuture.setException(t);
}
@ -384,8 +336,7 @@ public class BootstrappedPeerFactory
// TODO we want to get a list of connected nodes form the seed node and save them locally for future bootstrapping
// The seed node should only be used if no other known peers are available
private void requestBootstrapPeerMap()
{
private void requestBootstrapPeerMap() {
log.debug("getBootstrapPeerMap");
/* NavigableSet<PeerAddress> closePeers = peer.peerBean().peerMap().closePeers(2);

View File

@ -19,7 +19,6 @@ package io.bitsquare.msg;
import net.tomp2p.peers.PeerAddress;
public interface MessageBroker
{
public interface MessageBroker {
void handleMessage(Object message, PeerAddress peerAddress);
}

View File

@ -23,17 +23,21 @@ import io.bitsquare.trade.Offer;
import io.bitsquare.trade.protocol.TradeMessage;
import io.bitsquare.user.Arbitrator;
import io.bitsquare.user.User;
import java.io.IOException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.tomp2p.dht.FutureGet;
import net.tomp2p.dht.FuturePut;
import net.tomp2p.dht.FutureRemove;
@ -54,14 +58,12 @@ import org.slf4j.LoggerFactory;
* It is the translating domain specific functionality to the messaging layer.
* The TomP2P library codebase shall not be used outside that facade.
* That way we limit the dependency of the TomP2P library only to that class (and it's sub components).
* <p>
* <p/>
* TODO: improve callbacks that Platform.runLater is not necessary. We call usually that methods form teh UI thread.
*/
public class MessageFacade implements MessageBroker
{
public class MessageFacade implements MessageBroker {
public static interface AddOfferListener
{
public static interface AddOfferListener {
void onComplete();
void onFailed(String reason, Throwable throwable);
@ -70,8 +72,7 @@ public class MessageFacade implements MessageBroker
private static final Logger log = LoggerFactory.getLogger(MessageFacade.class);
private static final String ARBITRATORS_ROOT = "ArbitratorsRoot";
public P2PNode getP2pNode()
{
public P2PNode getP2pNode() {
return p2pNode;
}
@ -89,8 +90,7 @@ public class MessageFacade implements MessageBroker
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public MessageFacade(User user, P2PNode p2pNode)
{
public MessageFacade(User user, P2PNode p2pNode) {
this.user = user;
this.p2pNode = p2pNode;
}
@ -100,31 +100,26 @@ public class MessageFacade implements MessageBroker
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void init(BootstrapListener bootstrapListener)
{
public void init(BootstrapListener bootstrapListener) {
p2pNode.setMessageBroker(this);
p2pNode.setKeyPair(user.getMessageKeyPair());
p2pNode.start(new FutureCallback<PeerDHT>()
{
p2pNode.start(new FutureCallback<PeerDHT>() {
@Override
public void onSuccess(@Nullable PeerDHT result)
{
public void onSuccess(@Nullable PeerDHT result) {
log.debug("p2pNode.start success result = " + result);
Platform.runLater(() -> bootstrapListener.onCompleted());
}
@Override
public void onFailure(Throwable t)
{
public void onFailure(Throwable t) {
log.error(t.toString());
Platform.runLater(() -> bootstrapListener.onFailed(t));
}
});
}
public void shutDown()
{
public void shutDown() {
if (p2pNode != null)
p2pNode.shutDown();
}
@ -135,31 +130,23 @@ public class MessageFacade implements MessageBroker
///////////////////////////////////////////////////////////////////////////////////////////
public void getPeerAddress(PublicKey publicKey, GetPeerAddressListener listener)
{
public void getPeerAddress(PublicKey publicKey, GetPeerAddressListener listener) {
final Number160 locationKey = Utils.makeSHAHash(publicKey.getEncoded());
try
{
try {
FutureGet futureGet = p2pNode.getDomainProtectedData(locationKey, publicKey);
futureGet.addListener(new BaseFutureAdapter<BaseFuture>()
{
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture baseFuture) throws Exception
{
if (baseFuture.isSuccess() && futureGet.data() != null)
{
public void operationComplete(BaseFuture baseFuture) throws Exception {
if (baseFuture.isSuccess() && futureGet.data() != null) {
final PeerAddress peerAddress = (PeerAddress) futureGet.data().object();
Platform.runLater(() -> listener.onResult(peerAddress));
}
else
{
} else {
Platform.runLater(() -> listener.onFailed());
}
}
});
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
log.error(e.toString());
}
@ -170,24 +157,19 @@ public class MessageFacade implements MessageBroker
// Offer
///////////////////////////////////////////////////////////////////////////////////////////
public void addOffer(Offer offer, AddOfferListener addOfferListener)
{
public void addOffer(Offer offer, AddOfferListener addOfferListener) {
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
try
{
try {
final Data data = new Data(offer);
// the offer is default 30 days valid
int defaultOfferTTL = 30 * 24 * 60 * 60 * 1000;
data.ttlSeconds(defaultOfferTTL);
FuturePut futurePut = p2pNode.addProtectedData(locationKey, data);
futurePut.addListener(new BaseFutureListener<BaseFuture>()
{
futurePut.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
Platform.runLater(() -> {
addOfferListener.onComplete();
orderBookListeners.stream().forEach(listener -> listener.onOfferAdded(data, future.isSuccess()));
@ -196,9 +178,7 @@ public class MessageFacade implements MessageBroker
setDirty(locationKey);
log.trace("Add offer to DHT was successful. Stored data: [key: " + locationKey + ", value: " + data + "]");
});
}
else
{
} else {
Platform.runLater(() -> {
addOfferListener.onFailed("Add offer to DHT failed.", new Exception("Add offer to DHT failed. Reason: " + future.failedReason()));
log.error("Add offer to DHT failed. Reason: " + future.failedReason());
@ -207,16 +187,14 @@ public class MessageFacade implements MessageBroker
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
Platform.runLater(() -> {
addOfferListener.onFailed("Add offer to DHT failed with an exception.", t);
log.error("Add offer to DHT failed with an exception: " + t.getMessage());
});
}
});
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
Platform.runLater(() -> {
addOfferListener.onFailed("Add offer to DHT failed with an exception.", e);
log.error("Add offer to DHT failed with an exception: " + e.getMessage());
@ -224,60 +202,45 @@ public class MessageFacade implements MessageBroker
}
}
public void removeOffer(Offer offer)
{
public void removeOffer(Offer offer) {
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
try
{
try {
final Data data = new Data(offer);
FutureRemove futureRemove = p2pNode.removeFromDataMap(locationKey, data);
futureRemove.addListener(new BaseFutureListener<BaseFuture>()
{
futureRemove.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
public void operationComplete(BaseFuture future) throws Exception {
Platform.runLater(() -> {
orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOfferRemoved(data, future.isSuccess()));
setDirty(locationKey);
});
if (future.isSuccess())
{
if (future.isSuccess()) {
log.trace("Remove offer from DHT was successful. Stored data: [key: " + locationKey + ", value: " + data + "]");
}
else
{
} else {
log.error("Remove offer from DHT failed. Reason: " + future.failedReason());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error(t.toString());
}
});
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public void getOffers(String currencyCode)
{
public void getOffers(String currencyCode) {
Number160 locationKey = Number160.createHash(currencyCode);
FutureGet futureGet = p2pNode.getDataMap(locationKey);
futureGet.addListener(new BaseFutureAdapter<BaseFuture>()
{
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture baseFuture) throws Exception
{
public void operationComplete(BaseFuture baseFuture) throws Exception {
Platform.runLater(() -> orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOffersReceived(futureGet.dataMap(), baseFuture.isSuccess())));
if (baseFuture.isSuccess())
{
if (baseFuture.isSuccess()) {
//log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey + ", values: " + futureGet.dataMap() + "]");
}
else
{
} else {
log.error("Get offers from DHT failed with reason:" + baseFuture.failedReason());
}
}
@ -289,27 +252,20 @@ public class MessageFacade implements MessageBroker
// Trade process
///////////////////////////////////////////////////////////////////////////////////////////
public void sendTradeMessage(PeerAddress peerAddress, TradeMessage tradeMessage, OutgoingTradeMessageListener listener)
{
public void sendTradeMessage(PeerAddress peerAddress, TradeMessage tradeMessage, OutgoingTradeMessageListener listener) {
FutureDirect futureDirect = p2pNode.sendData(peerAddress, tradeMessage);
futureDirect.addListener(new BaseFutureListener<BaseFuture>()
{
futureDirect.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (futureDirect.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (futureDirect.isSuccess()) {
Platform.runLater(() -> listener.onResult());
}
else
{
} else {
Platform.runLater(() -> listener.onFailed());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
Platform.runLater(() -> listener.onFailed());
}
});
@ -320,78 +276,57 @@ public class MessageFacade implements MessageBroker
// Arbitrators
///////////////////////////////////////////////////////////////////////////////////////////
public void addArbitrator(Arbitrator arbitrator)
{
public void addArbitrator(Arbitrator arbitrator) {
Number160 locationKey = Number160.createHash(ARBITRATORS_ROOT);
try
{
try {
final Data arbitratorData = new Data(arbitrator);
FuturePut addFuture = p2pNode.addProtectedData(locationKey, arbitratorData);
addFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
addFuture.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
public void operationComplete(BaseFuture future) throws Exception {
Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorAdded(arbitratorData, addFuture.isSuccess())));
if (addFuture.isSuccess())
{
if (addFuture.isSuccess()) {
log.trace("Add arbitrator to DHT was successful. Stored data: [key: " + locationKey + ", values: " + arbitratorData + "]");
}
else
{
} else {
log.error("Add arbitrator to DHT failed with reason:" + addFuture.failedReason());
}
}
});
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e)
{
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void removeArbitrator(Arbitrator arbitrator) throws IOException, ClassNotFoundException
{
public void removeArbitrator(Arbitrator arbitrator) throws IOException, ClassNotFoundException {
Number160 locationKey = Number160.createHash(ARBITRATORS_ROOT);
final Data arbitratorData = new Data(arbitrator);
FutureRemove removeFuture = p2pNode.removeFromDataMap(locationKey, arbitratorData);
removeFuture.addListener(new BaseFutureAdapter<BaseFuture>()
{
removeFuture.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
public void operationComplete(BaseFuture future) throws Exception {
Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorRemoved(arbitratorData, removeFuture.isSuccess())));
if (removeFuture.isSuccess())
{
if (removeFuture.isSuccess()) {
log.trace("Remove arbitrator from DHT was successful. Stored data: [key: " + locationKey + ", values: " + arbitratorData + "]");
}
else
{
} else {
log.error("Remove arbitrators from DHT failed with reason:" + removeFuture.failedReason());
}
}
});
}
public void getArbitrators(Locale languageLocale)
{
public void getArbitrators(Locale languageLocale) {
Number160 locationKey = Number160.createHash(ARBITRATORS_ROOT);
FutureGet futureGet = p2pNode.getDataMap(locationKey);
futureGet.addListener(new BaseFutureAdapter<BaseFuture>()
{
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture baseFuture) throws Exception
{
public void operationComplete(BaseFuture baseFuture) throws Exception {
Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorsReceived(futureGet.dataMap(), baseFuture.isSuccess())));
if (baseFuture.isSuccess())
{
if (baseFuture.isSuccess()) {
log.trace("Get arbitrators from DHT was successful. Stored data: [key: " + locationKey + ", values: " + futureGet.dataMap() + "]");
}
else
{
} else {
log.error("Get arbitrators from DHT failed with reason:" + baseFuture.failedReason());
}
}
@ -403,13 +338,11 @@ public class MessageFacade implements MessageBroker
// Event Listeners
///////////////////////////////////////////////////////////////////////////////////////////
public void addOrderBookListener(OrderBookListener listener)
{
public void addOrderBookListener(OrderBookListener listener) {
orderBookListeners.add(listener);
}
public void removeOrderBookListener(OrderBookListener listener)
{
public void removeOrderBookListener(OrderBookListener listener) {
orderBookListeners.remove(listener);
}
@ -423,23 +356,19 @@ public class MessageFacade implements MessageBroker
pingPeerListeners.remove(listener);
} */
public void addArbitratorListener(ArbitratorListener listener)
{
public void addArbitratorListener(ArbitratorListener listener) {
arbitratorListeners.add(listener);
}
public void removeArbitratorListener(ArbitratorListener listener)
{
public void removeArbitratorListener(ArbitratorListener listener) {
arbitratorListeners.remove(listener);
}
public void addIncomingTradeMessageListener(IncomingTradeMessageListener listener)
{
public void addIncomingTradeMessageListener(IncomingTradeMessageListener listener) {
incomingTradeMessageListeners.add(listener);
}
public void removeIncomingTradeMessageListener(IncomingTradeMessageListener listener)
{
public void removeIncomingTradeMessageListener(IncomingTradeMessageListener listener) {
incomingTradeMessageListeners.remove(listener);
}
@ -449,41 +378,32 @@ public class MessageFacade implements MessageBroker
///////////////////////////////////////////////////////////////////////////////////////////
// TODO just temp...
public BooleanProperty getIsDirtyProperty()
{
public BooleanProperty getIsDirtyProperty() {
return isDirty;
}
public void getDirtyFlag(Currency currency)
{
public void getDirtyFlag(Currency currency) {
Number160 locationKey = Number160.createHash(currency.getCurrencyCode());
try
{
try {
FutureGet getFuture = p2pNode.getData(getDirtyLocationKey(locationKey));
getFuture.addListener(new BaseFutureListener<BaseFuture>()
{
getFuture.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
public void operationComplete(BaseFuture future) throws Exception {
Data data = getFuture.data();
if (data != null)
{
if (data != null) {
Object object = data.object();
if (object instanceof Long)
{
if (object instanceof Long) {
Platform.runLater(() -> onGetDirtyFlag((Long) object));
}
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("getFuture exceptionCaught " + t.toString());
}
});
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
@ -491,52 +411,40 @@ public class MessageFacade implements MessageBroker
private Long lastTimeStamp = -3L;
private final BooleanProperty isDirty = new SimpleBooleanProperty(false);
private void onGetDirtyFlag(long timeStamp)
{
private void onGetDirtyFlag(long timeStamp) {
// TODO don't get updates at first execute....
if (lastTimeStamp != timeStamp)
{
if (lastTimeStamp != timeStamp) {
isDirty.setValue(!isDirty.get());
}
if (lastTimeStamp > 0)
{
if (lastTimeStamp > 0) {
lastTimeStamp = timeStamp;
}
else
{
} else {
lastTimeStamp++;
}
}
public void setDirty(Number160 locationKey)
{
public void setDirty(Number160 locationKey) {
// we don't want to get an update from dirty for own changes, so update the lastTimeStamp to omit a change trigger
lastTimeStamp = System.currentTimeMillis();
try
{
try {
FuturePut putFuture = p2pNode.putData(getDirtyLocationKey(locationKey), new Data(lastTimeStamp));
putFuture.addListener(new BaseFutureListener<BaseFuture>()
{
putFuture.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
public void operationComplete(BaseFuture future) throws Exception {
// log.trace("operationComplete");
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.warn("Error at writing dirty flag (timeStamp) " + t.toString());
}
});
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
log.warn("Error at writing dirty flag (timeStamp) " + e.getMessage());
}
}
private Number160 getDirtyLocationKey(Number160 locationKey)
{
private Number160 getDirtyLocationKey(Number160 locationKey) {
return Number160.createHash(locationKey + "Dirty");
}
@ -546,10 +454,8 @@ public class MessageFacade implements MessageBroker
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void handleMessage(Object message, PeerAddress peerAddress)
{
if (message instanceof TradeMessage)
{
public void handleMessage(Object message, PeerAddress peerAddress) {
if (message instanceof TradeMessage) {
log.error("####################");
Platform.runLater(() -> incomingTradeMessageListeners.stream().forEach(e -> e.onMessage((TradeMessage) message, peerAddress)));
}

View File

@ -23,6 +23,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.name.Named;
import io.bitsquare.BitSquare;
import io.bitsquare.util.StorageDirectory;
import java.io.File;
import java.io.IOException;
import java.security.KeyPair;
@ -31,6 +32,7 @@ import java.util.Timer;
import java.util.TimerTask;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.tomp2p.connection.DSASignatureFactory;
import net.tomp2p.dht.*;
import net.tomp2p.futures.BaseFuture;
@ -52,8 +54,7 @@ import org.slf4j.LoggerFactory;
* This class is offering generic functionality of TomP2P needed for Bitsquare, like data and domain protection.
* It does not handle any domain aspects of Bitsquare.
*/
public class P2PNode
{
public class P2PNode {
private static final Logger log = LoggerFactory.getLogger(P2PNode.class);
private Thread bootstrapToLocalhostThread;
@ -101,16 +102,14 @@ public class P2PNode
@Inject
public P2PNode(BootstrappedPeerFactory bootstrappedPeerFactory,
@Named("useDiskStorage") Boolean useDiskStorage,
@Named("defaultSeedNode") SeedNodeAddress.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses)
{
@Named("defaultSeedNode") SeedNodeAddress.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses) {
this.bootstrappedPeerFactory = bootstrappedPeerFactory;
this.useDiskStorage = useDiskStorage;
this.defaultStaticSeedNodeAddresses = defaultStaticSeedNodeAddresses;
}
// for unit testing
P2PNode(KeyPair keyPair, PeerDHT peerDHT)
{
P2PNode(KeyPair keyPair, PeerDHT peerDHT) {
this.keyPair = keyPair;
this.peerDHT = peerDHT;
peerDHT.peerBean().keyPair(keyPair);
@ -125,19 +124,16 @@ public class P2PNode
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void setMessageBroker(MessageBroker messageBroker)
{
public void setMessageBroker(MessageBroker messageBroker) {
this.messageBroker = messageBroker;
}
public void setKeyPair(@NotNull KeyPair keyPair)
{
public void setKeyPair(@NotNull KeyPair keyPair) {
this.keyPair = keyPair;
bootstrappedPeerFactory.setKeyPair(keyPair);
}
public void start(FutureCallback<PeerDHT> callback)
{
public void start(FutureCallback<PeerDHT> callback) {
useDiscStorage(useDiskStorage);
bootstrappedPeerFactory.setStorage(storage);
@ -148,8 +144,7 @@ public class P2PNode
}
public void shutDown()
{
public void shutDown() {
if (peerDHT != null && peerDHT.peer() != null)
peerDHT.peer().shutdown();
@ -163,78 +158,64 @@ public class P2PNode
///////////////////////////////////////////////////////////////////////////////////////////
// The data and the domain are protected by that key pair.
public FuturePut putDomainProtectedData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException
{
public FuturePut putDomainProtectedData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException {
data.protectEntry(keyPair);
final Number160 ownerKeyHash = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
return peerDHT.put(locationKey).data(data).keyPair(keyPair).domainKey(ownerKeyHash).protectDomain().start();
}
// No protection, everybody can write.
public FuturePut putData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException
{
public FuturePut putData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException {
return peerDHT.put(locationKey).data(data).start();
}
// Not public readable. Only users with the public key of the peer who stored the data can read that data
public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) throws IOException, ClassNotFoundException
{
public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) throws IOException, ClassNotFoundException {
final Number160 ownerKeyHash = Utils.makeSHAHash(publicKey.getEncoded());
return peerDHT.get(locationKey).domainKey(ownerKeyHash).start();
}
// No protection, everybody can read.
public FutureGet getData(Number160 locationKey) throws IOException, ClassNotFoundException
{
public FutureGet getData(Number160 locationKey) throws IOException, ClassNotFoundException {
return peerDHT.get(locationKey).start();
}
// No domain protection, but entry protection
public FuturePut addProtectedData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException
{
public FuturePut addProtectedData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException {
data.protectEntry(keyPair);
log.trace("addProtectedData with contentKey " + data.hash().toString());
return peerDHT.add(locationKey).data(data).keyPair(keyPair).start();
}
// No domain protection, but entry protection
public FutureRemove removeFromDataMap(Number160 locationKey, Data data) throws IOException, ClassNotFoundException
{
public FutureRemove removeFromDataMap(Number160 locationKey, Data data) throws IOException, ClassNotFoundException {
Number160 contentKey = data.hash();
log.trace("removeFromDataMap with contentKey " + contentKey.toString());
return peerDHT.remove(locationKey).contentKey(contentKey).keyPair(keyPair).start();
}
// Public readable
public FutureGet getDataMap(Number160 locationKey)
{
public FutureGet getDataMap(Number160 locationKey) {
return peerDHT.get(locationKey).all().start();
}
// Send signed payLoad to peer
public FutureDirect sendData(PeerAddress peerAddress, Object payLoad)
{
public FutureDirect sendData(PeerAddress peerAddress, Object payLoad) {
// use 30 seconds as max idle time before connection get closed
FuturePeerConnection futurePeerConnection = peerDHT.peer().createPeerConnection(peerAddress, 30000);
FutureDirect futureDirect = peerDHT.peer().sendDirect(futurePeerConnection).object(payLoad).sign().start();
futureDirect.addListener(new BaseFutureListener<BaseFuture>()
{
futureDirect.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (futureDirect.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (futureDirect.isSuccess()) {
log.debug("sendMessage completed");
}
else
{
} else {
log.error("sendData failed with Reason " + futureDirect.failedReason());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error("Exception at sendData " + t.toString());
}
});
@ -246,66 +227,50 @@ public class P2PNode
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private ListenableFuture<PeerDHT> bootstrap()
{
private ListenableFuture<PeerDHT> bootstrap() {
ListenableFuture<PeerDHT> bootstrapComplete = bootstrappedPeerFactory.start();
Futures.addCallback(bootstrapComplete, new FutureCallback<PeerDHT>()
{
Futures.addCallback(bootstrapComplete, new FutureCallback<PeerDHT>() {
@Override
public void onSuccess(@Nullable PeerDHT peerDHT)
{
try
{
if (peerDHT != null)
{
public void onSuccess(@Nullable PeerDHT peerDHT) {
try {
if (peerDHT != null) {
P2PNode.this.peerDHT = peerDHT;
setupReplyHandler();
FuturePut futurePut = storePeerAddress();
futurePut.addListener(new BaseFutureListener<BaseFuture>()
{
futurePut.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception
{
if (future.isSuccess())
{
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
storedPeerAddress = peerDHT.peerAddress();
log.debug("storedPeerAddress = " + storedPeerAddress);
}
else
{
} else {
log.error("");
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception
{
public void exceptionCaught(Throwable t) throws Exception {
log.error(t.toString());
}
});
}
else
{
} else {
log.error("peerDHT is null");
}
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
log.error(e.toString());
}
}
@Override
public void onFailure(@NotNull Throwable t)
{
public void onFailure(@NotNull Throwable t) {
log.error(t.toString());
}
});
return bootstrapComplete;
}
private void setupReplyHandler()
{
private void setupReplyHandler() {
peerDHT.peer().objectDataReply((sender, request) -> {
if (!sender.equals(peerDHT.peer().peerAddress()))
if (messageBroker != null) messageBroker.handleMessage(request, sender);
@ -315,22 +280,16 @@ public class P2PNode
});
}
private void setupTimerForIPCheck()
{
private void setupTimerForIPCheck() {
Timer timer = new Timer();
long checkIfIPChangedPeriod = 600 * 1000;
timer.scheduleAtFixedRate(new TimerTask()
{
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run()
{
if (peerDHT != null && !storedPeerAddress.equals(peerDHT.peerAddress()))
{
try
{
public void run() {
if (peerDHT != null && !storedPeerAddress.equals(peerDHT.peerAddress())) {
try {
storePeerAddress();
} catch (IOException | ClassNotFoundException e)
{
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
log.error(e.toString());
}
@ -339,36 +298,28 @@ public class P2PNode
}, checkIfIPChangedPeriod, checkIfIPChangedPeriod);
}
private FuturePut storePeerAddress() throws IOException, ClassNotFoundException
{
private FuturePut storePeerAddress() throws IOException, ClassNotFoundException {
Number160 locationKey = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
Data data = new Data(peerDHT.peerAddress());
return putDomainProtectedData(locationKey, data);
}
private void useDiscStorage(boolean useDiscStorage)
{
if (useDiscStorage)
{
try
{
private void useDiscStorage(boolean useDiscStorage) {
if (useDiscStorage) {
try {
File path = new File(StorageDirectory.getStorageDirectory().getCanonicalPath() + "/" + BitSquare.getAppName() + "_tomP2P");
if (!path.exists())
{
if (!path.exists()) {
boolean created = path.mkdir();
if (!created)
throw new RuntimeException("Could not create the directory '" + path + "'");
}
storage = new StorageDisk(Number160.ZERO, path, new DSASignatureFactory());
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
}
}
else
{
} else {
storage = new StorageMemory();
}
}

View File

@ -21,36 +21,30 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SeedNodeAddress
{
public class SeedNodeAddress {
private final String id;
private final String ip;
private final int port;
public SeedNodeAddress(StaticSeedNodeAddresses staticSeedNodeAddresses)
{
public SeedNodeAddress(StaticSeedNodeAddresses staticSeedNodeAddresses) {
this(staticSeedNodeAddresses.getId(), staticSeedNodeAddresses.getIp(), staticSeedNodeAddresses.getPort());
}
public SeedNodeAddress(String id, String ip, int port)
{
public SeedNodeAddress(String id, String ip, int port) {
this.id = id;
this.ip = ip;
this.port = port;
}
public String getId()
{
public String getId() {
return id;
}
public String getIp()
{
public String getIp() {
return ip;
}
public int getPort()
{
public int getPort() {
return port;
}
@ -59,8 +53,7 @@ public class SeedNodeAddress
// Enum
///////////////////////////////////////////////////////////////////////////////////////////
public enum StaticSeedNodeAddresses
{
public enum StaticSeedNodeAddresses {
LOCALHOST("localhost", "127.0.0.1", 5001),
DIGITAL_OCEAN("digitalocean.bitsquare.io", "188.226.179.109", 5000);
@ -68,30 +61,25 @@ public class SeedNodeAddress
private final String ip;
private final int port;
StaticSeedNodeAddresses(String id, String ip, int port)
{
StaticSeedNodeAddresses(String id, String ip, int port) {
this.id = id;
this.ip = ip;
this.port = port;
}
public static List<StaticSeedNodeAddresses> getAllSeedNodeAddresses()
{
public static List<StaticSeedNodeAddresses> getAllSeedNodeAddresses() {
return new ArrayList<>(Arrays.asList(StaticSeedNodeAddresses.values()));
}
public String getId()
{
public String getId() {
return id;
}
public String getIp()
{
public String getIp() {
return ip;
}
public int getPort()
{
public int getPort() {
return port;
}
}

View File

@ -18,12 +18,12 @@
package io.bitsquare.msg.listeners;
import java.util.Map;
import net.tomp2p.peers.Number640;
import net.tomp2p.storage.Data;
@SuppressWarnings({"EmptyMethod", "UnusedParameters"})
public interface ArbitratorListener
{
public interface ArbitratorListener {
void onArbitratorAdded(Data offerData, boolean success);
void onArbitratorsReceived(Map<Number640, Data> dataMap, boolean success);

View File

@ -19,8 +19,7 @@ package io.bitsquare.msg.listeners;
import net.tomp2p.peers.PeerAddress;
public interface GetPeerAddressListener
{
public interface GetPeerAddressListener {
void onResult(PeerAddress peerAddress);
void onFailed();

View File

@ -20,7 +20,6 @@ package io.bitsquare.msg.listeners;
import io.bitsquare.trade.protocol.TradeMessage;
import net.tomp2p.peers.PeerAddress;
public interface IncomingTradeMessageListener
{
public interface IncomingTradeMessageListener {
void onMessage(TradeMessage tradeMessage, PeerAddress sender);
}

View File

@ -18,11 +18,11 @@
package io.bitsquare.msg.listeners;
import java.util.Map;
import net.tomp2p.peers.Number640;
import net.tomp2p.storage.Data;
public interface OrderBookListener
{
public interface OrderBookListener {
@SuppressWarnings("UnusedParameters")
void onOfferAdded(Data offerData, boolean success);

View File

@ -17,8 +17,7 @@
package io.bitsquare.msg.listeners;
public interface OutgoingTradeMessageListener
{
public interface OutgoingTradeMessageListener {
void onFailed();
void onResult();

View File

@ -17,8 +17,7 @@
package io.bitsquare.msg.listeners;
public interface PingPeerListener
{
public interface PingPeerListener {
void onPing();
void onPingPeerResult(boolean success);

View File

@ -19,7 +19,6 @@ package io.bitsquare.msg.listeners;
import net.tomp2p.peers.PeerAddress;
public interface TakeOfferRequestListener
{
public interface TakeOfferRequestListener {
void onTakeOfferRequested(String offerId, PeerAddress sender);
}

View File

@ -20,13 +20,13 @@ package io.bitsquare.settings;
import com.google.bitcoin.core.Coin;
import io.bitsquare.locale.Country;
import io.bitsquare.user.Arbitrator;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class Settings implements Serializable
{
public class Settings implements Serializable {
private static final long serialVersionUID = 7995048077355006861L;
@ -40,8 +40,7 @@ public class Settings implements Serializable
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public Settings()
{
public Settings() {
}
@ -49,10 +48,8 @@ public class Settings implements Serializable
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
public void applyPersistedSettings(Settings persistedSettings)
{
if (persistedSettings != null)
{
public void applyPersistedSettings(Settings persistedSettings) {
if (persistedSettings != null) {
acceptedLanguageLocales = persistedSettings.getAcceptedLanguageLocales();
acceptedCountryLocales = persistedSettings.getAcceptedCountries();
acceptedArbitrators = persistedSettings.getAcceptedArbitrators();
@ -60,42 +57,33 @@ public class Settings implements Serializable
}
}
public void addAcceptedLanguageLocale(Locale locale)
{
if (!acceptedLanguageLocales.contains(locale))
{
public void addAcceptedLanguageLocale(Locale locale) {
if (!acceptedLanguageLocales.contains(locale)) {
acceptedLanguageLocales.add(locale);
}
}
public void removeAcceptedLanguageLocale(Locale item)
{
public void removeAcceptedLanguageLocale(Locale item) {
acceptedLanguageLocales.remove(item);
}
public void addAcceptedCountry(Country locale)
{
if (!acceptedCountryLocales.contains(locale))
{
public void addAcceptedCountry(Country locale) {
if (!acceptedCountryLocales.contains(locale)) {
acceptedCountryLocales.add(locale);
}
}
public void removeAcceptedCountry(Country item)
{
public void removeAcceptedCountry(Country item) {
acceptedCountryLocales.remove(item);
}
public void addAcceptedArbitrator(Arbitrator arbitrator)
{
if (!acceptedArbitrators.contains(arbitrator))
{
public void addAcceptedArbitrator(Arbitrator arbitrator) {
if (!acceptedArbitrators.contains(arbitrator)) {
acceptedArbitrators.add(arbitrator);
}
}
public void removeAcceptedArbitrator(Arbitrator item)
{
public void removeAcceptedArbitrator(Arbitrator item) {
acceptedArbitrators.remove(item);
}
@ -105,30 +93,25 @@ public class Settings implements Serializable
///////////////////////////////////////////////////////////////////////////////////////////
public List<Arbitrator> getAcceptedArbitrators()
{
public List<Arbitrator> getAcceptedArbitrators() {
return acceptedArbitrators;
}
public List<Locale> getAcceptedLanguageLocales()
{
public List<Locale> getAcceptedLanguageLocales() {
return acceptedLanguageLocales;
}
public List<Country> getAcceptedCountries()
{
public List<Country> getAcceptedCountries() {
return acceptedCountryLocales;
}
//TODO
public Arbitrator getRandomArbitrator(Coin amount)
{
public Arbitrator getRandomArbitrator(Coin amount) {
List<Arbitrator> candidates = new ArrayList<>();
//noinspection Convert2streamapi
for (Arbitrator arbitrator : acceptedArbitrators)
{
for (Arbitrator arbitrator : acceptedArbitrators) {
/*if (arbitrator.getArbitrationFeePercent() >= collateral &&
arbitrator.getMinArbitrationAmount().compareTo(amount) < 0)
{ */
@ -139,8 +122,7 @@ public class Settings implements Serializable
}
public double getCollateral()
{
public double getCollateral() {
return collateral;
}

View File

@ -20,6 +20,7 @@ package io.bitsquare.storage;
import com.google.bitcoin.utils.Threading;
import io.bitsquare.BitSquare;
import io.bitsquare.util.FileUtil;
import java.io.*;
import java.util.HashMap;
import java.util.List;
@ -27,14 +28,14 @@ import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.concurrent.GuardedBy;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Simple storage solution for serialized data
*/
public class Persistence
{
public class Persistence {
private static final Logger log = LoggerFactory.getLogger(Persistence.class);
private static final ReentrantLock lock = Threading.lock("Storage");
@ -50,146 +51,113 @@ public class Persistence
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public Persistence()
{
public Persistence() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
public void init()
{
try
{
public void init() {
try {
lock.lock();
final Map<String, Serializable> map = readRootMap();
if (map == null)
{
if (map == null) {
lock.lock();
try
{
try {
saveObjectToFile((Serializable) rootMap);
} finally
{
} finally {
lock.unlock();
}
}
else
{
} else {
rootMap = map;
}
} finally
{
} finally {
lock.unlock();
}
}
// Map
public void write(String key, Map<String, ? extends Serializable> value)
{
public void write(String key, Map<String, ? extends Serializable> value) {
write(key, (Serializable) value);
}
public void write(Object classInstance, String propertyKey, Map<String, ? extends Serializable> value)
{
public void write(Object classInstance, String propertyKey, Map<String, ? extends Serializable> value) {
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(Object classInstance, Map<String, ? extends Serializable> value)
{
public void write(Object classInstance, Map<String, ? extends Serializable> value) {
write(classInstance.getClass().getName(), value);
}
// List
public void write(String key, List<? extends Serializable> value)
{
public void write(String key, List<? extends Serializable> value) {
write(key, (Serializable) value);
}
public void write(Object classInstance, String propertyKey, List<? extends Serializable> value)
{
public void write(Object classInstance, String propertyKey, List<? extends Serializable> value) {
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(Object classInstance, List<? extends Serializable> value)
{
public void write(Object classInstance, List<? extends Serializable> value) {
write(classInstance.getClass().getName(), value);
}
// Serializable
public void write(Object classInstance, String propertyKey, Serializable value)
{
public void write(Object classInstance, String propertyKey, Serializable value) {
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(Object classInstance, Serializable value)
{
public void write(Object classInstance, Serializable value) {
write(classInstance.getClass().getName(), value);
}
public void write(Serializable classInstance)
{
public void write(Serializable classInstance) {
write(classInstance.getClass().getName(), classInstance);
}
public void write(String key, Serializable value)
{
public void write(String key, Serializable value) {
// log.trace("Write object with key = " + key + " / value = " + value);
try
{
try {
lock.lock();
rootMap.put(key, value);
saveObjectToFile((Serializable) rootMap);
} finally
{
} finally {
lock.unlock();
}
}
public Serializable read(Object classInstance)
{
public Serializable read(Object classInstance) {
return read(classInstance.getClass().getName());
}
public Serializable read(Object classInstance, String propertyKey)
{
public Serializable read(Object classInstance, String propertyKey) {
return read(classInstance.getClass().getName() + "." + propertyKey);
}
// read from local rootMap, just if not found read from disc
public Serializable read(String key)
{
try
{
public Serializable read(String key) {
try {
lock.lock();
if (rootMap.containsKey(key))
{
if (rootMap.containsKey(key)) {
// log.trace("Read object with key = " + key + " / value = " + rootMap.get(key));
return rootMap.get(key);
}
else
{
} else {
final Map<String, Serializable> map = readRootMap();
if (map != null)
{
if (map != null) {
rootMap = map;
}
if (rootMap.containsKey(key))
{
if (rootMap.containsKey(key)) {
// log.trace("Read object with key = " + key + " / value = " + rootMap.get(key));
return rootMap.get(key);
}
else
{
} else {
log.info("Object with key = " + key + " not found.");
return null;
}
}
} finally
{
} finally {
lock.unlock();
}
}
@ -200,50 +168,38 @@ public class Persistence
///////////////////////////////////////////////////////////////////////////////////////////
private Map<String, Serializable> readRootMap()
{
try
{
private Map<String, Serializable> readRootMap() {
try {
final Object object = readObjectFromFile(storageFile);
if (object == null)
{
if (object == null) {
log.error("readRootMap returned null object.");
return null;
}
else
{
if (object instanceof Map)
{
} else {
if (object instanceof Map) {
//noinspection unchecked
return (Map<String, Serializable>) object;
}
else
{
} else {
log.error("Object is not type of Map<String, Serializable>");
return null;
}
}
} catch (FileNotFoundException e)
{
} catch (FileNotFoundException e) {
log.trace("File not found is ok for the first execute.");
return null;
} catch (ClassNotFoundException | IOException e2)
{
} catch (ClassNotFoundException | IOException e2) {
e2.printStackTrace();
log.error("Could not read rootMap. " + e2);
return null;
}
}
private void saveObjectToFile(Serializable serializable)
{
private void saveObjectToFile(Serializable serializable) {
File tempFile = null;
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try
{
try {
tempFile = FileUtil.getTempFile(prefix);
// Don't use auto closeable resources in try() as we would need too many try/catch clauses (for tempFile) and we need to close it
@ -263,39 +219,31 @@ public class Persistence
objectOutputStream.close();
FileUtil.writeTempFileToFile(tempFile, storageFile);
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
log.error("save object to file failed." + e);
} finally
{
if (tempFile != null && tempFile.exists())
{
} finally {
if (tempFile != null && tempFile.exists()) {
log.warn("Temp file still exists after failed save.");
if (!tempFile.delete()) log.error("Cannot delete temp file.");
}
try
{
try {
if (objectOutputStream != null) objectOutputStream.close();
if (fileOutputStream != null) fileOutputStream.close();
} catch (IOException e)
{
} catch (IOException e) {
e.printStackTrace();
log.error("Cannot close resources.");
}
}
}
private Object readObjectFromFile(File file) throws IOException, ClassNotFoundException
{
private Object readObjectFromFile(File file) throws IOException, ClassNotFoundException {
lock.lock();
try (final FileInputStream fileInputStream = new FileInputStream(file);
final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream))
{
final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
return objectInputStream.readObject();
} finally
{
} finally {
lock.unlock();
}
}

View File

@ -20,11 +20,11 @@ package io.bitsquare.trade;
import com.google.bitcoin.core.Coin;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.util.DSAKeyUtil;
import java.io.Serializable;
import java.security.PublicKey;
public class Contract implements Serializable
{
public class Contract implements Serializable {
private static final long serialVersionUID = 71472356206100158L;
private final Offer offer;
@ -45,8 +45,7 @@ public class Contract implements Serializable
BankAccount offererBankAccount,
BankAccount takerBankAccount,
PublicKey offererMessagePublicKey,
PublicKey takerMessagePublicKey)
{
PublicKey takerMessagePublicKey) {
this.offer = offer;
this.tradeAmount = tradeAmount;
this.takeOfferFeeTxID = takeOfferFeeTxID;
@ -63,54 +62,44 @@ public class Contract implements Serializable
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public Offer getOffer()
{
public Offer getOffer() {
return offer;
}
public String getTakeOfferFeeTxID()
{
public String getTakeOfferFeeTxID() {
return takeOfferFeeTxID;
}
public Coin getTradeAmount()
{
public Coin getTradeAmount() {
return tradeAmount;
}
public String getOffererAccountID()
{
public String getOffererAccountID() {
return offererAccountID;
}
public String getTakerAccountID()
{
public String getTakerAccountID() {
return takerAccountID;
}
public BankAccount getOffererBankAccount()
{
public BankAccount getOffererBankAccount() {
return offererBankAccount;
}
public BankAccount getTakerBankAccount()
{
public BankAccount getTakerBankAccount() {
return takerBankAccount;
}
public String getTakerMessagePublicKey()
{
public String getTakerMessagePublicKey() {
return takerMessagePublicKeyAsString;
}
public String getOffererMessagePublicKey()
{
public String getOffererMessagePublicKey() {
return offererMessagePublicKeyAsString;
}
@Override
public String toString()
{
public String toString() {
return "Contract{" +
"offer=" + offer +
", takeOfferFeeTxID='" + takeOfferFeeTxID + '\'' +

View File

@ -17,7 +17,6 @@
package io.bitsquare.trade;
public enum Direction
{
public enum Direction {
BUY, SELL
}

View File

@ -21,13 +21,13 @@ import com.google.bitcoin.core.Coin;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.locale.Country;
import io.bitsquare.user.Arbitrator;
import java.io.Serializable;
import java.math.BigDecimal;
import java.security.PublicKey;
import java.util.*;
public class Offer implements Serializable
{
public class Offer implements Serializable {
private static final long serialVersionUID = -971164804305475826L;
// key attributes for lookup
@ -71,8 +71,7 @@ public class Offer implements Serializable
Arbitrator arbitrator,
double collateral,
List<Country> acceptedCountries,
List<Locale> acceptedLanguageLocales)
{
List<Locale> acceptedLanguageLocales) {
this.id = id;
this.messagePublicKey = messagePublicKey;
this.direction = direction;
@ -97,8 +96,7 @@ public class Offer implements Serializable
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public PublicKey getMessagePublicKey()
{
public PublicKey getMessagePublicKey() {
return messagePublicKey;
}
@ -107,102 +105,83 @@ public class Offer implements Serializable
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public String getId()
{
public String getId() {
return id;
}
public double getPrice()
{
public double getPrice() {
return price;
}
public Coin getAmount()
{
public Coin getAmount() {
return amount;
}
public Coin getMinAmount()
{
public Coin getMinAmount() {
return minAmount;
}
public Direction getDirection()
{
public Direction getDirection() {
return direction;
}
public BankAccountType getBankAccountType()
{
public BankAccountType getBankAccountType() {
return bankAccountType;
}
public Currency getCurrency()
{
public Currency getCurrency() {
return currency;
}
public Country getBankAccountCountry()
{
public Country getBankAccountCountry() {
return bankAccountCountry;
}
public List<Country> getAcceptedCountries()
{
public List<Country> getAcceptedCountries() {
return acceptedCountries;
}
public List<Locale> getAcceptedLanguageLocales()
{
public List<Locale> getAcceptedLanguageLocales() {
return acceptedLanguageLocales;
}
public double getVolumeForCoin(Coin coin)
{
public double getVolumeForCoin(Coin coin) {
BigDecimal amountBD = BigDecimal.valueOf(coin.longValue());
BigDecimal volumeBD = amountBD.multiply(BigDecimal.valueOf(price));
return volumeBD.divide(BigDecimal.valueOf(Coin.COIN.value)).doubleValue();
}
public double getOfferVolume()
{
public double getOfferVolume() {
return getVolumeForCoin(amount);
}
public double getMinOfferVolume()
{
public double getMinOfferVolume() {
return getVolumeForCoin(minAmount);
}
public String getOfferFeePaymentTxID()
{
public String getOfferFeePaymentTxID() {
return offerFeePaymentTxID;
}
public void setOfferFeePaymentTxID(String offerFeePaymentTxID)
{
public void setOfferFeePaymentTxID(String offerFeePaymentTxID) {
this.offerFeePaymentTxID = offerFeePaymentTxID;
}
public Arbitrator getArbitrator()
{
public Arbitrator getArbitrator() {
return arbitrator;
}
public double getCollateral()
{
public double getCollateral() {
return collateral;
}
public String getBankAccountId()
{
public String getBankAccountId() {
return bankAccountUID;
}
@Override
public String toString()
{
public String toString() {
return "Offer{" +
"direction=" + direction +
", currency=" + currency +
@ -223,8 +202,7 @@ public class Offer implements Serializable
}
public Date getCreationDate()
{
public Date getCreationDate() {
return creationDate;
}
}

View File

@ -19,12 +19,13 @@ package io.bitsquare.trade;
import com.google.bitcoin.core.Coin;
import com.google.bitcoin.core.Transaction;
import java.io.Serializable;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
public class Trade implements Serializable
{
public class Trade implements Serializable {
private static final long serialVersionUID = -8275323072940974077L;
private final Offer offer;
@ -45,8 +46,7 @@ public class Trade implements Serializable
transient private SimpleBooleanProperty _contractChangedProperty;
transient private SimpleStringProperty _stateChangedProperty;
public Trade(Offer offer)
{
public Trade(Offer offer) {
this.offer = offer;
_depositTxChangedProperty = new SimpleBooleanProperty();
@ -55,8 +55,7 @@ public class Trade implements Serializable
_stateChangedProperty = new SimpleStringProperty();
}
public double getTradeVolume()
{
public double getTradeVolume() {
return offer.getVolumeForCoin(tradeAmount);
}
@ -64,54 +63,44 @@ public class Trade implements Serializable
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setContractTakerSignature(String takerSignature)
{
public void setContractTakerSignature(String takerSignature) {
this.takerSignature = takerSignature;
}
public void setTakeOfferFeeTxID(String takeOfferFeeTxID)
{
public void setTakeOfferFeeTxID(String takeOfferFeeTxID) {
this.takeOfferFeeTxID = takeOfferFeeTxID;
}
public Coin getTradeAmount()
{
public Coin getTradeAmount() {
return tradeAmount;
}
public void setTradeAmount(Coin tradeAmount)
{
public void setTradeAmount(Coin tradeAmount) {
this.tradeAmount = tradeAmount;
}
public Contract getContract()
{
public Contract getContract() {
return contract;
}
public void setContract(Contract contract)
{
public void setContract(Contract contract) {
this.contract = contract;
_contractChangedProperty.set(!_contractChangedProperty.get());
}
public String getId()
{
public String getId() {
return offer.getId();
}
public Offer getOffer()
{
public Offer getOffer() {
return offer;
}
public String getTakeOfferFeeTxId()
{
public String getTakeOfferFeeTxId() {
return takeOfferFeeTxID;
}
public String getContractAsJson()
{
public String getContractAsJson() {
return contractAsJson;
}
@ -120,88 +109,74 @@ public class Trade implements Serializable
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public void setContractAsJson(String contractAsJson)
{
public void setContractAsJson(String contractAsJson) {
this.contractAsJson = contractAsJson;
}
public String getTakerSignature()
{
public String getTakerSignature() {
return takerSignature;
}
public Transaction getDepositTransaction()
{
public Transaction getDepositTransaction() {
return depositTransaction;
}
public void setDepositTransaction(Transaction depositTransaction)
{
public void setDepositTransaction(Transaction depositTransaction) {
this.depositTransaction = depositTransaction;
depositTxChangedProperty().set(!depositTxChangedProperty().get());
}
public Transaction getPayoutTransaction()
{
public Transaction getPayoutTransaction() {
return payoutTransaction;
}
public void setPayoutTransaction(Transaction payoutTransaction)
{
public void setPayoutTransaction(Transaction payoutTransaction) {
this.payoutTransaction = payoutTransaction;
payoutTxChangedProperty().set(!payoutTxChangedProperty().get());
}
public State getState()
{
public State getState() {
return state;
}
public void setState(State state)
{
public void setState(State state) {
this.state = state;
stateChangedProperty().set(state.toString());
}
// The Property fields are not serialized and therefore not initialized when read from disc.
// We need to access then with the getter to be sure it is not null.
public SimpleBooleanProperty depositTxChangedProperty()
{
public SimpleBooleanProperty depositTxChangedProperty() {
if (_depositTxChangedProperty == null) _depositTxChangedProperty = new SimpleBooleanProperty();
return _depositTxChangedProperty;
}
public SimpleBooleanProperty contractChangedProperty()
{
public SimpleBooleanProperty contractChangedProperty() {
if (_contractChangedProperty == null) _contractChangedProperty = new SimpleBooleanProperty();
return _contractChangedProperty;
}
public SimpleBooleanProperty payoutTxChangedProperty()
{
public SimpleBooleanProperty payoutTxChangedProperty() {
if (_payoutTxChangedProperty == null) _payoutTxChangedProperty = new SimpleBooleanProperty();
return _payoutTxChangedProperty;
}
public SimpleStringProperty stateChangedProperty()
{
public SimpleStringProperty stateChangedProperty() {
if (_stateChangedProperty == null) _stateChangedProperty = new SimpleStringProperty();
return _stateChangedProperty;
}
public Coin getCollateralAmount()
{
public Coin getCollateralAmount() {
return tradeAmount.divide((long) (1d / offer.getCollateral()));
}
@Override
public String toString()
{
public String toString() {
return "Trade{" +
"offer=" + offer +
", takeOfferFeeTxID='" + takeOfferFeeTxID + '\'' +
@ -219,8 +194,7 @@ public class Trade implements Serializable
///////////////////////////////////////////////////////////////////////////////////////////
public static enum State
{
public static enum State {
OPEN,
ACCEPTED,
COMPLETED

View File

@ -36,21 +36,24 @@ import io.bitsquare.trade.protocol.createoffer.CreateOfferCoordinator;
import io.bitsquare.trade.protocol.offerer.*;
import io.bitsquare.trade.protocol.taker.*;
import io.bitsquare.user.User;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javax.inject.Inject;
import net.tomp2p.peers.PeerAddress;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TradeManager
{
public class TradeManager {
private static final Logger log = LoggerFactory.getLogger(TradeManager.class);
private final User user;
@ -81,8 +84,7 @@ public class TradeManager
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TradeManager(User user, Settings settings, Persistence persistence, MessageFacade messageFacade, BlockChainFacade blockChainFacade, WalletFacade walletFacade, CryptoFacade cryptoFacade)
{
public TradeManager(User user, Settings settings, Persistence persistence, MessageFacade messageFacade, BlockChainFacade blockChainFacade, WalletFacade walletFacade, CryptoFacade cryptoFacade) {
this.user = user;
this.settings = settings;
this.persistence = persistence;
@ -92,22 +94,16 @@ public class TradeManager
this.cryptoFacade = cryptoFacade;
Object offersObject = persistence.read(this, "offers");
if (offersObject instanceof HashMap)
{
if (offersObject instanceof HashMap) {
offers = (Map<String, Offer>) offersObject;
}
else
{
} else {
offers = new HashMap<>();
}
Object tradesObject = persistence.read(this, "trades");
if (tradesObject instanceof HashMap)
{
if (tradesObject instanceof HashMap) {
trades = (Map<String, Trade>) tradesObject;
}
else
{
} else {
trades = new HashMap<>();
}
@ -119,8 +115,7 @@ public class TradeManager
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void cleanup()
{
public void cleanup() {
messageFacade.removeIncomingTradeMessageListener(this::onIncomingTradeMessage);
}
@ -129,13 +124,11 @@ public class TradeManager
// Event Listeners
///////////////////////////////////////////////////////////////////////////////////////////
public void addTakeOfferRequestListener(TakeOfferRequestListener listener)
{
public void addTakeOfferRequestListener(TakeOfferRequestListener listener) {
takeOfferRequestListeners.add(listener);
}
public void removeTakeOfferRequestListener(TakeOfferRequestListener listener)
{
public void removeTakeOfferRequestListener(TakeOfferRequestListener listener) {
takeOfferRequestListeners.remove(listener);
}
@ -150,60 +143,53 @@ public class TradeManager
Coin amount,
Coin minAmount,
TransactionResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler)
{
ErrorMessageHandler errorMessageHandler) {
Offer offer = new Offer(id,
user.getMessagePublicKey(),
direction,
price,
amount,
minAmount,
user.getCurrentBankAccount().getBankAccountType(),
user.getCurrentBankAccount().getCurrency(),
user.getCurrentBankAccount().getCountry(),
user.getCurrentBankAccount().getUid(),
settings.getRandomArbitrator(amount),
settings.getCollateral(),
settings.getAcceptedCountries(),
settings.getAcceptedLanguageLocales());
Offer offer = new Offer(id,
user.getMessagePublicKey(),
direction,
price,
amount,
minAmount,
user.getCurrentBankAccount().getBankAccountType(),
user.getCurrentBankAccount().getCurrency(),
user.getCurrentBankAccount().getCountry(),
user.getCurrentBankAccount().getUid(),
settings.getRandomArbitrator(amount),
settings.getCollateral(),
settings.getAcceptedCountries(),
settings.getAcceptedLanguageLocales());
if (createOfferCoordinatorMap.containsKey(offer.getId()))
{
if (createOfferCoordinatorMap.containsKey(offer.getId())) {
errorMessageHandler.onFault("A createOfferCoordinator for the offer with the id " + offer.getId() + " already exists.");
}
else
{
} else {
CreateOfferCoordinator createOfferCoordinator = new CreateOfferCoordinator(persistence,
offer,
walletFacade,
messageFacade,
(transactionId) -> {
try
{
offer.setOfferFeePaymentTxID(transactionId.getHashAsString());
addOffer(offer);
createOfferCoordinatorMap.remove(offer.getId());
offer,
walletFacade,
messageFacade,
(transactionId) -> {
try {
offer.setOfferFeePaymentTxID(transactionId.getHashAsString());
addOffer(offer);
createOfferCoordinatorMap.remove(offer.getId());
resultHandler.onResult(transactionId);
} catch (Exception e)
{
//TODO retry policy
errorMessageHandler.onFault("Could not save offer. Reason: " + e.getMessage());
createOfferCoordinatorMap.remove(offer.getId());
}
},
(message, throwable) -> {
errorMessageHandler.onFault(message);
createOfferCoordinatorMap.remove(offer.getId());
});
resultHandler.onResult(transactionId);
} catch (Exception e) {
//TODO retry policy
errorMessageHandler.onFault("Could not save offer. Reason: " + e.getMessage());
createOfferCoordinatorMap.remove(offer.getId());
}
},
(message, throwable) -> {
errorMessageHandler.onFault(message);
createOfferCoordinatorMap.remove(offer.getId());
});
createOfferCoordinatorMap.put(offer.getId(), createOfferCoordinator);
createOfferCoordinator.start();
}
}
private void addOffer(Offer offer) throws IOException
{
private void addOffer(Offer offer) throws IOException {
if (offers.containsKey(offer.getId()))
throw new IllegalStateException("An offer with the id " + offer.getId() + " already exists. ");
@ -211,10 +197,8 @@ public class TradeManager
persistOffers();
}
public void removeOffer(Offer offer)
{
if (!offers.containsKey(offer.getId()))
{
public void removeOffer(Offer offer) {
if (!offers.containsKey(offer.getId())) {
throw new IllegalStateException("offers does not contain the offer with the ID " + offer.getId());
}
@ -224,8 +208,7 @@ public class TradeManager
messageFacade.removeOffer(offer);
}
public Trade takeOffer(Coin amount, Offer offer, ProtocolForTakerAsSellerListener listener)
{
public Trade takeOffer(Coin amount, Offer offer, ProtocolForTakerAsSellerListener listener) {
Trade trade = createTrade(offer);
trade.setTradeAmount(amount);
@ -241,10 +224,8 @@ public class TradeManager
// Manage trades
///////////////////////////////////////////////////////////////////////////////////////////
public Trade createTrade(Offer offer)
{
if (trades.containsKey(offer.getId()))
{
public Trade createTrade(Offer offer) {
if (trades.containsKey(offer.getId())) {
throw new IllegalStateException("trades contains already an trade with the ID " + offer.getId());
}
@ -258,10 +239,8 @@ public class TradeManager
return trade;
}
public void removeTrade(Trade trade)
{
if (!trades.containsKey(trade.getId()))
{
public void removeTrade(Trade trade) {
if (!trades.containsKey(trade.getId())) {
throw new IllegalStateException("trades does not contain the trade with the ID " + trade.getId());
}
@ -277,114 +256,95 @@ public class TradeManager
// Trading protocols
///////////////////////////////////////////////////////////////////////////////////////////
private void createOffererAsBuyerProtocol(String offerId, PeerAddress sender)
{
private void createOffererAsBuyerProtocol(String offerId, PeerAddress sender) {
log.trace("createOffererAsBuyerProtocol offerId = " + offerId);
if (offers.containsKey(offerId))
{
if (offers.containsKey(offerId)) {
Offer offer = offers.get(offerId);
Trade trade = createTrade(offer);
pendingTrade = trade;
ProtocolForOffererAsBuyer protocolForOffererAsBuyer = new ProtocolForOffererAsBuyer(trade,
sender,
messageFacade,
walletFacade,
blockChainFacade,
cryptoFacade,
user,
new ProtocolForOffererAsBuyerListener()
{
@Override
public void onOfferAccepted(Offer offer)
{
removeOffer(offer);
}
sender,
messageFacade,
walletFacade,
blockChainFacade,
cryptoFacade,
user,
new ProtocolForOffererAsBuyerListener() {
@Override
public void onOfferAccepted(Offer offer) {
removeOffer(offer);
}
@Override
public void onDepositTxPublished(String depositTxID)
{
log.trace("trading onDepositTxPublishedMessage " + depositTxID);
}
@Override
public void onDepositTxPublished(String depositTxID) {
log.trace("trading onDepositTxPublishedMessage " + depositTxID);
}
@Override
public void onDepositTxConfirmedUpdate(TransactionConfidence confidence)
{
log.trace("trading onDepositTxConfirmedUpdate");
}
@Override
public void onDepositTxConfirmedUpdate(TransactionConfidence confidence) {
log.trace("trading onDepositTxConfirmedUpdate");
}
@Override
public void onPayoutTxPublished(String payoutTxAsHex)
{
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(),
Utils.parseAsHexOrBase58(payoutTxAsHex));
trade.setPayoutTransaction(payoutTx);
trade.setState(Trade.State.COMPLETED);
log.debug("trading onPayoutTxPublishedMessage");
}
@Override
public void onPayoutTxPublished(String payoutTxAsHex) {
Transaction payoutTx = new Transaction(walletFacade.getWallet().getParams(),
Utils.parseAsHexOrBase58(payoutTxAsHex));
trade.setPayoutTransaction(payoutTx);
trade.setState(Trade.State.COMPLETED);
log.debug("trading onPayoutTxPublishedMessage");
}
@Override
public void onFault(Throwable throwable, ProtocolForOffererAsBuyer.State state)
{
log.error("Error while executing trade process at state: " + state + " / " + throwable);
Popups.openErrorPopup("Error while executing trade process",
"Error while executing trade process at state: " + state + " / " +
throwable);
}
@Override
public void onFault(Throwable throwable, ProtocolForOffererAsBuyer.State state) {
log.error("Error while executing trade process at state: " + state + " / " + throwable);
Popups.openErrorPopup("Error while executing trade process",
"Error while executing trade process at state: " + state + " / " +
throwable);
}
@Override
public void onWaitingForPeerResponse(ProtocolForOffererAsBuyer.State state)
{
log.debug("Waiting for peers response at state " + state);
}
@Override
public void onWaitingForPeerResponse(ProtocolForOffererAsBuyer.State state) {
log.debug("Waiting for peers response at state " + state);
}
@Override
public void onCompleted(ProtocolForOffererAsBuyer.State state)
{
log.debug("Trade protocol completed at state " + state);
}
@Override
public void onCompleted(ProtocolForOffererAsBuyer.State state) {
log.debug("Trade protocol completed at state " + state);
}
@Override
public void onWaitingForUserInteraction(ProtocolForOffererAsBuyer.State state)
{
log.debug("Waiting for UI activity at state " + state);
}
@Override
public void onWaitingForUserInteraction(ProtocolForOffererAsBuyer.State state) {
log.debug("Waiting for UI activity at state " + state);
}
@Override
public void onDepositTxConfirmedInBlockchain()
{
log.trace("trading onDepositTxConfirmedInBlockchain");
}
@Override
public void onDepositTxConfirmedInBlockchain() {
log.trace("trading onDepositTxConfirmedInBlockchain");
}
});
});
if (!offererAsBuyerProtocolMap.containsKey(trade.getId()))
{
if (!offererAsBuyerProtocolMap.containsKey(trade.getId())) {
offererAsBuyerProtocolMap.put(trade.getId(), protocolForOffererAsBuyer);
}
else
{
} else {
// We don't store the protocol in case we have already a pending offer. The protocol is only temporary used to reply with a reject message.
log.trace("offererAsBuyerProtocol not stored as offer is already pending.");
}
protocolForOffererAsBuyer.start();
}
else
{
} else {
log.warn("Incoming offer take request does not match with any saved offer. We ignore that request.");
}
}
public void bankTransferInited(String tradeUID)
{
public void bankTransferInited(String tradeUID) {
offererAsBuyerProtocolMap.get(tradeUID).onUIEventBankTransferInited();
}
public void onFiatReceived(String tradeUID)
{
public void onFiatReceived(String tradeUID) {
takerAsSellerProtocolMap.get(tradeUID).onUIEventFiatReceived();
}
@ -392,44 +352,28 @@ public class TradeManager
// Process incoming tradeMessages
///////////////////////////////////////////////////////////////////////////////////////////
private void onIncomingTradeMessage(TradeMessage tradeMessage, PeerAddress sender)
{
private void onIncomingTradeMessage(TradeMessage tradeMessage, PeerAddress sender) {
// log.trace("processTradingMessage TradeId " + tradeMessage.getTradeId());
log.trace("processTradingMessage instance " + tradeMessage.getClass().getSimpleName());
String tradeId = tradeMessage.getTradeId();
if (tradeMessage instanceof RequestTakeOfferMessage)
{
if (tradeMessage instanceof RequestTakeOfferMessage) {
createOffererAsBuyerProtocol(tradeId, sender);
takeOfferRequestListeners.stream().forEach(e -> e.onTakeOfferRequested(tradeId, sender));
}
else if (tradeMessage instanceof RespondToTakeOfferRequestMessage)
{
} else if (tradeMessage instanceof RespondToTakeOfferRequestMessage) {
takerAsSellerProtocolMap.get(tradeId).onRespondToTakeOfferRequestMessage((RespondToTakeOfferRequestMessage) tradeMessage);
}
else if (tradeMessage instanceof TakeOfferFeePayedMessage)
{
} else if (tradeMessage instanceof TakeOfferFeePayedMessage) {
offererAsBuyerProtocolMap.get(tradeId).onTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage);
}
else if (tradeMessage instanceof RequestTakerDepositPaymentMessage)
{
} else if (tradeMessage instanceof RequestTakerDepositPaymentMessage) {
takerAsSellerProtocolMap.get(tradeId).onRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage);
}
else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage)
{
} else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) {
offererAsBuyerProtocolMap.get(tradeId).onRequestOffererPublishDepositTxMessage((RequestOffererPublishDepositTxMessage) tradeMessage);
}
else if (tradeMessage instanceof DepositTxPublishedMessage)
{
} else if (tradeMessage instanceof DepositTxPublishedMessage) {
takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
}
else if (tradeMessage instanceof BankTransferInitedMessage)
{
} else if (tradeMessage instanceof BankTransferInitedMessage) {
takerAsSellerProtocolMap.get(tradeId).onBankTransferInitedMessage((BankTransferInitedMessage) tradeMessage);
}
else if (tradeMessage instanceof PayoutTxPublishedMessage)
{
} else if (tradeMessage instanceof PayoutTxPublishedMessage) {
offererAsBuyerProtocolMap.get(tradeId).onPayoutTxPublishedMessage((PayoutTxPublishedMessage) tradeMessage);
}
}
@ -439,8 +383,7 @@ public class TradeManager
// Utils
///////////////////////////////////////////////////////////////////////////////////////////
public boolean isOfferAlreadyInTrades(Offer offer)
{
public boolean isOfferAlreadyInTrades(Offer offer) {
return trades.containsKey(offer.getId());
}
@ -449,28 +392,23 @@ public class TradeManager
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public Map<String, Trade> getTrades()
{
public Map<String, Trade> getTrades() {
return trades;
}
public Map<String, Offer> getOffers()
{
public Map<String, Offer> getOffers() {
return offers;
}
public Offer getOffer(String offerId)
{
public Offer getOffer(String offerId) {
return offers.get(offerId);
}
public Trade getPendingTrade()
{
public Trade getPendingTrade() {
return pendingTrade;
}
public final StringProperty getNewTradeProperty()
{
public final StringProperty getNewTradeProperty() {
return this.newTradeProperty;
}
@ -479,25 +417,19 @@ public class TradeManager
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void persistOffers()
{
private void persistOffers() {
persistence.write(this, "offers", offers);
}
private void saveTrades()
{
private void saveTrades() {
persistence.write(this, "trades", trades);
}
@Nullable
public Trade getTrade(String tradeId)
{
if (trades.containsKey(tradeId))
{
public Trade getTrade(String tradeId) {
if (trades.containsKey(tradeId)) {
return trades.get(trades);
}
else
{
} else {
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More