mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 23:36:00 -04:00
Add null checks or price and volume
This commit is contained in:
parent
a45f8d7325
commit
3b94eda701
@ -118,7 +118,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
// E.g. Buy offer with market price 400.- leads to a 360.- price.
|
||||
// Sell offer with market price 400.- leads to a 440.- price.
|
||||
private final double marketPriceMargin;
|
||||
|
||||
|
||||
private final long amount;
|
||||
private final long minAmount;
|
||||
private final NodeAddress offererNodeAddress;
|
||||
@ -236,19 +236,27 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
return getPubKeyRing().equals(keyRing.getPubKeyRing());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Fiat getVolumeByAmount(Coin amount) {
|
||||
try {
|
||||
return new ExchangeRate(getPrice()).coinToFiat(amount);
|
||||
} catch (Throwable t) {
|
||||
log.error("getVolumeByAmount failed. Error=" + t.getMessage());
|
||||
return Fiat.valueOf(currencyCode, 0);
|
||||
Fiat price = getPrice();
|
||||
if (price != null && amount != null) {
|
||||
try {
|
||||
return new ExchangeRate(price).coinToFiat(amount);
|
||||
} catch (Throwable t) {
|
||||
log.error("getVolumeByAmount failed. Error=" + t.getMessage());
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Fiat getOfferVolume() {
|
||||
return getVolumeByAmount(getAmount());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Fiat getMinOfferVolume() {
|
||||
return getVolumeByAmount(getMinAmount());
|
||||
}
|
||||
@ -337,6 +345,7 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
return pubKeyRing;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Fiat getPrice() {
|
||||
if (useMarketBasedPrice) {
|
||||
checkNotNull(priceFeed, "priceFeed must not be null");
|
||||
@ -357,14 +366,13 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
|
||||
return Fiat.parseFiat(currencyCode, String.valueOf(targetPrice));
|
||||
} catch (Exception e) {
|
||||
log.error("Exception at getPrice / parseToFiat: " + e.toString() + "\n" +
|
||||
"We use an inaccessible price to avoid null pointers.\n" +
|
||||
"That case should never happen.");
|
||||
return Fiat.valueOf(currencyCode, direction == Direction.BUY ? Long.MIN_VALUE : Long.MAX_VALUE);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.warn("We don't have a market price. We use an inaccessible price to avoid null pointers.\n" +
|
||||
log.warn("We don't have a market price./n" +
|
||||
"That case could only happen if you don't get a price feed.");
|
||||
return Fiat.valueOf(currencyCode, direction == Direction.BUY ? Long.MIN_VALUE : Long.MAX_VALUE);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return Fiat.valueOf(currencyCode, fiatPrice);
|
||||
|
@ -82,6 +82,7 @@ public class ProcessPayDepositRequest extends TradeTask {
|
||||
checkArgument(takersTradePrice > 0);
|
||||
Fiat tradePriceAsFiat = Fiat.valueOf(trade.getOffer().getCurrencyCode(), takersTradePrice);
|
||||
Fiat offerPriceAsFiat = trade.getOffer().getPrice();
|
||||
checkArgument(offerPriceAsFiat != null, "offerPriceAsFiat must not be null");
|
||||
double factor = (double) takersTradePrice / (double) offerPriceAsFiat.value;
|
||||
// We allow max. 2 % difference between own offer price calculation and takers calculation.
|
||||
// Market price might be different at offerers and takers side so we need a bit of tolerance.
|
||||
@ -95,8 +96,8 @@ public class ProcessPayDepositRequest extends TradeTask {
|
||||
failed(msg);
|
||||
}
|
||||
trade.setTradePrice(takersTradePrice);
|
||||
|
||||
|
||||
|
||||
|
||||
checkArgument(payDepositRequest.tradeAmount > 0);
|
||||
trade.setTradeAmount(Coin.valueOf(payDepositRequest.tradeAmount));
|
||||
|
||||
|
@ -47,6 +47,7 @@ import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.StringConverter;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
|
||||
@ -184,9 +185,13 @@ public class MarketsChartsView extends ActivatableViewAndModel<VBox, MarketsChar
|
||||
@Override
|
||||
public void updateItem(final Offer offer, boolean empty) {
|
||||
super.updateItem(offer, empty);
|
||||
if (offer != null && !empty)
|
||||
setText(formatter.formatFiat(offer.getPrice()));
|
||||
else
|
||||
if (offer != null && !empty) {
|
||||
Fiat offerPrice = offer.getPrice();
|
||||
if (offerPrice != null)
|
||||
setText(formatter.formatFiat(offerPrice));
|
||||
else
|
||||
setText("");
|
||||
} else
|
||||
setText("");
|
||||
}
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -90,8 +91,8 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||
.filter(e -> e.getCurrencyCode().equals(tradeCurrency.get().getCode())
|
||||
&& e.getDirection().equals(Offer.Direction.BUY))
|
||||
.sorted((o1, o2) -> {
|
||||
long a = o1.getPrice().value;
|
||||
long b = o2.getPrice().value;
|
||||
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
||||
long b = o2.getPrice() != null ? o2.getPrice().value : 0;
|
||||
if (a != b)
|
||||
return a < b ? 1 : -1;
|
||||
return 0;
|
||||
@ -105,8 +106,8 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||
.filter(e -> e.getCurrencyCode().equals(tradeCurrency.get().getCode())
|
||||
&& e.getDirection().equals(Offer.Direction.SELL))
|
||||
.sorted((o1, o2) -> {
|
||||
long a = o1.getPrice().value;
|
||||
long b = o2.getPrice().value;
|
||||
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
||||
long b = o2.getPrice() != null ? o2.getPrice().value : 0;
|
||||
if (a != b)
|
||||
return a > b ? 1 : -1;
|
||||
return 0;
|
||||
@ -120,13 +121,16 @@ class MarketsChartsViewModel extends ActivatableViewModel {
|
||||
data.clear();
|
||||
double accumulatedAmount = 0;
|
||||
for (Offer offer : sortedList) {
|
||||
double price = (double) offer.getPrice().value / LongMath.pow(10, offer.getPrice().smallestUnitExponent());
|
||||
double amount = (double) offer.getAmount().value / LongMath.pow(10, offer.getAmount().smallestUnitExponent());
|
||||
accumulatedAmount += amount;
|
||||
if (direction.equals(Offer.Direction.BUY))
|
||||
data.add(0, new XYChart.Data(price, accumulatedAmount));
|
||||
else
|
||||
data.add(new XYChart.Data(price, accumulatedAmount));
|
||||
Fiat priceAsFiat = offer.getPrice();
|
||||
if (priceAsFiat != null) {
|
||||
double price = (double) priceAsFiat.value / LongMath.pow(10, priceAsFiat.smallestUnitExponent());
|
||||
double amount = (double) offer.getAmount().value / LongMath.pow(10, offer.getAmount().smallestUnitExponent());
|
||||
accumulatedAmount += amount;
|
||||
if (direction.equals(Offer.Direction.BUY))
|
||||
data.add(0, new XYChart.Data(price, accumulatedAmount));
|
||||
else
|
||||
data.add(new XYChart.Data(price, accumulatedAmount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,29 +82,30 @@ class MarketsStatisticViewModel extends ActivatableViewModel {
|
||||
.stream()
|
||||
.filter(e -> e.getDirection().equals(Offer.Direction.BUY))
|
||||
.sorted((o1, o2) -> {
|
||||
long a = o1.getPrice().value;
|
||||
long b = o2.getPrice().value;
|
||||
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
||||
long b = o2.getPrice() != null ? o2.getPrice().value : 0;
|
||||
if (a != b)
|
||||
return a < b ? 1 : -1;
|
||||
return 0;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
Fiat bestBuyOfferPrice = buyOffers.isEmpty() ? null : buyOffers.get(0).getPrice();
|
||||
|
||||
List<Offer> sellOffers = offers
|
||||
.stream()
|
||||
.filter(e -> e.getDirection().equals(Offer.Direction.SELL))
|
||||
.sorted((o1, o2) -> {
|
||||
long a = o1.getPrice().value;
|
||||
long b = o2.getPrice().value;
|
||||
long a = o1.getPrice() != null ? o1.getPrice().value : 0;
|
||||
long b = o2.getPrice() != null ? o2.getPrice().value : 0;
|
||||
if (a != b)
|
||||
return a > b ? 1 : -1;
|
||||
return 0;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
Fiat bestSellOfferPrice = sellOffers.isEmpty() ? null : sellOffers.get(0).getPrice();
|
||||
|
||||
Fiat spread = null;
|
||||
if (bestBuyOfferPrice != null && bestSellOfferPrice != null)
|
||||
Fiat bestSellOfferPrice = sellOffers.isEmpty() ? null : sellOffers.get(0).getPrice();
|
||||
Fiat bestBuyOfferPrice = buyOffers.isEmpty() ? null : buyOffers.get(0).getPrice();
|
||||
if (bestBuyOfferPrice != null && bestSellOfferPrice != null)
|
||||
spread = bestSellOfferPrice.subtract(bestBuyOfferPrice);
|
||||
|
||||
Coin totalAmount = Coin.valueOf(offers.stream().mapToLong(offer -> offer.getAmount().getValue()).sum());
|
||||
|
@ -51,6 +51,7 @@ import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.StringConverter;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -164,9 +165,17 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
placeholder.setWrapText(true);
|
||||
tableView.setPlaceholder(placeholder);
|
||||
|
||||
priceColumn.setComparator((o1, o2) -> o1.getOffer().getPrice().compareTo(o2.getOffer().getPrice()));
|
||||
priceColumn.setComparator((o1, o2) -> {
|
||||
Fiat price1 = o1.getOffer().getPrice();
|
||||
Fiat price2 = o2.getOffer().getPrice();
|
||||
return price1 != null && price2 != null ? price1.compareTo(price2) : 0;
|
||||
});
|
||||
amountColumn.setComparator((o1, o2) -> o1.getOffer().getAmount().compareTo(o2.getOffer().getAmount()));
|
||||
volumeColumn.setComparator((o1, o2) -> o1.getOffer().getOfferVolume().compareTo(o2.getOffer().getOfferVolume()));
|
||||
volumeColumn.setComparator((o1, o2) -> {
|
||||
Fiat offerVolume1 = o1.getOffer().getOfferVolume();
|
||||
Fiat offerVolume2 = o2.getOffer().getOfferVolume();
|
||||
return offerVolume1 != null && offerVolume2 != null ? offerVolume1.compareTo(offerVolume2) : 0;
|
||||
});
|
||||
paymentMethodColumn.setComparator((o1, o2) -> o1.getOffer().getPaymentMethod().compareTo(o2.getOffer().getPaymentMethod()));
|
||||
avatarColumn.setComparator((o1, o2) -> o1.getOffer().getOwnerNodeAddress().hostName.compareTo(o2.getOffer().getOwnerNodeAddress().hostName));
|
||||
|
||||
|
@ -262,14 +262,18 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
|
||||
Offer offer = item.getOffer();
|
||||
Fiat price = offer.getPrice();
|
||||
String postFix = "";
|
||||
if (offer.getUseMarketBasedPrice()) {
|
||||
postFix = " (" + formatter.formatToPercentWithSymbol(offer.getMarketPriceMargin()) + ")";
|
||||
if (price != null) {
|
||||
String postFix = "";
|
||||
if (offer.getUseMarketBasedPrice()) {
|
||||
postFix = " (" + formatter.formatToPercentWithSymbol(offer.getMarketPriceMargin()) + ")";
|
||||
}
|
||||
if (showAllTradeCurrenciesProperty.get())
|
||||
return formatter.formatPriceWithCode(price) + postFix;
|
||||
else
|
||||
return formatter.formatFiat(price) + postFix;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
if (showAllTradeCurrenciesProperty.get())
|
||||
return formatter.formatPriceWithCode(price) + postFix;
|
||||
else
|
||||
return formatter.formatFiat(price) + postFix;
|
||||
}
|
||||
|
||||
String getVolume(OfferBookListItem item) {
|
||||
|
@ -160,7 +160,8 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||
void initWithData(Offer offer) {
|
||||
this.offer = offer;
|
||||
tradePrice = offer.getPrice();
|
||||
|
||||
// we check at the view class and close in case we dont get a price
|
||||
checkNotNull(tradePrice, "tradePrice must not be null");
|
||||
addressEntry = walletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.OFFER_FUNDING);
|
||||
checkNotNull(addressEntry, "addressEntry must not be null");
|
||||
|
||||
|
@ -194,45 +194,51 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void initWithData(Offer offer) {
|
||||
model.initWithData(offer);
|
||||
if (offer.getPrice() != null) {
|
||||
model.initWithData(offer);
|
||||
priceAsPercentageInputBox.setVisible(offer.getUseMarketBasedPrice());
|
||||
|
||||
priceAsPercentageInputBox.setVisible(offer.getUseMarketBasedPrice());
|
||||
if (model.getOffer().getDirection() == Offer.Direction.SELL) {
|
||||
imageView.setId("image-buy-large");
|
||||
directionLabel.setId("direction-icon-label-buy");
|
||||
|
||||
if (model.getOffer().getDirection() == Offer.Direction.SELL) {
|
||||
imageView.setId("image-buy-large");
|
||||
directionLabel.setId("direction-icon-label-buy");
|
||||
takeOfferButton.setId("buy-button-big");
|
||||
takeOfferButton.setText("Review offer for buying bitcoin");
|
||||
nextButton.setId("buy-button");
|
||||
} else {
|
||||
imageView.setId("image-sell-large");
|
||||
directionLabel.setId("direction-icon-label-sell");
|
||||
|
||||
takeOfferButton.setId("buy-button-big");
|
||||
takeOfferButton.setText("Review offer for buying bitcoin");
|
||||
nextButton.setId("buy-button");
|
||||
takeOfferButton.setId("sell-button-big");
|
||||
nextButton.setId("sell-button");
|
||||
takeOfferButton.setText("Review offer for selling bitcoin");
|
||||
}
|
||||
|
||||
boolean showComboBox = model.getPossiblePaymentAccounts().size() > 1;
|
||||
paymentAccountsLabel.setVisible(showComboBox);
|
||||
paymentAccountsLabel.setManaged(showComboBox);
|
||||
paymentAccountsComboBox.setVisible(showComboBox);
|
||||
paymentAccountsComboBox.setManaged(showComboBox);
|
||||
paymentMethodTextField.setVisible(!showComboBox);
|
||||
paymentMethodTextField.setManaged(!showComboBox);
|
||||
paymentMethodLabel.setVisible(!showComboBox);
|
||||
paymentMethodLabel.setManaged(!showComboBox);
|
||||
if (!showComboBox)
|
||||
paymentMethodTextField.setText(BSResources.get(model.getPaymentMethod().getId()));
|
||||
currencyTextField.setText(model.dataModel.getCurrencyNameAndCode());
|
||||
directionLabel.setText(model.getDirectionLabel());
|
||||
amountDescriptionLabel.setText(model.getAmountDescription());
|
||||
amountRangeTextField.setText(model.getAmountRange());
|
||||
priceTextField.setText(model.getPrice());
|
||||
priceAsPercentageTextField.setText(model.marketPriceMargin);
|
||||
addressTextField.setPaymentLabel(model.getPaymentLabel());
|
||||
addressTextField.setAddress(model.dataModel.getAddressEntry().getAddressString());
|
||||
} else {
|
||||
imageView.setId("image-sell-large");
|
||||
directionLabel.setId("direction-icon-label-sell");
|
||||
|
||||
takeOfferButton.setId("sell-button-big");
|
||||
nextButton.setId("sell-button");
|
||||
takeOfferButton.setText("Review offer for selling bitcoin");
|
||||
new Popup().warning("You cannot take that offer as it uses a percentage price based on the " +
|
||||
"market price but there is no price feed available.")
|
||||
.onClose(this::close)
|
||||
.show();
|
||||
}
|
||||
|
||||
boolean showComboBox = model.getPossiblePaymentAccounts().size() > 1;
|
||||
paymentAccountsLabel.setVisible(showComboBox);
|
||||
paymentAccountsLabel.setManaged(showComboBox);
|
||||
paymentAccountsComboBox.setVisible(showComboBox);
|
||||
paymentAccountsComboBox.setManaged(showComboBox);
|
||||
paymentMethodTextField.setVisible(!showComboBox);
|
||||
paymentMethodTextField.setManaged(!showComboBox);
|
||||
paymentMethodLabel.setVisible(!showComboBox);
|
||||
paymentMethodLabel.setManaged(!showComboBox);
|
||||
if (!showComboBox)
|
||||
paymentMethodTextField.setText(BSResources.get(model.getPaymentMethod().getId()));
|
||||
currencyTextField.setText(model.dataModel.getCurrencyNameAndCode());
|
||||
directionLabel.setText(model.getDirectionLabel());
|
||||
amountDescriptionLabel.setText(model.getAmountDescription());
|
||||
amountRangeTextField.setText(model.getAmountRange());
|
||||
priceTextField.setText(model.getPrice());
|
||||
priceAsPercentageTextField.setText(model.marketPriceMargin);
|
||||
addressTextField.setPaymentLabel(model.getPaymentLabel());
|
||||
addressTextField.setAddress(model.dataModel.getAddressEntry().getAddressString());
|
||||
}
|
||||
|
||||
public void setCloseHandler(OfferView.CloseHandler closeHandler) {
|
||||
|
@ -175,11 +175,17 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
||||
addLabelTextField(gridPane, ++rowIndex, CurrencyUtil.getNameByCode(offer.getCurrencyCode()) + " amount" + fiatDirectionInfo, formatter.formatFiatWithCode(offer.getVolumeByAmount(offer.getAmount())));
|
||||
}
|
||||
|
||||
if (takeOfferHandlerOptional.isPresent())
|
||||
if (takeOfferHandlerOptional.isPresent()) {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(tradePrice) + " " + offer.getCurrencyCode() + "/" + "BTC");
|
||||
else
|
||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC");
|
||||
|
||||
} else {
|
||||
Fiat price = offer.getPrice();
|
||||
if (offer.getUseMarketBasedPrice()) {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatPriceWithCode(price) +
|
||||
" (" + formatter.formatToPercentWithSymbol(offer.getMarketPriceMargin()) + ")");
|
||||
} else {
|
||||
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatPriceWithCode(price));
|
||||
}
|
||||
}
|
||||
if (offer.isMyOffer(keyRing) && user.getPaymentAccount(offer.getOffererPaymentAccountId()) != null)
|
||||
addLabelTextField(gridPane, ++rowIndex, "Payment account:", user.getPaymentAccount(offer.getOffererPaymentAccountId()).getAccountName());
|
||||
else
|
||||
|
@ -85,8 +85,11 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
||||
Tradable tradable = o1.getTradable();
|
||||
if (tradable instanceof Trade)
|
||||
return ((Trade) o1.getTradable()).getTradePrice().compareTo(((Trade) o2.getTradable()).getTradePrice());
|
||||
else
|
||||
return o1.getTradable().getOffer().getPrice().compareTo(o2.getTradable().getOffer().getPrice());
|
||||
else {
|
||||
Fiat price1 = o1.getTradable().getOffer().getPrice();
|
||||
Fiat price2 = o2.getTradable().getOffer().getPrice();
|
||||
return price1 != null && price2 != null ? price1.compareTo(price2) : 0;
|
||||
}
|
||||
});
|
||||
volumeColumn.setComparator((o1, o2) -> {
|
||||
if (o1.getTradable() instanceof Trade && o2.getTradable() instanceof Trade) {
|
||||
|
@ -34,6 +34,7 @@ import javafx.scene.control.*;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.util.Callback;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -72,8 +73,16 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
||||
offerIdColumn.setComparator((o1, o2) -> o1.getOffer().getId().compareTo(o2.getOffer().getId()));
|
||||
directionColumn.setComparator((o1, o2) -> o1.getOffer().getDirection().compareTo(o2.getOffer().getDirection()));
|
||||
amountColumn.setComparator((o1, o2) -> o1.getOffer().getAmount().compareTo(o2.getOffer().getAmount()));
|
||||
priceColumn.setComparator((o1, o2) -> o1.getOffer().getPrice().compareTo(o2.getOffer().getPrice()));
|
||||
volumeColumn.setComparator((o1, o2) -> o1.getOffer().getOfferVolume().compareTo(o2.getOffer().getOfferVolume()));
|
||||
priceColumn.setComparator((o1, o2) -> {
|
||||
Fiat price1 = o1.getOffer().getPrice();
|
||||
Fiat price2 = o2.getOffer().getPrice();
|
||||
return price1 != null && price2 != null ? price1.compareTo(price2) : 0;
|
||||
});
|
||||
volumeColumn.setComparator((o1, o2) -> {
|
||||
Fiat offerVolume1 = o1.getOffer().getOfferVolume();
|
||||
Fiat offerVolume2 = o2.getOffer().getOfferVolume();
|
||||
return offerVolume1 != null && offerVolume2 != null ? offerVolume1.compareTo(offerVolume2) : 0;
|
||||
});
|
||||
dateColumn.setComparator((o1, o2) -> o1.getOffer().getDate().compareTo(o2.getOffer().getDate()));
|
||||
|
||||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
|
Loading…
x
Reference in New Issue
Block a user