Add deposit funds screen

This commit is contained in:
Manfred Karrer 2016-03-22 00:33:05 +01:00
parent 605cf27eaf
commit fa11cb4a6b
23 changed files with 675 additions and 37 deletions

View file

@ -82,7 +82,7 @@ public class TextFieldWithCopyIcon extends AnchorPane {
// Getter/Setter
///////////////////////////////////////////////////////////////////////////////////////////
private String getText() {
public String getText() {
return text.get();
}

View file

@ -684,7 +684,7 @@ public class MainViewModel implements ViewModel {
private void updateReservedBalance() {
Coin sum = Coin.valueOf(Stream.concat(openOfferManager.getOpenOffers().stream(), tradeManager.getTrades().stream())
.map(tradable -> walletService.getAddressEntryByOfferId(tradable.getId()))
.map(tradable -> walletService.getTradeAddressEntry(tradable.getId()))
.map(addressEntry -> walletService.getBalanceForAddress(addressEntry.getAddress()))
.mapToLong(Coin::getValue)
.sum());
@ -703,7 +703,7 @@ public class MainViewModel implements ViewModel {
if (trade.getContract() != null &&
trade.getTradeAmount() != null &&
trade.getContract().getSellerPayoutAddressString()
.equals(walletService.getAddressEntryByOfferId(trade.getId()).getAddressString())) {
.equals(walletService.getTradeAddressEntry(trade.getId()).getAddressString())) {
balanceInDeposit = balanceInDeposit.add(trade.getTradeAmount());
}
return balanceInDeposit;

View file

@ -16,16 +16,16 @@
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<TabPane fx:id="root" fx:controller="io.bitsquare.gui.main.funds.FundsView"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"
xmlns:fx="http://javafx.com/fxml">
<Tab fx:id="reservedTab" text="Reserved/Locked funds" closable="false"/>
<Tab fx:id="depositTab" text="Deposit funds" closable="false"/>
<Tab fx:id="withdrawalTab" text="Available for withdrawal" closable="false"/>
<Tab fx:id="reservedTab" text="Reserved/Locked funds" closable="false"/>
<Tab fx:id="transactionsTab" text="Transactions" closable="false"/>
</TabPane>

View file

@ -17,17 +17,14 @@
package io.bitsquare.gui.main.funds;
import io.bitsquare.app.BitsquareApp;
import io.bitsquare.common.util.Utilities;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.common.model.Activatable;
import io.bitsquare.gui.common.view.*;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.funds.deposit.DepositView;
import io.bitsquare.gui.main.funds.reserved.ReservedView;
import io.bitsquare.gui.main.funds.transactions.TransactionsView;
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.user.Preferences;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.Tab;
@ -39,7 +36,7 @@ import javax.inject.Inject;
public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML
Tab reservedTab, withdrawalTab, transactionsTab;
Tab depositTab, withdrawalTab, reservedTab, transactionsTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
@ -47,13 +44,11 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
private final ViewLoader viewLoader;
private final Navigation navigation;
private final Preferences preferences;
@Inject
public FundsView(CachingViewLoader viewLoader, Navigation navigation, Preferences preferences) {
public FundsView(CachingViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader;
this.navigation = navigation;
this.preferences = preferences;
}
@Override
@ -64,10 +59,12 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == reservedTab)
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
if (newValue == depositTab)
navigation.navigateTo(MainView.class, FundsView.class, DepositView.class);
else if (newValue == withdrawalTab)
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
else if (newValue == reservedTab)
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
else if (newValue == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
};
@ -78,15 +75,17 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == reservedTab)
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
if (root.getSelectionModel().getSelectedItem() == depositTab)
navigation.navigateTo(MainView.class, FundsView.class, DepositView.class);
else if (root.getSelectionModel().getSelectedItem() == withdrawalTab)
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
else if (root.getSelectionModel().getSelectedItem() == reservedTab)
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
else if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
String key = "tradeWalletInfoAtFunds";
if (!BitsquareApp.DEV_MODE)
/* if (!BitsquareApp.DEV_MODE)
new Popup().backgroundInfo("Bitsquare does not use a single application wallet, but dedicated wallets for every trade.\n\n" +
"Funding of the wallet will be done when needed, for instance when you create or take an offer.\n" +
"Withdrawing funds can be done after a trade is completed.\n\n" +
@ -96,7 +95,7 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
.onAction(() -> Utilities.openWebPage("https://bitsquare.io/faq"))
.closeButtonText("I understand")
.dontShowAgainId(key, preferences)
.show();
.show();*/
}
@Override
@ -113,10 +112,12 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
View view = viewLoader.load(viewClass);
if (view instanceof ReservedView)
currentTab = reservedTab;
if (view instanceof DepositView)
currentTab = depositTab;
else if (view instanceof WithdrawalView)
currentTab = withdrawalTab;
else if (view instanceof ReservedView)
currentTab = reservedTab;
else if (view instanceof TransactionsView)
currentTab = transactionsTab;

View file

@ -0,0 +1,149 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.funds.deposit;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.btc.listeners.TxConfidenceListener;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.util.BSFormatter;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Tooltip;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DepositListItem {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final StringProperty balance = new SimpleStringProperty();
private final WalletService walletService;
private BSFormatter formatter;
private final ConfidenceProgressIndicator progressIndicator;
private final Tooltip tooltip;
private String balanceString;
private String addressString;
private String status = "Unused";
private TxConfidenceListener txConfidenceListener;
// public DepositListItem(AddressEntry addressEntry, Transaction transaction, WalletService walletService, Optional<Tradable> tradableOptional, BSFormatter formatter) {
public DepositListItem(AddressEntry addressEntry, WalletService walletService, BSFormatter formatter) {
this.walletService = walletService;
this.formatter = formatter;
addressString = addressEntry.getAddressString();
// confidence
progressIndicator = new ConfidenceProgressIndicator();
progressIndicator.setId("funds-confidence");
tooltip = new Tooltip("Not used yet");
progressIndicator.setProgress(0);
progressIndicator.setPrefHeight(30);
progressIndicator.setPrefWidth(30);
Tooltip.install(progressIndicator, tooltip);
final Address address = addressEntry.getAddress();
walletService.addBalanceListener(new BalanceListener(address) {
@Override
public void onBalanceChanged(Coin balanceAsCoin, Transaction tx) {
DepositListItem.this.balance.set(formatter.formatCoin(balanceAsCoin));
updateConfidence(walletService.getConfidenceForTxId(tx.getHashAsString()));
if (balanceAsCoin.isPositive())
status = "Funded";
}
});
Coin balanceAsCoin = walletService.getBalanceForAddress(address);
balance.set(formatter.formatCoin(balanceAsCoin));
if (balanceAsCoin.isPositive())
status = "Funded";
TransactionConfidence transactionConfidence = walletService.getConfidenceForAddress(address);
if (transactionConfidence != null) {
updateConfidence(transactionConfidence);
txConfidenceListener = new TxConfidenceListener(transactionConfidence.getTransactionHash().toString()) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(confidence);
}
};
walletService.addTxConfidenceListener(txConfidenceListener);
}
}
public void setStatus(String status) {
this.status = status;
}
public void cleanup() {
walletService.removeTxConfidenceListener(txConfidenceListener);
}
private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) {
switch (confidence.getConfidenceType()) {
case UNKNOWN:
tooltip.setText("Unknown transaction status");
progressIndicator.setProgress(0);
break;
case PENDING:
tooltip.setText("Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 confirmations");
progressIndicator.setProgress(-1.0);
break;
case BUILDING:
tooltip.setText("Confirmed in " + confidence.getDepthInBlocks() + " block(s)");
progressIndicator.setProgress(Math.min(1, (double) confidence.getDepthInBlocks() / 6.0));
break;
case DEAD:
tooltip.setText("Transaction is invalid.");
progressIndicator.setProgress(0);
break;
}
progressIndicator.setPrefSize(24, 24);
}
}
public ConfidenceProgressIndicator getProgressIndicator() {
return progressIndicator;
}
public String getAddressString() {
return addressString;
}
public String getStatus() {
return status;
}
public final StringProperty balanceProperty() {
return this.balance;
}
public String getBalance() {
return balance.get();
}
}

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ This file is part of Bitsquare.
~
~ Bitsquare is free software: you can redistribute it and/or modify it
~ under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or (at
~ your option) any later version.
~
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
~ License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.funds.deposit.DepositView"
spacing="10" xmlns:fx="http://javafx.com/fxml">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<TableView fx:id="table" VBox.vgrow="ALWAYS">
<columns>
<TableColumn text="Select" fx:id="selectColumn" minWidth="110" maxWidth="110" sortable="false"/>
<TableColumn text="Address" fx:id="addressColumn" minWidth="260"/>
<TableColumn text="Balance (BTC)" fx:id="balanceColumn" minWidth="150" maxWidth="150">
<cellValueFactory>
<PropertyValueFactory property="balance"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Confirmations" fx:id="confidenceColumn" minWidth="150" maxWidth="150"/>
<TableColumn text="Status" fx:id="statusColumn" minWidth="150" maxWidth="150"/>
</columns>
</TableView>
<GridPane fx:id="gridPane" hgap="5.0" vgap="5.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="NEVER"/>
<ColumnConstraints hgrow="ALWAYS"/>
<ColumnConstraints hgrow="NEVER"/>
</columnConstraints>
</GridPane>
</VBox>

