Fix missing update in open trades table (part of #239)

This commit is contained in:
Manfred Karrer 2014-11-13 00:28:33 +01:00
parent d657763596
commit 57faf40759
5 changed files with 156 additions and 144 deletions

View File

@ -19,13 +19,20 @@ package io.bitsquare.gui.main.portfolio.pending;
import io.bitsquare.trade.Trade;
import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat;
import java.util.Date;
import javafx.beans.property.ObjectProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* We could remove that wrapper if it is not needed for additional UI only fields.
*/
class PendingTradesListItem {
public class PendingTradesListItem {
private static final Logger log = LoggerFactory.getLogger(PendingTradesListItem.class);
private final Trade trade;
@ -35,16 +42,35 @@ class PendingTradesListItem {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
PendingTradesListItem(Trade trade) {
public PendingTradesListItem(Trade trade) {
this.trade = trade;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
Trade getTrade() {
public Trade getTrade() {
return trade;
}
public ObjectProperty<Coin> tradeAmountProperty() {
return trade.tradeAmountProperty();
}
public ObjectProperty<Fiat> tradeVolumeProperty() {
return trade.tradeVolumeProperty();
}
public Date getDate() {
return trade.getDate();
}
public String getId() {
return trade.getId();
}
public Fiat getPrice() {
return trade.getOffer().getPrice();
}
}

View File

@ -24,8 +24,13 @@ import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.BtcAddressValidator;
import io.bitsquare.locale.BSResources;
import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat;
import com.google.inject.Inject;
import java.util.Date;
import javafx.beans.InvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
@ -174,28 +179,28 @@ public class PendingTradesPM extends PresentationModel<PendingTradesModel> {
}
// columns
String getTradeId(PendingTradesListItem item) {
return item.getTrade().getId();
String formatTradeId(String value) {
return value;
}
String getAmount(PendingTradesListItem item) {
return (item != null) ? formatter.formatCoinWithCode(item.getTrade().getTradeAmount()) : "";
String formatTradeAmount(Coin value) {
return formatter.formatCoinWithCode(value);
}
String getPrice(PendingTradesListItem item) {
return (item != null) ? formatter.formatFiat(item.getTrade().getOffer().getPrice()) : "";
String formatPrice(Fiat value) {
return formatter.formatFiat(value);
}
String getVolume(PendingTradesListItem item) {
return (item != null) ? formatter.formatFiatWithCode(item.getTrade().getTradeVolume()) : "";
String formatTradeVolume(Fiat value) {
return formatter.formatFiatWithCode(value);
}
String getDirectionLabel(PendingTradesListItem item) {
String evaluateDirection(PendingTradesListItem item) {
return (item != null) ? formatter.formatDirection(model.getDirection(item.getTrade().getOffer())) : "";
}
String getDate(PendingTradesListItem item) {
return formatter.formatDateTime(item.getTrade().getDate());
String formatDate(Date value) {
return formatter.formatDateTime(value);
}
// payment

View File

@ -26,6 +26,7 @@
<?import io.bitsquare.gui.components.TxIdTextField?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.portfolio.pending.PendingTradesViewCB"
xmlns:fx="http://javafx.com/fxml">
@ -48,11 +49,31 @@
<Insets top="10.0" left="-10" right="-10" bottom="-15"/>
</GridPane.margin>
<columns>
<TableColumn text="Trade ID" fx:id="tradeIdColumn" minWidth="100" sortable="false"/>
<TableColumn text="Date" fx:id="dateColumn" minWidth="130"/>
<TableColumn text="Trade amount in BTC" fx:id="amountColumn" minWidth="130" sortable="false"/>
<TableColumn text="Price" fx:id="priceColumn" minWidth="100" sortable="false"/>
<TableColumn text="Trade amount in EUR" fx:id="volumeColumn" minWidth="130" sortable="false"/>
<TableColumn text="Trade ID" fx:id="idColumn" minWidth="100" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="id"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Date" fx:id="dateColumn" minWidth="130">
<cellValueFactory>
<PropertyValueFactory property="date"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Trade amount in BTC" fx:id="tradeAmountColumn" minWidth="130" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="tradeAmount"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Price" fx:id="priceColumn" minWidth="100" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="price"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Trade amount in EUR" fx:id="tradeVolumeColumn" minWidth="130" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="tradeVolume"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Trade type" fx:id="directionColumn" minWidth="80" sortable="false"/>
</columns>
</TableView>

View File

@ -31,9 +31,13 @@ import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.locale.BSResources;
import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
@ -45,8 +49,10 @@ import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.scene.layout.*;
import javafx.util.Callback;
import javafx.util.StringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -78,8 +84,13 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
@FXML Button confirmPaymentReceiptButton, paymentsButton, withdrawButton;
@FXML TextFieldWithCopyIcon fiatAmountTextField, holderNameTextField, secondaryIdTextField, primaryIdTextField;
@FXML TableView<PendingTradesListItem> table;
@FXML TableColumn<PendingTradesListItem, PendingTradesListItem> priceColumn, amountColumn, volumeColumn,
directionColumn, dateColumn, tradeIdColumn;
@FXML TableColumn<PendingTradesListItem, Fiat> priceColumn;
@FXML TableColumn<PendingTradesListItem, Fiat> tradeVolumeColumn;
@FXML TableColumn<PendingTradesListItem, PendingTradesListItem> directionColumn;
@FXML TableColumn<PendingTradesListItem, String> idColumn;
@FXML TableColumn<PendingTradesListItem, Date> dateColumn;
@FXML TableColumn<PendingTradesListItem, Coin> tradeAmountColumn;
///////////////////////////////////////////////////////////////////////////////////////////
@ -547,119 +558,79 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
///////////////////////////////////////////////////////////////////////////////////////////
private void setTradeIdColumnCellFactory() {
tradeIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
tradeIdColumn.setCellFactory(
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>,
TableCell<PendingTradesListItem, PendingTradesListItem>>() {
idColumn.setCellFactory(TextFieldTableCell.<PendingTradesListItem, String>forTableColumn(
new StringConverter<String>() {
@Override
public String toString(String value) {
return presentationModel.formatTradeId(value);
}
@Override
public TableCell<PendingTradesListItem, PendingTradesListItem> call
(TableColumn<PendingTradesListItem,
PendingTradesListItem> column) {
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
private Hyperlink hyperlink;
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
hyperlink = new Hyperlink(presentationModel.getTradeId(item));
hyperlink.setId("id-link");
Tooltip.install(hyperlink, new Tooltip(presentationModel.getTradeId(item)));
hyperlink.setOnAction(event -> openOfferDetails(item));
setGraphic(hyperlink);
}
else {
setGraphic(null);
setId(null);
}
}
};
public String fromString(String string) {
return null;
}
});
}));
}
private void setDateColumnCellFactory() {
dateColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
dateColumn.setCellFactory(
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
PendingTradesListItem>>() {
dateColumn.setCellFactory(TextFieldTableCell.<PendingTradesListItem, Date>forTableColumn(
new StringConverter<Date>() {
@Override
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(presentationModel.getDate(item));
else
setText("");
}
};
public String toString(Date value) {
return presentationModel.formatDate(value);
}
});
@Override
public Date fromString(String string) {
return null;
}
}));
}
private void setAmountColumnCellFactory() {
amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
amountColumn.setCellFactory(
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
PendingTradesListItem>>() {
tradeAmountColumn.setCellFactory(TextFieldTableCell.<PendingTradesListItem, Coin>forTableColumn(
new StringConverter<Coin>() {
@Override
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
setText(presentationModel.getAmount(item));
}
};
public String toString(Coin value) {
return presentationModel.formatTradeAmount(value);
}
});
@Override
public Coin fromString(String string) {
return null;
}
}));
}
private void setPriceColumnCellFactory() {
priceColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
priceColumn.setCellFactory(
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
PendingTradesListItem>>() {
priceColumn.setCellFactory(TextFieldTableCell.<PendingTradesListItem, Fiat>forTableColumn(
new StringConverter<Fiat>() {
@Override
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
setText(presentationModel.getPrice(item));
}
};
public String toString(Fiat value) {
return presentationModel.formatPrice(value);
}
});
@Override
public Fiat fromString(String string) {
return null;
}
}));
}
private void setVolumeColumnCellFactory() {
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
volumeColumn.setCellFactory(
new Callback<TableColumn<PendingTradesListItem, PendingTradesListItem>, TableCell<PendingTradesListItem,
PendingTradesListItem>>() {
tradeVolumeColumn.setCellFactory(TextFieldTableCell.<PendingTradesListItem, Fiat>forTableColumn(
new StringConverter<Fiat>() {
@Override
public TableCell<PendingTradesListItem, PendingTradesListItem> call(
TableColumn<PendingTradesListItem, PendingTradesListItem> column) {
return new TableCell<PendingTradesListItem, PendingTradesListItem>() {
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null)
setText(presentationModel.getVolume(item));
else
setText("");
}
};
public String toString(Fiat value) {
return presentationModel.formatTradeVolume(value);
}
});
@Override
public Fiat fromString(String string) {
return null;
}
}));
}
private void setDirectionColumnCellFactory() {
@ -674,12 +645,14 @@ public class PendingTradesViewCB extends CachedViewCB<PendingTradesPM> {
@Override
public void updateItem(final PendingTradesListItem item, boolean empty) {
super.updateItem(item, empty);
setText(presentationModel.getDirectionLabel(item));
if (item != null && !empty)
setText(presentationModel.evaluateDirection(item));
else
setText(null);
}
};
}
});
}
}

