public void onDataRequest(Message message, final Connection connection) {
    Log.traceCall(message.toString() + " / connection=" + connection);

    checkArgument(timeoutTimer == null, "requestData must not be called twice.");
    timeoutTimer =
        UserThread.runAfter(
            () -> {
              log.info("timeoutTimer called");
              peerManager.shutDownConnection(connection);
              shutDown();
              listener.onFault("A timeout occurred");
            },
            10,
            TimeUnit.SECONDS);

    DataRequest dataRequest = (DataRequest) message;
    DataResponse dataResponse =
        new DataResponse(new HashSet<>(dataStorage.getMap().values()), dataRequest.getNonce());
    SettableFuture<Connection> future = networkNode.sendMessage(connection, dataResponse);
    Futures.addCallback(
        future,
        new FutureCallback<Connection>() {
          @Override
          public void onSuccess(Connection connection) {
            log.trace(
                "Send DataResponse to {} succeeded. dataResponse={}",
                connection.getPeersNodeAddressOptional(),
                dataResponse);
            shutDown();
            listener.onComplete();
          }

          @Override
          public void onFailure(@NotNull Throwable throwable) {
            String errorMessage =
                "Sending dataRequest to "
                    + connection
                    + " failed. That is expected if the peer is offline. dataRequest="
                    + dataRequest
                    + "."
                    + "Exception: "
                    + throwable.getMessage();
            log.info(errorMessage);

            peerManager.shutDownConnection(connection);
            shutDown();
            listener.onFault(errorMessage);
          }
        });
  }
  public void requestData(NodeAddress nodeAddress) {
    Log.traceCall("nodeAddress=" + nodeAddress);
    checkArgument(timeoutTimer == null, "requestData must not be called twice.");

    timeoutTimer =
        UserThread.runAfter(
            () -> {
              log.info("timeoutTimer called");
              peerManager.shutDownConnection(nodeAddress);
              shutDown();
              listener.onFault("A timeout occurred");
            },
            10,
            TimeUnit.SECONDS);

    Message dataRequest;
    if (networkNode.getNodeAddress() == null) dataRequest = new PreliminaryDataRequest(nonce);
    else dataRequest = new UpdateDataRequest(networkNode.getNodeAddress(), nonce);

    log.info("We send a {} to peer {}. ", dataRequest.getClass().getSimpleName(), nodeAddress);

    SettableFuture<Connection> future = networkNode.sendMessage(nodeAddress, dataRequest);
    Futures.addCallback(
        future,
        new FutureCallback<Connection>() {
          @Override
          public void onSuccess(@Nullable Connection connection) {
            log.trace("Send " + dataRequest + " to " + nodeAddress + " succeeded.");
          }

          @Override
          public void onFailure(@NotNull Throwable throwable) {
            String errorMessage =
                "Sending dataRequest to "
                    + nodeAddress
                    + " failed. That is expected if the peer is offline. dataRequest="
                    + dataRequest
                    + "."
                    + "Exception: "
                    + throwable.getMessage();
            log.info(errorMessage);

            peerManager.shutDownConnection(nodeAddress);
            shutDown();
            listener.onFault(errorMessage);
          }
        });
  }
 private void doWithdrawRequest(String toAddress, KeyParameter aesKey) {
   if (toAddress != null && toAddress.length() > 0) {
     tradeManager.onWithdrawRequest(
         toAddress,
         aesKey,
         trade,
         () ->
             UserThread.execute(
                 () ->
                     navigation.navigateTo(
                         MainView.class, PortfolioView.class, ClosedTradesView.class)),
         (errorMessage, throwable) -> {
           log.error(errorMessage);
           new Popup().error("An error occurred:\n" + throwable.getMessage()).show();
         });
   }
 }
 private void onDeleteAccount(PaymentAccount paymentAccount) {
   new Popup()
       .warning("Do you really want to delete the selected account?")
       .actionButtonText("Yes")
       .onAction(
           () -> {
             boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount);
             if (!isPaymentAccountUsed) removeSelectAccountForm();
             else
               UserThread.runAfter(
                   () -> {
                     new Popup()
                         .warning(
                             "You cannot delete that account because it is used in an "
                                 + "open offer or in a trade.")
                         .show();
                   },
                   100,
                   TimeUnit.MILLISECONDS);
           })
       .closeButtonText("Cancel")
       .show();
 }
 private void scrollToBottom() {
   if (messageListView != null)
     UserThread.execute(() -> messageListView.scrollTo(Integer.MAX_VALUE));
 }
  private Tuple2<TableView<Offer>, VBox> getOfferTable(Offer.Direction direction) {
    TableView<Offer> tableView = new TableView();

    // price
    TableColumn<Offer, Offer> priceColumn = new TableColumn<>();
    priceColumn.textProperty().bind(priceColumnLabel);
    priceColumn.setMinWidth(120);
    priceColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
    priceColumn.setCellFactory(
        new Callback<TableColumn<Offer, Offer>, TableCell<Offer, Offer>>() {
          @Override
          public TableCell<Offer, Offer> call(TableColumn<Offer, Offer> column) {
            return new TableCell<Offer, Offer>() {
              @Override
              public void updateItem(final Offer item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null && !empty) setText(formatter.formatFiat(item.getPrice()));
                else setText("");
              }
            };
          }
        });
    tableView.getColumns().add(priceColumn);

    // amount
    TableColumn<Offer, Offer> amountColumn = new TableColumn<>("Amount (BTC)");
    amountColumn.setText("Amount (BTC)");
    amountColumn.setMinWidth(120);
    amountColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
    amountColumn.setCellFactory(
        new Callback<TableColumn<Offer, Offer>, TableCell<Offer, Offer>>() {
          @Override
          public TableCell<Offer, Offer> call(TableColumn<Offer, Offer> column) {
            return new TableCell<Offer, Offer>() {
              @Override
              public void updateItem(final Offer item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null && !empty) setText(formatter.formatCoin(item.getAmount()));
                else setText("");
              }
            };
          }
        });
    tableView.getColumns().add(amountColumn);

    // volume
    TableColumn<Offer, Offer> volumeColumn = new TableColumn<>("Amount (BTC)");
    volumeColumn.setMinWidth(120);
    volumeColumn.textProperty().bind(volumeColumnLabel);
    volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
    volumeColumn.setCellFactory(
        new Callback<TableColumn<Offer, Offer>, TableCell<Offer, Offer>>() {
          @Override
          public TableCell<Offer, Offer> call(TableColumn<Offer, Offer> column) {
            return new TableCell<Offer, Offer>() {
              @Override
              public void updateItem(final Offer item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null && !empty) setText(formatter.formatFiat(item.getOfferVolume()));
                else setText("");
              }
            };
          }
        });
    tableView.getColumns().add(volumeColumn);

    tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    Label placeholder = new Label("Currently there are no offers available");
    placeholder.setWrapText(true);
    tableView.setPlaceholder(placeholder);

    Label titleLabel =
        new Label(
            direction.equals(Offer.Direction.BUY)
                ? "Offers for buy bitcoin (bid)"
                : "Offers for sell bitcoin (ask)");
    titleLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-alignment: center");
    UserThread.execute(() -> titleLabel.prefWidthProperty().bind(tableView.widthProperty()));

    VBox vBox = new VBox();
    vBox.setSpacing(10);
    vBox.setFillWidth(true);
    vBox.setMinHeight(150);
    vBox.getChildren().addAll(titleLabel, tableView);
    return new Tuple2<>(tableView, vBox);
  }