View file

@ -0,0 +1,395 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.funds.deposit;
import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.common.util.Tuple2;
import io.bitsquare.common.util.Utilities;
import io.bitsquare.gui.common.view.ActivatableView;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.components.AddressTextField;
import io.bitsquare.gui.components.HyperlinkWithIcon;
import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
import io.bitsquare.gui.main.overlays.windows.QRCodeWindow;
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.BtcAddressValidator;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.closed.ClosedTradableManager;
import io.bitsquare.trade.failed.FailedTradesManager;
import io.bitsquare.trade.offer.OpenOfferManager;
import io.bitsquare.user.Preferences;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.uri.BitcoinURI;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import static io.bitsquare.gui.util.FormBuilder.*;
@FxmlView
public class DepositView extends ActivatableView<VBox, Void> {
@FXML
GridPane gridPane;
@FXML
TableView<DepositListItem> table;
@FXML
TableColumn<DepositListItem, DepositListItem> selectColumn, addressColumn, balanceColumn, confidenceColumn, statusColumn;
private ImageView qrCodeImageView;
private int gridRow = 0;
private AddressTextField addressTextField;
Button generateNewAddressButton;
private final WalletService walletService;
private final TradeManager tradeManager;
private final ClosedTradableManager closedTradableManager;
private final FailedTradesManager failedTradesManager;
private final OpenOfferManager openOfferManager;
private final BSFormatter formatter;
private final Preferences preferences;
private final BtcAddressValidator btcAddressValidator;
private final WalletPasswordWindow walletPasswordWindow;
private final OfferDetailsWindow offerDetailsWindow;
private final TradeDetailsWindow tradeDetailsWindow;
private final ObservableList<DepositListItem> depositAddresses = FXCollections.observableArrayList();
private BalanceListener balanceListener;
private TitledGroupBg titledGroupBg;
private Label addressLabel;
private Label qrCodeLabel;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private DepositView(WalletService walletService, TradeManager tradeManager,
ClosedTradableManager closedTradableManager,
FailedTradesManager failedTradesManager, OpenOfferManager openOfferManager,
BSFormatter formatter, Preferences preferences,
BtcAddressValidator btcAddressValidator, WalletPasswordWindow walletPasswordWindow,
OfferDetailsWindow offerDetailsWindow, TradeDetailsWindow tradeDetailsWindow) {
this.walletService = walletService;
this.tradeManager = tradeManager;
this.closedTradableManager = closedTradableManager;
this.failedTradesManager = failedTradesManager;
this.openOfferManager = openOfferManager;
this.formatter = formatter;
this.preferences = preferences;
this.btcAddressValidator = btcAddressValidator;
this.walletPasswordWindow = walletPasswordWindow;
this.offerDetailsWindow = offerDetailsWindow;
this.tradeDetailsWindow = tradeDetailsWindow;
}
@Override
public void initialize() {
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No deposit addresses are generated yet"));
setSelectColumnCellFactory();
setAddressColumnCellFactory();
setStatusColumnCellFactory();
setConfidenceColumnCellFactory();
titledGroupBg = addTitledGroupBg(gridPane, gridRow, 2, "Fund your wallet");
qrCodeLabel = addLabel(gridPane, gridRow, "QR-Code:", 0);
//GridPane.setMargin(qrCodeLabel, new Insets(Layout.FIRST_ROW_DISTANCE - 9, 0, 0, 5));
qrCodeImageView = new ImageView();
qrCodeImageView.setStyle("-fx-cursor: hand;");
Tooltip.install(qrCodeImageView, new Tooltip("Open large QR-Code window"));
qrCodeImageView.setOnMouseClicked(e -> new QRCodeWindow(getBitcoinURI()).show());
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 1);
GridPane.setMargin(qrCodeImageView, new Insets(Layout.FIRST_ROW_DISTANCE, 0, 0, 0));
gridPane.getChildren().add(qrCodeImageView);
Tuple2<Label, AddressTextField> addressTuple = addLabelAddressTextField(gridPane, ++gridRow, "Address:");
addressLabel = addressTuple.first;
GridPane.setValignment(addressLabel, VPos.TOP);
GridPane.setMargin(addressLabel, new Insets(3, 0, 0, 0));
addressTextField = addressTuple.second;
titledGroupBg.setVisible(false);
titledGroupBg.setManaged(false);
qrCodeLabel.setVisible(false);
qrCodeLabel.setManaged(false);
qrCodeImageView.setVisible(false);
qrCodeImageView.setManaged(false);
addressLabel.setVisible(false);
addressLabel.setManaged(false);
addressTextField.setVisible(false);
addressTextField.setManaged(false);
generateNewAddressButton = addButton(gridPane, ++gridRow, "Generate new address", -20);
generateNewAddressButton.setOnAction(event -> {
boolean hasUnUsedAddress = walletService.getSavingsAddressEntryList().stream()
.filter(addressEntry -> walletService.getBalanceForAddress(addressEntry.getAddress()).isZero())
.findAny().isPresent();
if (hasUnUsedAddress) {
new Popup().warning("You have already addresses generated which are still not used.\n" +
"Please select in the address table an unused address.").show();
} else {
AddressEntry newSavingsAddressEntry = walletService.getNewSavingsAddressEntry();
fillForm(newSavingsAddressEntry.getAddressString());
updateList();
}
});
balanceListener = new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance, Transaction tx) {
updateList();
}
};
}
@NotNull
private String getBitcoinURI() {
return BitcoinURI.convertToBitcoinURI(addressTextField.getAddress(),
null,
null,
null);
}
@Override
protected void activate() {
updateList();
walletService.addBalanceListener(balanceListener);
}
@Override
protected void deactivate() {
depositAddresses.forEach(DepositListItem::cleanup);
walletService.removeBalanceListener(balanceListener);
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI handlers
///////////////////////////////////////////////////////////////////////////////////////////
private void fillForm(String address) {
titledGroupBg.setVisible(true);
titledGroupBg.setManaged(true);
qrCodeLabel.setVisible(true);
qrCodeLabel.setManaged(true);
qrCodeImageView.setVisible(true);
qrCodeImageView.setManaged(true);
addressLabel.setVisible(true);
addressLabel.setManaged(true);
addressTextField.setVisible(true);
addressTextField.setManaged(true);
GridPane.setMargin(generateNewAddressButton, new Insets(15, 0, 0, 0));
addressTextField.setAddress(address);
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.withSize(150, 150) // code has 41 elements 8 px is border with 150 we get 3x scale and min. border
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
qrCodeImageView.setImage(qrImage);
}
private void openBlockExplorer(DepositListItem item) {
if (item.getAddressString() != null) {
try {
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
} catch (Exception e) {
log.error(e.getMessage());
new Popup().warning("Opening browser failed. Please check your internet " +
"connection.").show();
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void updateList() {
depositAddresses.clear();
walletService.getSavingsAddressEntryList().stream()
.forEach(e -> depositAddresses.add(new DepositListItem(e, walletService, formatter)));
table.setItems(depositAddresses);
}
///////////////////////////////////////////////////////////////////////////////////////////
// ColumnCellFactories
///////////////////////////////////////////////////////////////////////////////////////////
private void setStatusColumnCellFactory() {
statusColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
statusColumn.setCellFactory(new Callback<TableColumn<DepositListItem, DepositListItem>,
TableCell<DepositListItem, DepositListItem>>() {
@Override
public TableCell<DepositListItem, DepositListItem> call(TableColumn<DepositListItem,
DepositListItem> column) {
return new TableCell<DepositListItem, DepositListItem>() {
@Override
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
setGraphic(new Label(item.getStatus()));
} else {
setGraphic(null);
}
}
};
}
});
}
private void setSelectColumnCellFactory() {
selectColumn.setCellValueFactory((addressListItem) ->
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
selectColumn.setCellFactory(
new Callback<TableColumn<DepositListItem, DepositListItem>, TableCell<DepositListItem,
DepositListItem>>() {
@Override
public TableCell<DepositListItem, DepositListItem> call(TableColumn<DepositListItem,
DepositListItem> column) {
return new TableCell<DepositListItem, DepositListItem>() {
Button button;
@Override
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
if (button == null) {
button = new Button("Select");
button.setOnAction(e -> fillForm(item.getAddressString()));
setGraphic(button);
}
} else {
setGraphic(null);
if (button != null) {
button.setOnAction(null);
button = null;
}
}
}
};
}
});
}
private void setAddressColumnCellFactory() {
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
addressColumn.setCellFactory(
new Callback<TableColumn<DepositListItem, DepositListItem>, TableCell<DepositListItem,
DepositListItem>>() {
@Override
public TableCell<DepositListItem, DepositListItem> call(TableColumn<DepositListItem,
DepositListItem> column) {
return new TableCell<DepositListItem, DepositListItem>() {
private HyperlinkWithIcon field;
@Override
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
String addressString = item.getAddressString();
field = new HyperlinkWithIcon(addressString, AwesomeIcon.EXTERNAL_LINK);
field.setOnAction(event -> openBlockExplorer(item));
field.setTooltip(new Tooltip("Open external blockchain explorer for " +
"address: " + addressString));
setGraphic(field);
} else {
setGraphic(null);
if (field != null)
field.setOnAction(null);
}
}
};
}
});
}
private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) ->
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
confidenceColumn.setCellFactory(
new Callback<TableColumn<DepositListItem, DepositListItem>, TableCell<DepositListItem,
DepositListItem>>() {
@Override
public TableCell<DepositListItem, DepositListItem> call(TableColumn<DepositListItem,
DepositListItem> column) {
return new TableCell<DepositListItem, DepositListItem>() {
@Override
public void updateItem(final DepositListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
setGraphic(item.getProgressIndicator());
} else {
setGraphic(null);
}
}
};
}
});
}
}

