diff --git a/gui/src/main/java/io/bitsquare/gui/Navigation.java b/gui/src/main/java/io/bitsquare/gui/Navigation.java index 82fc6d34f8..3ffd768d86 100644 --- a/gui/src/main/java/io/bitsquare/gui/Navigation.java +++ b/gui/src/main/java/io/bitsquare/gui/Navigation.java @@ -22,7 +22,7 @@ import io.bitsquare.app.Version; import io.bitsquare.gui.common.view.View; import io.bitsquare.gui.common.view.ViewPath; import io.bitsquare.gui.main.MainView; -import io.bitsquare.gui.main.market.MarketView; +import io.bitsquare.gui.main.markets.MarketView; import io.bitsquare.storage.Storage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/gui/src/main/java/io/bitsquare/gui/main/MainView.java b/gui/src/main/java/io/bitsquare/gui/main/MainView.java index 001551c0da..1cc9028b2d 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/MainView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/MainView.java @@ -26,7 +26,7 @@ import io.bitsquare.gui.components.SystemNotification; import io.bitsquare.gui.main.account.AccountView; import io.bitsquare.gui.main.disputes.DisputesView; import io.bitsquare.gui.main.funds.FundsView; -import io.bitsquare.gui.main.market.MarketView; +import io.bitsquare.gui.main.markets.MarketView; import io.bitsquare.gui.main.offer.BuyOfferView; import io.bitsquare.gui.main.offer.SellOfferView; import io.bitsquare.gui.main.portfolio.PortfolioView; diff --git a/gui/src/main/java/io/bitsquare/gui/main/market/MarketView.fxml b/gui/src/main/java/io/bitsquare/gui/main/markets/MarketView.fxml similarity index 88% rename from gui/src/main/java/io/bitsquare/gui/main/market/MarketView.fxml rename to gui/src/main/java/io/bitsquare/gui/main/markets/MarketView.fxml index 604305a7fc..34e8a03b46 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/market/MarketView.fxml +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/MarketView.fxml @@ -20,9 +20,11 @@ - - + + + diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/MarketView.java b/gui/src/main/java/io/bitsquare/gui/main/markets/MarketView.java new file mode 100644 index 0000000000..fa69da8a03 --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/MarketView.java @@ -0,0 +1,92 @@ +/* + * 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 . + */ + +package io.bitsquare.gui.main.markets; + +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.markets.charts.MarketsChartsView; +import io.bitsquare.gui.main.markets.statistics.MarketsStatisticsView; +import javafx.beans.value.ChangeListener; +import javafx.fxml.FXML; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; + +import javax.inject.Inject; + +@FxmlView +public class MarketView extends ActivatableViewAndModel { + @FXML + Tab chartsTab, statisticsTab; + private final ViewLoader viewLoader; + private final Navigation navigation; + private Navigation.Listener navigationListener; + private ChangeListener tabChangeListener; + + @Inject + public MarketView(CachingViewLoader viewLoader, Navigation navigation) { + this.viewLoader = viewLoader; + this.navigation = navigation; + } + + @Override + public void initialize() { + navigationListener = viewPath -> { + if (viewPath.size() == 3 && viewPath.indexOf(MarketView.class) == 1) + loadView(viewPath.tip()); + }; + + tabChangeListener = (ov, oldValue, newValue) -> { + if (newValue == chartsTab) + navigation.navigateTo(MainView.class, MarketView.class, MarketsChartsView.class); + else if (newValue == statisticsTab) + navigation.navigateTo(MainView.class, MarketView.class, MarketsStatisticsView.class); + }; + } + + @Override + protected void activate() { + root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener); + navigation.addListener(navigationListener); + + if (root.getSelectionModel().getSelectedItem() == chartsTab) + navigation.navigateTo(MainView.class, MarketView.class, MarketsChartsView.class); + else + navigation.navigateTo(MainView.class, MarketView.class, MarketsStatisticsView.class); + } + + @Override + protected void deactivate() { + root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener); + navigation.removeListener(navigationListener); + } + + private void loadView(Class viewClass) { + final Tab tab; + View view = viewLoader.load(viewClass); + + if (view instanceof MarketsChartsView) tab = chartsTab; + else if (view instanceof MarketsStatisticsView) tab = statisticsTab; + else throw new IllegalArgumentException("Navigation to " + viewClass + " is not supported"); + + tab.setContent(view.getRoot()); + root.getSelectionModel().select(tab); + } + +} diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.fxml b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.fxml new file mode 100644 index 0000000000..459bb21edf --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/gui/src/main/java/io/bitsquare/gui/main/market/MarketView.java b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java similarity index 64% rename from gui/src/main/java/io/bitsquare/gui/main/market/MarketView.java rename to gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java index ee6bae15b9..7863e7edb3 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/market/MarketView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsView.java @@ -15,21 +15,22 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.gui.main.market; +package io.bitsquare.gui.main.markets.charts; import io.bitsquare.common.UserThread; import io.bitsquare.common.util.Tuple2; import io.bitsquare.gui.common.view.ActivatableViewAndModel; import io.bitsquare.gui.common.view.FxmlView; +import io.bitsquare.gui.main.markets.statistics.MarketStatisticItem; import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem; import io.bitsquare.gui.util.BSFormatter; +import io.bitsquare.locale.CurrencyUtil; import io.bitsquare.locale.TradeCurrency; import io.bitsquare.trade.offer.Offer; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.ListChangeListener; -import javafx.fxml.FXML; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.chart.AreaChart; @@ -46,9 +47,7 @@ import org.fxmisc.easybind.Subscription; import javax.inject.Inject; @FxmlView -public class MarketView extends ActivatableViewAndModel { - @FXML - Tab tab; +public class MarketsChartsView extends ActivatableViewAndModel { private NumberAxis xAxis, yAxis; XYChart.Series seriesBuy, seriesSell; @@ -63,12 +62,13 @@ public class MarketView extends ActivatableViewAndModel getCurrencyColumn() { + TableColumn column = new TableColumn("Currency") { + { + setMinWidth(100); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) + setText(CurrencyUtil.getNameByCode(item.currencyCode)); + else + setText(""); + } + }; + } + }); + return column; + } + + private TableColumn getNumberOfOffersColumn() { + TableColumn column = new TableColumn("Total offers") { + { + setMinWidth(100); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) + setText(String.valueOf(item.numberOfOffers)); + else + setText(""); + } + }; + } + }); + return column; + } + + private TableColumn getTotalAmountColumn() { + TableColumn column = new TableColumn("Total amount (BTC)") { + { + setMinWidth(130); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) + setText(formatter.formatCoin(item.totalAmount)); + else + setText(""); + } + }; + } + }); + return column; + } + + private TableColumn getSpreadColumn() { + TableColumn column = new TableColumn("Spread") { + { + setMinWidth(130); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty && item.spread != null) + setText(formatter.formatFiatWithCode(item.spread)); + else + setText(""); + } + }; + } + }); + return column; + } + + } diff --git a/gui/src/main/java/io/bitsquare/gui/main/market/MarketViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java similarity index 96% rename from gui/src/main/java/io/bitsquare/gui/main/market/MarketViewModel.java rename to gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java index 41ff6a4581..2a9a144d2c 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/market/MarketViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/charts/MarketsChartsViewModel.java @@ -15,7 +15,7 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.gui.main.market; +package io.bitsquare.gui.main.markets.charts; import com.google.common.math.LongMath; import com.google.inject.Inject; @@ -37,7 +37,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -class MarketViewModel extends ActivatableViewModel { +class MarketsChartsViewModel extends ActivatableViewModel { private final OfferBook offerBook; private final Preferences preferences; @@ -56,7 +56,7 @@ class MarketViewModel extends ActivatableViewModel { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public MarketViewModel(OfferBook offerBook, Preferences preferences) { + public MarketsChartsViewModel(OfferBook offerBook, Preferences preferences) { this.offerBook = offerBook; this.preferences = preferences; @@ -77,7 +77,7 @@ class MarketViewModel extends ActivatableViewModel { private void updateChartData(ObservableList offerBookListItems) { List offerList = offerBookListItems.stream() - .map(e -> e.getOffer()) + .map(OfferBookListItem::getOffer) .collect(Collectors.toList()); buyOfferList.clear(); diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketStatisticItem.java b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketStatisticItem.java new file mode 100644 index 0000000000..eed312b4f7 --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketStatisticItem.java @@ -0,0 +1,24 @@ +package io.bitsquare.gui.main.markets.statistics; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.utils.Fiat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nullable; + +public class MarketStatisticItem { + private static final Logger log = LoggerFactory.getLogger(MarketStatisticItem.class); + public final String currencyCode; + public final int numberOfOffers; + @Nullable + public final Fiat spread; + public final Coin totalAmount; + + public MarketStatisticItem(String currencyCode, int numberOfOffers, @Nullable Fiat spread, Coin totalAmount) { + this.currencyCode = currencyCode; + this.numberOfOffers = numberOfOffers; + this.spread = spread; + this.totalAmount = totalAmount; + } +} diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticViewModel.java new file mode 100644 index 0000000000..45bd32461b --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticViewModel.java @@ -0,0 +1,117 @@ +/* + * 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 . + */ + +package io.bitsquare.gui.main.markets.statistics; + +import com.google.inject.Inject; +import io.bitsquare.gui.common.model.ActivatableViewModel; +import io.bitsquare.gui.main.offer.offerbook.OfferBook; +import io.bitsquare.gui.main.offer.offerbook.OfferBookListItem; +import io.bitsquare.trade.offer.Offer; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import org.bitcoinj.core.Coin; +import org.bitcoinj.utils.Fiat; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +class MarketsStatisticViewModel extends ActivatableViewModel { + + private final OfferBook offerBook; + private final ObservableList offerBookListItems; + private final ListChangeListener listChangeListener; + final ObservableList marketStatisticItems = FXCollections.observableArrayList(); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public MarketsStatisticViewModel(OfferBook offerBook) { + this.offerBook = offerBook; + + offerBookListItems = offerBook.getOfferBookListItems(); + listChangeListener = c -> update(offerBookListItems); + } + + @Override + protected void activate() { + offerBookListItems.addListener(listChangeListener); + offerBook.fillOfferBookListItems(); + } + + @Override + protected void deactivate() { + offerBookListItems.removeListener(listChangeListener); + } + + private void update(ObservableList offerBookListItems) { + Map> offersByCurrencyMap = new HashMap<>(); + for (OfferBookListItem offerBookListItem : offerBookListItems) { + Offer offer = offerBookListItem.getOffer(); + String currencyCode = offer.getCurrencyCode(); + if (!offersByCurrencyMap.containsKey(currencyCode)) + offersByCurrencyMap.put(currencyCode, new ArrayList<>()); + offersByCurrencyMap.get(currencyCode).add(offer); + } + marketStatisticItems.clear(); + long totalAmount = 0; + for (String currencyCode : offersByCurrencyMap.keySet()) { + List offers = offersByCurrencyMap.get(currencyCode); + List buyOffers = offers + .stream() + .filter(e -> e.getDirection().equals(Offer.Direction.BUY)) + .sorted((o1, o2) -> { + long a = o1.getPrice().value; + long b = o2.getPrice().value; + if (a != b) + return a < b ? 1 : -1; + return 0; + }) + .collect(Collectors.toList()); + Fiat bestBuyOfferPrice = buyOffers.isEmpty() ? null : buyOffers.get(0).getPrice(); + List sellOffers = offers + .stream() + .filter(e -> e.getDirection().equals(Offer.Direction.SELL)) + .sorted((o1, o2) -> { + long a = o1.getPrice().value; + long b = o2.getPrice().value; + 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) { + spread = bestSellOfferPrice.subtract(bestBuyOfferPrice); + } + + for (Offer offer : offers) { + totalAmount += offer.getAmount().getValue(); + } + marketStatisticItems.add(new MarketStatisticItem(currencyCode, offers.size(), spread, Coin.valueOf(totalAmount))); + } + } +} diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticsView.fxml b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticsView.fxml new file mode 100644 index 0000000000..6ffc5e339a --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticsView.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticsView.java b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticsView.java new file mode 100644 index 0000000000..8c89d640c7 --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/statistics/MarketsStatisticsView.java @@ -0,0 +1,202 @@ +/* + * 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 . + */ + +package io.bitsquare.gui.main.markets.statistics; + +import io.bitsquare.gui.common.view.ActivatableViewAndModel; +import io.bitsquare.gui.common.view.FxmlView; +import io.bitsquare.gui.components.TableGroupHeadline; +import io.bitsquare.gui.util.BSFormatter; +import io.bitsquare.locale.CurrencyUtil; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.geometry.Insets; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; +import javafx.util.Callback; + +import javax.inject.Inject; + +@FxmlView +public class MarketsStatisticsView extends ActivatableViewAndModel { + private BSFormatter formatter; + private int gridRow = 0; + private TableView statisticsTableView; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public MarketsStatisticsView(MarketsStatisticViewModel model, BSFormatter formatter) { + super(model); + this.formatter = formatter; + } + + @Override + public void initialize() { + TableGroupHeadline header = new TableGroupHeadline("Statistics"); + GridPane.setRowIndex(header, gridRow); + GridPane.setMargin(header, new Insets(0, -10, -10, -10)); + root.getChildren().add(header); + + statisticsTableView = new TableView<>(); + GridPane.setRowIndex(statisticsTableView, gridRow); + GridPane.setMargin(statisticsTableView, new Insets(20, -10, -10, -10)); + GridPane.setVgrow(statisticsTableView, Priority.ALWAYS); + GridPane.setHgrow(statisticsTableView, Priority.ALWAYS); + root.getChildren().add(statisticsTableView); + statisticsTableView.getColumns().add(getCurrencyColumn()); + statisticsTableView.getColumns().add(getNumberOfOffersColumn()); + statisticsTableView.getColumns().add(getTotalAmountColumn()); + statisticsTableView.getColumns().add(getSpreadColumn()); + statisticsTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + Label placeholder = new Label("Currently there are no offers available"); + placeholder.setWrapText(true); + statisticsTableView.setPlaceholder(placeholder); + } + + @Override + protected void activate() { + statisticsTableView.setItems(model.marketStatisticItems); + } + + @Override + protected void deactivate() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Columns + /////////////////////////////////////////////////////////////////////////////////////////// + + private TableColumn getCurrencyColumn() { + TableColumn column = new TableColumn("Currency") { + { + setMinWidth(100); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) + setText(CurrencyUtil.getNameByCode(item.currencyCode)); + else + setText(""); + } + }; + } + }); + return column; + } + + private TableColumn getNumberOfOffersColumn() { + TableColumn column = new TableColumn("Total offers") { + { + setMinWidth(100); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) + setText(String.valueOf(item.numberOfOffers)); + else + setText(""); + } + }; + } + }); + return column; + } + + private TableColumn getTotalAmountColumn() { + TableColumn column = new TableColumn("Total amount (BTC)") { + { + setMinWidth(130); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) + setText(formatter.formatCoin(item.totalAmount)); + else + setText(""); + } + }; + } + }); + return column; + } + + private TableColumn getSpreadColumn() { + TableColumn column = new TableColumn("Spread") { + { + setMinWidth(130); + } + }; + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory( + new Callback, TableCell>() { + @Override + public TableCell call( + TableColumn column) { + return new TableCell() { + @Override + public void updateItem(final MarketStatisticItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty && item.spread != null) + setText(formatter.formatFiatWithCode(item.spread)); + else + setText(""); + } + }; + } + }); + return column; + } +} diff --git a/gui/src/main/java/io/bitsquare/gui/main/settings/SettingsView.java b/gui/src/main/java/io/bitsquare/gui/main/settings/SettingsView.java index 40af9cf35f..c56874acee 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/settings/SettingsView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/settings/SettingsView.java @@ -32,14 +32,12 @@ import javax.inject.Inject; @FxmlView public class SettingsView extends ActivatableViewAndModel { - - @FXML Tab preferencesTab, networkSettingsTab; - - private Navigation.Listener navigationListener; - private ChangeListener tabChangeListener; - + @FXML + Tab preferencesTab, networkSettingsTab; private final ViewLoader viewLoader; private final Navigation navigation; + private Navigation.Listener navigationListener; + private ChangeListener tabChangeListener; @Inject public SettingsView(CachingViewLoader viewLoader, Navigation navigation) { diff --git a/network/src/main/java/io/bitsquare/p2p/P2PService.java b/network/src/main/java/io/bitsquare/p2p/P2PService.java index 28468eff1a..97ec4f5931 100644 --- a/network/src/main/java/io/bitsquare/p2p/P2PService.java +++ b/network/src/main/java/io/bitsquare/p2p/P2PService.java @@ -341,7 +341,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis connection.setConnectionPriority(ConnectionPriority.DIRECT_MSG); log.info("\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" + - "Received SealedAndSignedMessage and decrypted it.\ndecryptedMsgWithPubKey={}" + "Decrypted SealedAndSignedMessage:\ndecryptedMsgWithPubKey={}" + "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", decryptedMsgWithPubKey); connection.getPeerAddressOptional().ifPresent(peerAddresses -> decryptedMailListeners.stream().forEach( @@ -400,6 +400,9 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis Log.traceCall(); checkArgument(optionalEncryptionService.isPresent(), "EncryptionService not set. Seems that is called on a seed node which must not happen."); try { + log.info("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" + + "Encrypt message:\nmessage={}" + + "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", message); SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage( optionalEncryptionService.get().encryptAndSign(pubKeyRing, message), peerAddress.getAddressPrefixHash()); SettableFuture future = networkNode.sendMessage(peerAddress, sealedAndSignedMessage); @@ -495,6 +498,9 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen."); checkArgument(optionalEncryptionService.isPresent(), "EncryptionService not set. Seems that is called on a seed node which must not happen."); try { + log.info("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" + + "Encrypt message:\nmessage={}" + + "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", message); SealedAndSignedMessage sealedAndSignedMessage = new SealedAndSignedMessage( optionalEncryptionService.get().encryptAndSign(peersPubKeyRing, message), peerAddress.getAddressPrefixHash()); SettableFuture future = networkNode.sendMessage(peerAddress, sealedAndSignedMessage);