mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
balance chart, transactions view refactor, tx viewer coin labels updating
This commit is contained in:
parent
d8c19ac0f8
commit
539013919b
15 changed files with 337 additions and 28 deletions
|
@ -0,0 +1,84 @@
|
||||||
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.BitcoinUnit;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
|
import com.sparrowwallet.sparrow.wallet.TransactionEntry;
|
||||||
|
import com.sparrowwallet.sparrow.wallet.WalletTransactionsEntry;
|
||||||
|
import javafx.beans.NamedArg;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.chart.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class BalanceChart extends LineChart<Number, Number> {
|
||||||
|
private XYChart.Series<Number, Number> balanceSeries;
|
||||||
|
|
||||||
|
private TransactionEntry selectedEntry;
|
||||||
|
|
||||||
|
public BalanceChart(@NamedArg("xAxis") Axis<Number> xAxis, @NamedArg("yAxis") Axis<Number> yAxis) {
|
||||||
|
super(xAxis, yAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(WalletTransactionsEntry walletTransactionsEntry) {
|
||||||
|
balanceSeries = new XYChart.Series<>();
|
||||||
|
getData().add(balanceSeries);
|
||||||
|
update(walletTransactionsEntry);
|
||||||
|
|
||||||
|
BitcoinUnit unit = Config.get().getBitcoinUnit();
|
||||||
|
setBitcoinUnit(walletTransactionsEntry.getWallet(), unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(WalletTransactionsEntry walletTransactionsEntry) {
|
||||||
|
balanceSeries.getData().clear();
|
||||||
|
|
||||||
|
List<Data<Number, Number>> balanceDataList = walletTransactionsEntry.getChildren().stream()
|
||||||
|
.map(entry -> (TransactionEntry)entry)
|
||||||
|
.map(txEntry -> new XYChart.Data<>((Number)txEntry.getBlockTransaction().getDate().getTime(), (Number)txEntry.getBalance(), txEntry))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if(!balanceDataList.isEmpty()) {
|
||||||
|
long min = balanceDataList.stream().map(data -> data.getXValue().longValue()).min(Long::compare).get();
|
||||||
|
long max = balanceDataList.stream().map(data -> data.getXValue().longValue()).max(Long::compare).get();
|
||||||
|
|
||||||
|
DateAxisFormatter dateAxisFormatter = new DateAxisFormatter(max - min);
|
||||||
|
NumberAxis xAxis = (NumberAxis)getXAxis();
|
||||||
|
xAxis.setTickLabelFormatter(dateAxisFormatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
balanceSeries.getData().addAll(balanceDataList);
|
||||||
|
|
||||||
|
if(selectedEntry != null) {
|
||||||
|
select(selectedEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void select(TransactionEntry transactionEntry) {
|
||||||
|
Set<Node> selectedSymbols = lookupAll(".chart-line-symbol.selected");
|
||||||
|
for(Node selectedSymbol : selectedSymbols) {
|
||||||
|
selectedSymbol.getStyleClass().remove("selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < balanceSeries.getData().size(); i++) {
|
||||||
|
XYChart.Data<Number, Number> data = balanceSeries.getData().get(i);
|
||||||
|
Node symbol = lookup(".chart-line-symbol.data" + i);
|
||||||
|
if(symbol != null) {
|
||||||
|
if(data.getXValue().equals(transactionEntry.getBlockTransaction().getDate().getTime())) {
|
||||||
|
symbol.getStyleClass().add("selected");
|
||||||
|
selectedEntry = transactionEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitcoinUnit(Wallet wallet, BitcoinUnit unit) {
|
||||||
|
if(unit == null || unit.equals(BitcoinUnit.AUTO)) {
|
||||||
|
unit = wallet.getAutoUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAxis yaxis = (NumberAxis)getYAxis();
|
||||||
|
yaxis.setTickLabelFormatter(new CoinAxisFormatter(yaxis, unit));
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,7 +29,7 @@ public class CoinLabel extends CopyableLabel {
|
||||||
public CoinLabel(String text) {
|
public CoinLabel(String text) {
|
||||||
super(text);
|
super(text);
|
||||||
BTC_FORMAT.setMaximumFractionDigits(8);
|
BTC_FORMAT.setMaximumFractionDigits(8);
|
||||||
valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue));
|
valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue, Config.get().getBitcoinUnit()));
|
||||||
tooltip = new Tooltip();
|
tooltip = new Tooltip();
|
||||||
contextMenu = new CoinContextMenu();
|
contextMenu = new CoinContextMenu();
|
||||||
}
|
}
|
||||||
|
@ -46,14 +46,22 @@ public class CoinLabel extends CopyableLabel {
|
||||||
this.value.set(value);
|
this.value.set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setValueAsText(Long value) {
|
public void refresh() {
|
||||||
|
refresh(Config.get().getBitcoinUnit());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(BitcoinUnit bitcoinUnit) {
|
||||||
|
setValueAsText(getValue(), bitcoinUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setValueAsText(Long value, BitcoinUnit bitcoinUnit) {
|
||||||
setTooltip(tooltip);
|
setTooltip(tooltip);
|
||||||
setContextMenu(contextMenu);
|
setContextMenu(contextMenu);
|
||||||
|
|
||||||
String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats";
|
String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats";
|
||||||
String btcValue = BTC_FORMAT.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
|
String btcValue = BTC_FORMAT.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
|
||||||
|
|
||||||
BitcoinUnit unit = Config.get().getBitcoinUnit();
|
BitcoinUnit unit = bitcoinUnit;
|
||||||
if(unit == null || unit.equals(BitcoinUnit.AUTO)) {
|
if(unit == null || unit.equals(BitcoinUnit.AUTO)) {
|
||||||
unit = (value >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS);
|
unit = (value >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class DateAxisFormatter extends StringConverter<Number> {
|
||||||
|
private static final DateFormat HOUR_FORMAT = new SimpleDateFormat("HH:mm");
|
||||||
|
private static final DateFormat DAY_FORMAT = new SimpleDateFormat("d MMM");
|
||||||
|
private static final DateFormat MONTH_FORMAT = new SimpleDateFormat("MMM yy");
|
||||||
|
|
||||||
|
private final DateFormat dateFormat;
|
||||||
|
private int oddCounter;
|
||||||
|
|
||||||
|
public DateAxisFormatter(long duration) {
|
||||||
|
if(duration < (24 * 60 * 60 * 1000L)) {
|
||||||
|
dateFormat = HOUR_FORMAT;
|
||||||
|
} else if(duration < (365 * 24 * 60 * 60 * 1000L)) {
|
||||||
|
dateFormat = DAY_FORMAT;
|
||||||
|
} else {
|
||||||
|
dateFormat = MONTH_FORMAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(Number object) {
|
||||||
|
oddCounter++;
|
||||||
|
return oddCounter % 3 == 0 ? dateFormat.format(new Date(object.longValue())) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Number fromString(String string) {
|
||||||
|
try {
|
||||||
|
Date date = dateFormat.parse(string);
|
||||||
|
return date.getTime();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,9 +73,7 @@ public class TransactionsTreeTable extends CoinTreeTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHistory(List<WalletNode> updatedNodes) {
|
public void updateHistory(List<WalletNode> updatedNodes) {
|
||||||
//Recalculate from scratch and update accordingly - any changes may affect the balance of other transactions
|
//Transaction entries should have already been updated using WalletTransactionsEntry.updateHistory, so only a resort required
|
||||||
WalletTransactionsEntry rootEntry = (WalletTransactionsEntry)getRoot().getValue();
|
|
||||||
rootEntry.updateTransactions();
|
|
||||||
sort();
|
sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,7 @@ public class UtxosTreeTable extends CoinTreeTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHistory(List<WalletNode> updatedNodes) {
|
public void updateHistory(List<WalletNode> updatedNodes) {
|
||||||
//Recalculate from scratch and update accordingly
|
//Utxo entries should have already been updated, so only a resort required
|
||||||
WalletUtxosEntry rootEntry = (WalletUtxosEntry)getRoot().getValue();
|
|
||||||
rootEntry.updateUtxos();
|
|
||||||
sort();
|
sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.CoinLabel;
|
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||||
import com.sparrowwallet.sparrow.control.IdLabel;
|
import com.sparrowwallet.sparrow.control.IdLabel;
|
||||||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||||
|
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
|
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.TransactionChangedEvent;
|
import com.sparrowwallet.sparrow.event.TransactionChangedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.TransactionLocktimeChangedEvent;
|
import com.sparrowwallet.sparrow.event.TransactionLocktimeChangedEvent;
|
||||||
|
@ -356,4 +357,9 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
|
fee.refresh(event.getBitcoinUnit());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,10 +9,7 @@ import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.*;
|
import com.sparrowwallet.sparrow.control.*;
|
||||||
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
import com.sparrowwallet.sparrow.event.TransactionChangedEvent;
|
|
||||||
import com.sparrowwallet.sparrow.event.TransactionLocktimeChangedEvent;
|
|
||||||
import com.sparrowwallet.sparrow.event.ViewTransactionEvent;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
@ -498,4 +495,9 @@ public class InputController extends TransactionFormController implements Initia
|
||||||
locktimeAbsolute.setText(Long.toString(event.getTransaction().getLocktime()));
|
locktimeAbsolute.setText(Long.toString(event.getTransaction().getLocktime()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
|
spends.refresh(event.getBitcoinUnit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.CoinLabel;
|
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||||
|
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
|
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
@ -160,4 +161,9 @@ public class InputsController extends TransactionFormController implements Initi
|
||||||
updateBlockTransactionInputs(event.getInputTransactions());
|
updateBlockTransactionInputs(event.getInputTransactions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
|
total.refresh(event.getBitcoinUnit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.AddressLabel;
|
import com.sparrowwallet.sparrow.control.AddressLabel;
|
||||||
import com.sparrowwallet.sparrow.control.CoinLabel;
|
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||||
|
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.BlockTransactionOutputsFetchedEvent;
|
import com.sparrowwallet.sparrow.event.BlockTransactionOutputsFetchedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.ViewTransactionEvent;
|
import com.sparrowwallet.sparrow.event.ViewTransactionEvent;
|
||||||
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
||||||
|
@ -142,4 +143,9 @@ public class OutputController extends TransactionFormController implements Initi
|
||||||
updateSpent(event.getOutputTransactions());
|
updateSpent(event.getOutputTransactions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
|
value.refresh(event.getBitcoinUnit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||||
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.CoinLabel;
|
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||||
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||||
|
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.chart.PieChart;
|
import javafx.scene.chart.PieChart;
|
||||||
|
@ -25,7 +28,7 @@ public class OutputsController extends TransactionFormController implements Init
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
EventManager.get().register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModel(OutputsForm form) {
|
public void setModel(OutputsForm form) {
|
||||||
|
@ -47,4 +50,9 @@ public class OutputsController extends TransactionFormController implements Init
|
||||||
addPieData(outputsPie, tx.getOutputs());
|
addPieData(outputsPie, tx.getOutputs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
|
total.refresh(event.getBitcoinUnit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,15 @@ package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
import com.sparrowwallet.sparrow.control.BalanceChart;
|
||||||
|
import com.sparrowwallet.sparrow.control.CoinLabel;
|
||||||
|
import com.sparrowwallet.sparrow.control.CopyableLabel;
|
||||||
import com.sparrowwallet.sparrow.control.TransactionsTreeTable;
|
import com.sparrowwallet.sparrow.control.TransactionsTreeTable;
|
||||||
import com.sparrowwallet.sparrow.event.*;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.TreeItem;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -13,9 +18,21 @@ import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class TransactionsController extends WalletFormController implements Initializable {
|
public class TransactionsController extends WalletFormController implements Initializable {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private CoinLabel balance;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private CopyableLabel fiatBalance;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private CoinLabel mempoolBalance;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TransactionsTreeTable transactionsTable;
|
private TransactionsTreeTable transactionsTable;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private BalanceChart balanceChart;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
EventManager.get().register(this);
|
EventManager.get().register(this);
|
||||||
|
@ -23,20 +40,46 @@ public class TransactionsController extends WalletFormController implements Init
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeView() {
|
public void initializeView() {
|
||||||
transactionsTable.initialize(getWalletForm().getWalletTransactionsEntry());
|
WalletTransactionsEntry walletTransactionsEntry = getWalletForm().getWalletTransactionsEntry();
|
||||||
|
|
||||||
|
transactionsTable.initialize(walletTransactionsEntry);
|
||||||
|
|
||||||
|
balance.setValue(walletTransactionsEntry.getBalance());
|
||||||
|
mempoolBalance.setValue(walletTransactionsEntry.getMempoolBalance());
|
||||||
|
balanceChart.initialize(walletTransactionsEntry);
|
||||||
|
|
||||||
|
transactionsTable.getSelectionModel().getSelectedIndices().addListener((ListChangeListener<Integer>) c -> {
|
||||||
|
TreeItem<Entry> selectedItem = transactionsTable.getSelectionModel().getSelectedItem();
|
||||||
|
if(selectedItem != null && selectedItem.getValue() instanceof TransactionEntry) {
|
||||||
|
balanceChart.select((TransactionEntry)selectedItem.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void walletNodesChanged(WalletNodesChangedEvent event) {
|
public void walletNodesChanged(WalletNodesChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
transactionsTable.updateAll(getWalletForm().getWalletTransactionsEntry());
|
WalletTransactionsEntry walletTransactionsEntry = getWalletForm().getWalletTransactionsEntry();
|
||||||
|
|
||||||
|
transactionsTable.updateAll(walletTransactionsEntry);
|
||||||
|
balance.setValue(walletTransactionsEntry.getBalance());
|
||||||
|
mempoolBalance.setValue(walletTransactionsEntry.getMempoolBalance());
|
||||||
|
balanceChart.update(walletTransactionsEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
|
WalletTransactionsEntry walletTransactionsEntry = getWalletForm().getWalletTransactionsEntry();
|
||||||
|
|
||||||
|
//Will automatically update transactionsTable transactions and recalculate balances
|
||||||
|
walletTransactionsEntry.updateTransactions();
|
||||||
|
|
||||||
transactionsTable.updateHistory(event.getHistoryChangedNodes());
|
transactionsTable.updateHistory(event.getHistoryChangedNodes());
|
||||||
|
balance.setValue(walletTransactionsEntry.getBalance());
|
||||||
|
mempoolBalance.setValue(walletTransactionsEntry.getMempoolBalance());
|
||||||
|
balanceChart.update(walletTransactionsEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +87,16 @@ public class TransactionsController extends WalletFormController implements Init
|
||||||
public void walletEntryLabelChanged(WalletEntryLabelChangedEvent event) {
|
public void walletEntryLabelChanged(WalletEntryLabelChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
transactionsTable.updateLabel(event.getEntry());
|
transactionsTable.updateLabel(event.getEntry());
|
||||||
|
balanceChart.update(getWalletForm().getWalletTransactionsEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) {
|
||||||
transactionsTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit());
|
transactionsTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit());
|
||||||
|
balanceChart.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit());
|
||||||
|
balance.refresh(event.getBitcoinUnit());
|
||||||
|
mempoolBalance.refresh(event.getBitcoinUnit());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Remove
|
//TODO: Remove
|
||||||
|
|
|
@ -44,16 +44,22 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void walletNodesChanged(WalletNodesChangedEvent event) {
|
public void walletNodesChanged(WalletNodesChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
utxosTable.updateAll(getWalletForm().getWalletUtxosEntry());
|
WalletUtxosEntry walletUtxosEntry = getWalletForm().getWalletUtxosEntry();
|
||||||
utxosChart.update(getWalletForm().getWalletUtxosEntry());
|
utxosTable.updateAll(walletUtxosEntry);
|
||||||
|
utxosChart.update(walletUtxosEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
||||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||||
|
WalletUtxosEntry walletUtxosEntry = getWalletForm().getWalletUtxosEntry();
|
||||||
|
|
||||||
|
//Will automatically update utxosTable
|
||||||
|
walletUtxosEntry.updateUtxos();
|
||||||
|
|
||||||
utxosTable.updateHistory(event.getHistoryChangedNodes());
|
utxosTable.updateHistory(event.getHistoryChangedNodes());
|
||||||
utxosChart.update(getWalletForm().getWalletUtxosEntry());
|
utxosChart.update(walletUtxosEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,17 +31,24 @@ public class WalletTransactionsEntry extends Entry {
|
||||||
|
|
||||||
protected void calculateBalances() {
|
protected void calculateBalances() {
|
||||||
long balance = 0L;
|
long balance = 0L;
|
||||||
|
long mempoolBalance = 0L;
|
||||||
|
|
||||||
//Note transaction entries must be in ascending order. This sorting is ultimately done according to BlockTransactions' comparator
|
//Note transaction entries must be in ascending order. This sorting is ultimately done according to BlockTransactions' comparator
|
||||||
getChildren().sort(Comparator.comparing(TransactionEntry.class::cast));
|
getChildren().sort(Comparator.comparing(TransactionEntry.class::cast));
|
||||||
|
|
||||||
for(Entry entry : getChildren()) {
|
for(Entry entry : getChildren()) {
|
||||||
TransactionEntry transactionEntry = (TransactionEntry)entry;
|
TransactionEntry transactionEntry = (TransactionEntry)entry;
|
||||||
|
if(transactionEntry.getConfirmations() != 0) {
|
||||||
balance += entry.getValue();
|
balance += entry.getValue();
|
||||||
|
} else {
|
||||||
|
mempoolBalance += entry.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
transactionEntry.setBalance(balance);
|
transactionEntry.setBalance(balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBalance(balance);
|
setBalance(balance);
|
||||||
|
setMempoolBalance(mempoolBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTransactions() {
|
public void updateTransactions() {
|
||||||
|
@ -126,6 +133,39 @@ public class WalletTransactionsEntry extends Entry {
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the wallet balance in the mempool
|
||||||
|
*/
|
||||||
|
private LongProperty mempoolBalance;
|
||||||
|
|
||||||
|
public final void setMempoolBalance(long value) {
|
||||||
|
if(mempoolBalance != null || value != 0) {
|
||||||
|
mempoolBalanceProperty().set(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final long getMempoolBalance() {
|
||||||
|
return mempoolBalance == null ? 0L : mempoolBalance.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final LongProperty mempoolBalanceProperty() {
|
||||||
|
if(mempoolBalance == null) {
|
||||||
|
mempoolBalance = new LongPropertyBase(0L) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getBean() {
|
||||||
|
return WalletTransactionsEntry.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "mempoolBalance";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return mempoolBalance;
|
||||||
|
}
|
||||||
|
|
||||||
private static class WalletTransaction {
|
private static class WalletTransaction {
|
||||||
private final Wallet wallet;
|
private final Wallet wallet;
|
||||||
private final BlockTransaction blockTransaction;
|
private final BlockTransaction blockTransaction;
|
||||||
|
|
|
@ -3,3 +3,23 @@
|
||||||
-fx-font-size: 1.2em;
|
-fx-font-size: 1.2em;
|
||||||
-fx-padding: 10 0 10 0;
|
-fx-padding: 10 0 10 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#balanceChart {
|
||||||
|
-fx-padding: 10 0 0 0;
|
||||||
|
-fx-max-width: 350px;
|
||||||
|
-fx-pref-width: 350px;
|
||||||
|
-fx-max-height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default-color0.chart-series-line {
|
||||||
|
-fx-stroke: rgba(105, 108, 119, 0.3);
|
||||||
|
-fx-stroke-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-line-symbol {
|
||||||
|
-fx-background-color: rgba(105, 108, 119, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-line-symbol.selected {
|
||||||
|
-fx-background-color: rgba(30, 136, 207, 0.8);
|
||||||
|
}
|
|
@ -7,15 +7,51 @@
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import com.sparrowwallet.sparrow.control.TransactionsTreeTable?>
|
<?import com.sparrowwallet.sparrow.control.TransactionsTreeTable?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import com.sparrowwallet.sparrow.control.BalanceChart?>
|
||||||
|
<?import javafx.scene.chart.NumberAxis?>
|
||||||
|
<?import tornadofx.control.Form?>
|
||||||
|
<?import tornadofx.control.Fieldset?>
|
||||||
|
<?import tornadofx.control.Field?>
|
||||||
|
<?import com.sparrowwallet.sparrow.control.CoinLabel?>
|
||||||
|
<?import com.sparrowwallet.sparrow.control.CopyableLabel?>
|
||||||
|
|
||||||
<BorderPane stylesheets="@transactions.css, @wallet.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.TransactionsController">
|
<BorderPane stylesheets="@transactions.css, @wallet.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.TransactionsController">
|
||||||
<padding>
|
|
||||||
<Insets left="25.0" right="25.0" top="15.0" bottom="25.0" />
|
|
||||||
</padding>
|
|
||||||
<top>
|
|
||||||
<Label styleClass="transactions-treetable-label" text="Transactions" /> <!-- onMouseClicked="#advanceBlock" -->
|
|
||||||
</top>
|
|
||||||
<center>
|
<center>
|
||||||
<TransactionsTreeTable fx:id="transactionsTable" />
|
<VBox spacing="10">
|
||||||
|
<padding>
|
||||||
|
<Insets left="25.0" right="25.0" top="25.0" bottom="25.0" />
|
||||||
|
</padding>
|
||||||
|
<GridPane styleClass="send-form" hgap="10.0" vgap="10.0">
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints percentWidth="50" />
|
||||||
|
<ColumnConstraints percentWidth="50" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints />
|
||||||
|
</rowConstraints>
|
||||||
|
<Form GridPane.columnIndex="0" GridPane.rowIndex="0">
|
||||||
|
<Fieldset inputGrow="SOMETIMES" text="Transactions">
|
||||||
|
<Field text="Balance:">
|
||||||
|
<CoinLabel fx:id="balance"/>
|
||||||
|
</Field>
|
||||||
|
<Field text="Fiat balance:">
|
||||||
|
<CopyableLabel fx:id="fiatBalance" />
|
||||||
|
</Field>
|
||||||
|
<Field text="Mempool:">
|
||||||
|
<CoinLabel fx:id="mempoolBalance" />
|
||||||
|
</Field>
|
||||||
|
</Fieldset>
|
||||||
|
</Form>
|
||||||
|
<BalanceChart fx:id="balanceChart" animated="false" legendVisible="false" verticalGridLinesVisible="false" GridPane.columnIndex="1" GridPane.rowIndex="0">
|
||||||
|
<xAxis>
|
||||||
|
<NumberAxis side="BOTTOM" forceZeroInRange="false" minorTickVisible="false" />
|
||||||
|
</xAxis>
|
||||||
|
<yAxis>
|
||||||
|
<NumberAxis side="LEFT" />
|
||||||
|
</yAxis>
|
||||||
|
</BalanceChart>
|
||||||
|
</GridPane>
|
||||||
|
<TransactionsTreeTable fx:id="transactionsTable" VBox.vgrow="ALWAYS" />
|
||||||
|
</VBox>
|
||||||
</center>
|
</center>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
|
|
Loading…
Reference in a new issue