View file

@ -123,7 +123,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
private void updateList() {
reservedAddresses.forEach(ReservedListItem::cleanup);
reservedAddresses.setAll(Stream.concat(openOfferManager.getOpenOffers().stream(), tradeManager.getTrades().stream())
.map(tradable -> new ReservedListItem(tradable, walletService.getAddressEntryByOfferId(tradable.getOffer().getId()), walletService, formatter))
.map(tradable -> new ReservedListItem(tradable, walletService.getTradeAddressEntry(tradable.getOffer().getId()), walletService, formatter))
.collect(Collectors.toList()));
reservedAddresses.sort((o1, o2) -> getTradable(o2).get().getDate().compareTo(getTradable(o1).get().getDate()));

View file

@ -127,7 +127,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
this.formatter = formatter;
offerId = UUID.randomUUID().toString();
addressEntry = walletService.getAddressEntryByOfferId(offerId);
addressEntry = walletService.getTradeAddressEntry(offerId);
offerFeeAsCoin = FeePolicy.getCreateOfferFee();
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
securityDepositAsCoin = FeePolicy.getSecurityDeposit();

View file

@ -734,6 +734,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
qrCodeImageView = new ImageView();
qrCodeImageView.setVisible(false);
qrCodeImageView.setStyle("-fx-cursor: hand;");
Tooltip.install(qrCodeImageView, new Tooltip("Open large QR-Code window"));
qrCodeImageView.setOnMouseClicked(e -> new QRCodeWindow(getBitcoinURI()).show());
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 2);

