mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 07:15:54 -04:00
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:
parent
9c3df7375a
commit
7d6ca37d06
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 + '\'' +
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) + " %";
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
@ -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 + '\'' +
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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(), "");
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -17,8 +17,7 @@
|
||||
|
||||
package io.bitsquare.msg;
|
||||
|
||||
public interface BootstrapListener
|
||||
{
|
||||
public interface BootstrapListener {
|
||||
public void onCompleted();
|
||||
|
||||
public void onFailed(Throwable throwable);
|
||||
|
@ -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 don’t 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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -17,8 +17,7 @@
|
||||
|
||||
package io.bitsquare.msg.listeners;
|
||||
|
||||
public interface OutgoingTradeMessageListener
|
||||
{
|
||||
public interface OutgoingTradeMessageListener {
|
||||
void onFailed();
|
||||
|
||||
void onResult();
|
||||
|
@ -17,8 +17,7 @@
|
||||
|
||||
package io.bitsquare.msg.listeners;
|
||||
|
||||
public interface PingPeerListener
|
||||
{
|
||||
public interface PingPeerListener {
|
||||
void onPing();
|
||||
|
||||
void onPingPeerResult(boolean success);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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 + '\'' +
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package io.bitsquare.trade;
|
||||
|
||||
public enum Direction
|
||||
{
|
||||
public enum Direction {
|
||||
BUY, SELL
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user