View File

@ -27,13 +27,9 @@ import java.io.Serializable;
import java.util.Date;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
//TODO flatten down?
public class Trade implements Serializable {
private static final long serialVersionUID = -8275323072940974077L;
@ -52,28 +48,28 @@ public class Trade implements Serializable {
COMPLETED
}
private final Offer offer;
private final Date date;
private String takeOfferFeeTxID;
private Coin tradeAmount;
private Contract contract;
private String contractAsJson;
private String takerSignature;
private Transaction depositTx;
private Transaction payoutTx;
private Coin tradeAmount;
private State state;
private Throwable fault;
// For changing values we use properties to get binding support in the UI (table)
// When serialized those transient properties are not instantiated, so we instantiate them in the getters at first
// access. Only use the accessor not the private field.
// TODO use ObjectProperties instead of BooleanProperty
transient private BooleanProperty _payoutTxChanged;
transient private BooleanProperty _contractChanged;
transient private ObjectProperty<Transaction> _depositTx;
transient private ObjectProperty<Coin> _tradeAmount;
transient private ObjectProperty<Fiat> _tradeVolume;
transient private ObjectProperty<State> _state;
transient private ObjectProperty<Throwable> _fault;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@ -81,6 +77,7 @@ public class Trade implements Serializable {
public Trade(Offer offer) {
this.offer = offer;
date = new Date();
state = State.OPEN;
}
@ -103,6 +100,8 @@ public class Trade implements Serializable {
public void setTradeAmount(Coin tradeAmount) {
this.tradeAmount = tradeAmount;
tradeAmountProperty().set(tradeAmount);
tradeVolumeProperty().set(getTradeVolume());
}
public Contract getContract() {
@ -115,17 +114,14 @@ public class Trade implements Serializable {
public void setContract(Contract contract) {
this.contract = contract;
contractChangedProperty().set(!contractChangedProperty().get());
}
public void setDepositTx(Transaction tx) {
this.depositTx = tx;
depositTxProperty().set(tx);
}
public void setPayoutTx(Transaction tx) {
this.payoutTx = tx;
payoutTxChangedProperty().set(!payoutTxChangedProperty().get());
}
public void setState(State state) {
@ -192,25 +188,18 @@ public class Trade implements Serializable {
}
// When serialized those transient properties are not instantiated, so we need to instantiate them at first access
public ObjectProperty<Transaction> depositTxProperty() {
if (_depositTx == null)
_depositTx = new SimpleObjectProperty<>(depositTx);
public ObjectProperty<Coin> tradeAmountProperty() {
if (_tradeAmount == null)
_tradeAmount = new SimpleObjectProperty<>();
return _depositTx;
return _tradeAmount;
}
public BooleanProperty contractChangedProperty() {
if (_contractChanged == null)
_contractChanged = new SimpleBooleanProperty();
public ObjectProperty<Fiat> tradeVolumeProperty() {
if (_tradeVolume == null)
_tradeVolume = new SimpleObjectProperty<>();
return _contractChanged;
}
public BooleanProperty payoutTxChangedProperty() {
if (_payoutTxChanged == null)
_payoutTxChanged = new SimpleBooleanProperty();
return _payoutTxChanged;
return _tradeVolume;
}
public ObjectProperty<State> stateProperty() {
@ -225,6 +214,4 @@ public class Trade implements Serializable {
_fault = new SimpleObjectProperty<>(fault);
return _fault;
}
}