View file

@ -155,7 +155,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
void initWithData(Offer offer) {
this.offer = offer;
addressEntry = walletService.getAddressEntryByOfferId(offer.getId());
addressEntry = walletService.getTradeAddressEntry(offer.getId());
checkNotNull(addressEntry, "addressEntry must not be null");
ObservableList<PaymentAccount> possiblePaymentAccounts = getPossiblePaymentAccounts();

View file

@ -668,6 +668,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
qrCodeImageView = new ImageView();
qrCodeImageView.setVisible(false);
qrCodeImageView.setStyle("-fx-cursor: hand;");
Tooltip.install(qrCodeImageView, new Tooltip("Open large QR-Code window"));
qrCodeImageView.setOnMouseClicked(e -> new QRCodeWindow(getBitcoinURI()).show());
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 2);

View file

@ -159,7 +159,7 @@ public class BuyerStep5View extends TradeStepView {
private void reviewWithdrawal() {
Coin senderAmount = trade.getPayoutAmount();
WalletService walletService = model.dataModel.walletService;
AddressEntry fromAddressesEntry = walletService.getAddressEntryByOfferId(trade.getId());
AddressEntry fromAddressesEntry = walletService.getTradeAddressEntry(trade.getId());
String fromAddresses = fromAddressesEntry.getAddressString();
String toAddresses = withdrawAddressTextField.getText();