Handle views for trade process

This commit is contained in:
Manfred Karrer 2015-04-03 16:51:36 +02:00
parent 3a95e51bc9
commit a2aa0b40b4
18 changed files with 273 additions and 296 deletions

View file

@ -61,14 +61,7 @@ public class TaskRunner<T extends Model> {
try {
currentTask = tasks.poll();
log.trace("Run task: " + currentTask.getSimpleName());
log.debug("sharedModel.getClass() " + sharedModel.getClass());
log.debug("sharedModel.getClass().getSuperclass() " + sharedModel.getClass().getSuperclass());
/* Object c = currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass());
log.debug("c " + c);
Object c2 = currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass().getSuperclass());
log.debug("c getSuperclass " + c2);
Object o = currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel);*/
//TODO solve in tasks problem with superclasses
// We use also super class as type ein tasks, so we need to support both variants
try {
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run();
} catch (Throwable throwable) {

View file

@ -79,8 +79,11 @@ public class BuyerSubView extends TradeSubView {
waitFiatReceived.inactive();
completed.inactive();
if (tradeStepDetailsView != null)
tradeStepDetailsView.deactivate();
switch (viewState) {
case EMPTY:
case UNDEFINED:
break;
case BUYER_WAIT_TX_CONF:
showItem(waitTxInBlockchain);

View file

@ -0,0 +1,30 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.portfolio.pending;
// That is used if trade is null but must not be null in that state
public class MissingTradeException extends RuntimeException {
public MissingTradeException(String msg) {
super(msg);
}
public MissingTradeException() {
super("Trade is null.That must not happen.");
}
}

View file

@ -0,0 +1,30 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.portfolio.pending;
// That is used if trade is null and it is a valid state
public class NoTradeFoundException extends Throwable {
public NoTradeFoundException(String msg) {
super(msg);
}
public NoTradeFoundException() {
super("Trade is null");
}
}

View file

@ -21,7 +21,11 @@ import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService;
import io.bitsquare.common.viewfx.model.Activatable;
import io.bitsquare.common.viewfx.model.DataModel;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.closed.ClosedTradesView;
import io.bitsquare.offer.Offer;
import io.bitsquare.trade.BuyerTrade;
import io.bitsquare.trade.Contract;
@ -37,9 +41,8 @@ import com.google.inject.Inject;
import java.util.stream.Collectors;
import javafx.beans.property.IntegerProperty;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
@ -56,6 +59,7 @@ class PendingTradesDataModel implements Activatable, DataModel {
private final TradeManager tradeManager;
private final WalletService walletService;
private final User user;
private Navigation navigation;
private final ObservableList<PendingTradesListItem> list = FXCollections.observableArrayList();
@ -65,7 +69,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
private final ListChangeListener<Trade> tradesListChangeListener;
final StringProperty txId = new SimpleStringProperty();
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
final ObjectProperty<TradeState.ProcessState> sellerProcessState = new SimpleObjectProperty<>();
final ObjectProperty<TradeState.ProcessState> buyerProcessState = new SimpleObjectProperty<>();
@ -73,23 +76,19 @@ class PendingTradesDataModel implements Activatable, DataModel {
final ObjectProperty<Trade> currentTrade = new SimpleObjectProperty<>();
@Inject
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, User user) {
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, User user, Navigation navigation) {
this.tradeManager = tradeManager;
this.walletService = walletService;
this.user = user;
this.navigation = navigation;
tradesListChangeListener = change -> onListChanged();
}
@Override
public void activate() {
onListChanged();
tradeManager.getPendingTrades().addListener(tradesListChangeListener);
if (list.size() > 0) {
selectTrade(list.get(0));
selectedIndex.set(0);
}
onListChanged();
}
@Override
@ -105,20 +104,22 @@ class PendingTradesDataModel implements Activatable, DataModel {
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
if (list.size() > 0) {
log.debug("onListChanged {}", list.size());
if (list.size() > 0)
selectTrade(list.get(0));
selectedIndex.set(0);
}
else if (list.size() == 0)
selectTrade(null);
}
boolean isBuyOffer() {
boolean isBuyOffer() throws NoTradeFoundException {
if (getTrade() != null)
return getTrade().getOffer().getDirection() == Offer.Direction.BUY;
else
return false;
throw new NoTradeFoundException();
}
void selectTrade(PendingTradesListItem item) {
log.debug("selectTrade {} {}", item != null, item != null ? item.getTrade().getId() : "null");
// clean up previous selectedItem
unbindStates();
@ -144,52 +145,67 @@ class PendingTradesDataModel implements Activatable, DataModel {
}
void fiatPaymentStarted() {
if (getTrade() instanceof BuyerTrade)
((BuyerTrade) getTrade()).onFiatPaymentStarted();
try {
if (getTrade() instanceof BuyerTrade)
((BuyerTrade) getTrade()).onFiatPaymentStarted();
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
}
void fiatPaymentReceived() {
if (getTrade() instanceof SellerTrade)
((SellerTrade) getTrade()).onFiatPaymentReceived();
try {
if (getTrade() instanceof SellerTrade)
((SellerTrade) getTrade()).onFiatPaymentReceived();
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
}
void withdraw(String toAddress) {
if (getTrade() != null) {
tradeManager.requestWithdraw(toAddress,
getTrade(),
() -> log.debug("requestWithdraw was successful"),
(errorMessage, throwable) -> {
log.error(errorMessage);
Popups.openExceptionPopup(throwable);
});
/*
Action response = Popups.openConfirmPopup(
"Withdrawal request", "Confirm your request",
"Your withdrawal request:\n\n" + "Amount: " + amountTextField.getText() + " BTC\n" + "Sending" +
" address: " + withdrawFromTextField.getText() + "\n" + "Receiving address: " +
withdrawToTextField.getText() + "\n" + "Transaction fee: " +
formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
"You receive in total: " +
formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
"Are you sure you withdraw that amount?");
if (Popups.isOK(response)) {
try {
walletService.sendFunds(
withdrawFromTextField.getText(), withdrawToTextField.getText(),
changeAddressTextField.getText(), amount, callback);
} catch (AddressFormatException e) {
Popups.openErrorPopup("Address invalid",
"The address is not correct. Please check the address format.");
} catch (InsufficientMoneyException e) {
Popups.openInsufficientMoneyPopup();
} catch (IllegalArgumentException e) {
Popups.openErrorPopup("Wrong inputs", "Please check the inputs.");
try {
if (getTrade() != null) {
tradeManager.requestWithdraw(toAddress,
getTrade(),
() -> {
log.debug("requestWithdraw was successful");
Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
},
(errorMessage, throwable) -> {
log.error(errorMessage);
Popups.openExceptionPopup(throwable);
});
/*
Action response = Popups.openConfirmPopup(
"Withdrawal request", "Confirm your request",
"Your withdrawal request:\n\n" + "Amount: " + amountTextField.getText() + " BTC\n" + "Sending" +
" address: " + withdrawFromTextField.getText() + "\n" + "Receiving address: " +
withdrawToTextField.getText() + "\n" + "Transaction fee: " +
formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
"You receive in total: " +
formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
"Are you sure you withdraw that amount?");
if (Popups.isOK(response)) {
try {
walletService.sendFunds(
withdrawFromTextField.getText(), withdrawToTextField.getText(),
changeAddressTextField.getText(), amount, callback);
} catch (AddressFormatException e) {
Popups.openErrorPopup("Address invalid",
"The address is not correct. Please check the address format.");
} catch (InsufficientMoneyException e) {
Popups.openInsufficientMoneyPopup();
} catch (IllegalArgumentException e) {
Popups.openErrorPopup("Wrong inputs", "Please check the inputs.");
}
}*/
}
}*/
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
}
@ -223,17 +239,19 @@ class PendingTradesDataModel implements Activatable, DataModel {
}
Throwable getTradeException() {
if (getTrade() != null)
try {
return getTrade().getThrowable();
else
} catch (NoTradeFoundException e) {
return null;
}
}
String getErrorMessage() {
if (getTrade() != null)
try {
return getTrade().getErrorMessage();
else
} catch (NoTradeFoundException e) {
return null;
}
}
public Offer.Direction getDirection(Offer offer) {
@ -247,21 +265,26 @@ class PendingTradesDataModel implements Activatable, DataModel {
}
public Coin getPayoutAmount() {
return getTrade().getPayoutAmount();
try {
return getTrade().getPayoutAmount();
} catch (NoTradeFoundException e) {
return Coin.ZERO;
}
}
public Contract getContract() {
if (getTrade() != null)
try {
return getTrade().getContract();
else
return null;
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
}
public Trade getTrade() {
public Trade getTrade() throws NoTradeFoundException {
if (currentTrade.get() != null)
return currentTrade.get();
else
return null;
throw new NoTradeFoundException();
}
}

View file

@ -20,6 +20,7 @@ package io.bitsquare.gui.main.portfolio.pending;
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
import io.bitsquare.common.viewfx.view.FxmlView;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.trade.Trade;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.Coin;
@ -30,6 +31,7 @@ import java.util.Date;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
@ -55,7 +57,9 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
private ChangeListener<PendingTradesListItem> selectedItemChangeListener;
private TradeSubView currentSubView;
private ChangeListener<Boolean> appFocusChangeListener;
private ReadOnlyBooleanProperty appFocusProperty;
private ChangeListener<Trade> currentTradeChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
@ -79,17 +83,43 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
table.setPlaceholder(new Label("No pending trades available"));
selectedItemChangeListener = (ov, oldValue, newValue) -> {
log.debug("selectedItemChangeListener {}", newValue);
model.selectTrade(newValue);
if (newValue != null)
addSubView();
else
removeSubView();
};
model.selectTrade(newValue);
appFocusChangeListener = (observable, oldValue, newValue) -> {
log.debug("appFocusChangeListener {}", newValue);
if (newValue && model.getSelectedItem() != null) {
// Focus selectedItem from model
int index = table.getItems().indexOf(model.getSelectedItem());
Platform.runLater(() -> {
table.requestFocus();
Platform.runLater(() -> table.getFocusModel().focus(index));
});
}
};
currentTradeChangeListener = (observable, oldValue, newValue) -> {
log.debug("currentTradeChangeListener {} {}", newValue, model.getList().size());
if (newValue != null)
addSubView();
else
removeSubView();
};
}
@Override
public void doActivate() {
appFocusProperty = root.getScene().getWindow().focusedProperty();
appFocusProperty.addListener(appFocusChangeListener);
model.currentTrade().addListener(currentTradeChangeListener);
table.setItems(model.getList());
table.getSelectionModel().selectedItemProperty().addListener(selectedItemChangeListener);
PendingTradesListItem selectedItem = model.getSelectedItem();
if (selectedItem != null) {
@ -117,6 +147,9 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
if (currentSubView != null)
currentSubView.deactivate();
appFocusProperty.removeListener(appFocusChangeListener);
model.currentTrade().removeListener(currentTradeChangeListener);
}
@ -125,31 +158,48 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
///////////////////////////////////////////////////////////////////////////////////////////
private void addSubView() {
log.debug("addSubView");
removeSubView();
if (model.isOfferer()) {
if (model.isBuyOffer())
currentSubView = new BuyerSubView(model);
else
currentSubView = new SellerSubView(model);
try {
if (model.isBuyOffer())
currentSubView = new BuyerSubView(model);
else
currentSubView = new SellerSubView(model);
} catch (NoTradeFoundException e) {
log.warn("No trade selected");
}
}
else {
if (model.isBuyOffer())
currentSubView = new SellerSubView(model);
else
currentSubView = new BuyerSubView(model);
try {
if (model.isBuyOffer())
currentSubView = new SellerSubView(model);
else
currentSubView = new BuyerSubView(model);
} catch (NoTradeFoundException e) {
log.warn("No trade selected");
}
}
currentSubView.activate();
if (currentSubView != null) {
currentSubView.activate();
AnchorPane.setTopAnchor(currentSubView, 0d);
AnchorPane.setRightAnchor(currentSubView, 0d);
AnchorPane.setBottomAnchor(currentSubView, 0d);
AnchorPane.setLeftAnchor(currentSubView, 0d);
tradeStepPane.getChildren().setAll(currentSubView);
AnchorPane.setTopAnchor(currentSubView, 0d);
AnchorPane.setRightAnchor(currentSubView, 0d);
AnchorPane.setBottomAnchor(currentSubView, 0d);
AnchorPane.setLeftAnchor(currentSubView, 0d);
tradeStepPane.getChildren().setAll(currentSubView);
log.warn("currentSubView added");
}
else {
log.warn("currentSubView=null");
}
}
private void removeSubView() {
log.debug("removeSubView called");
if (currentSubView != null) {
log.debug("remove currentSubView");
currentSubView.deactivate();
tradeStepPane.getChildren().remove(currentSubView);
currentSubView = null;

View file

@ -20,13 +20,10 @@ package io.bitsquare.gui.main.portfolio.pending;
import io.bitsquare.btc.WalletService;
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
import io.bitsquare.common.viewfx.model.ViewModel;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.closed.ClosedTradesView;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.BtcAddressValidator;
import io.bitsquare.locale.BSResources;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.states.OffererTradeState;
import io.bitsquare.trade.states.TakerTradeState;
@ -37,13 +34,10 @@ import com.google.inject.Inject;
import java.util.Date;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
@ -56,7 +50,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
private static final Logger log = LoggerFactory.getLogger(PendingTradesViewModel.class);
enum ViewState {
EMPTY,
UNDEFINED,
SELLER_WAIT_TX_CONF,
SELLER_WAIT_PAYMENT_STARTED,
SELLER_CONFIRM_RECEIVE_PAYMENT,
@ -71,25 +65,22 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
EXCEPTION
}
private Navigation navigation;
private final BSFormatter formatter;
private final InvalidationListener sellerStateListener;
private final InvalidationListener buyerStateListener;
private final BtcAddressValidator btcAddressValidator;
public final StringProperty txId = new SimpleStringProperty();
public final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true);
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
final ObjectProperty<ViewState> viewState = new SimpleObjectProperty<>(ViewState.EMPTY);
final ObjectProperty<ViewState> viewState = new SimpleObjectProperty<>(ViewState.UNDEFINED);
@Inject
public PendingTradesViewModel(PendingTradesDataModel dataModel, Navigation navigation, BSFormatter formatter,
public PendingTradesViewModel(PendingTradesDataModel dataModel, BSFormatter formatter,
BtcAddressValidator btcAddressValidator) {
super(dataModel);
this.navigation = navigation;
this.formatter = formatter;
this.btcAddressValidator = btcAddressValidator;
@ -100,7 +91,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
@Override
public void doActivate() {
txId.bind(dataModel.txId);
selectedIndex.bind(dataModel.selectedIndex);
dataModel.sellerProcessState.addListener(sellerStateListener);
dataModel.buyerProcessState.addListener(buyerStateListener);
@ -112,7 +102,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
@Override
public void doDeactivate() {
txId.unbind();
selectedIndex.unbind();
dataModel.sellerProcessState.removeListener(sellerStateListener);
dataModel.buyerProcessState.removeListener(buyerStateListener);
@ -123,10 +112,13 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
dataModel.selectTrade(item);
}
boolean isBuyOffer() {
boolean isBuyOffer() throws NoTradeFoundException {
return dataModel.isBuyOffer();
}
ObjectProperty<Trade> currentTrade() {
return dataModel.currentTrade;
}
public void fiatPaymentStarted() {
dataModel.fiatPaymentStarted();
@ -138,7 +130,6 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
public void withdraw(String withdrawToAddress) {
dataModel.withdraw(withdrawToAddress);
Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
}
public void withdrawAddressFocusOut(String text) {
@ -201,7 +192,11 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
public String getFiatAmount() {
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
try {
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
} catch (NoTradeFoundException e) {
return "";
}
}
public String getHolderName() {
@ -221,11 +216,19 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
// summary
public String getTradeVolume() {
return dataModel.getTrade() != null ? formatter.formatCoinWithCode(dataModel.getTrade().getTradeAmount()) : "";
try {
return formatter.formatCoinWithCode(dataModel.getTrade().getTradeAmount());
} catch (NoTradeFoundException e) {
return "";
}
}
public String getFiatVolume() {
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
try {
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
} catch (NoTradeFoundException e) {
return "";
}
}
public String getTotalFees() {
@ -235,10 +238,15 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
public String getSecurityDeposit() {
// securityDeposit is handled different for offerer and taker.
// Offerer have paid in the max amount, but taker might have taken less so also paid in less securityDeposit
if (dataModel.isOfferer())
return formatter.formatCoinWithCode(dataModel.getTrade().getOffer().getSecurityDeposit());
else
return formatter.formatCoinWithCode(dataModel.getTrade().getSecurityDeposit());
try {
if (dataModel.isOfferer())
return formatter.formatCoinWithCode(dataModel.getTrade().getOffer().getSecurityDeposit());
else
return formatter.formatCoinWithCode(dataModel.getTrade().getSecurityDeposit());
} catch (NoTradeFoundException e) {
return "";
}
}
public BtcAddressValidator getBtcAddressValidator() {

View file

@ -78,8 +78,11 @@ public class SellerSubView extends TradeSubView {
confirmFiatReceived.inactive();
completed.inactive();
if (tradeStepDetailsView != null)
tradeStepDetailsView.deactivate();
switch (viewState) {
case EMPTY:
case UNDEFINED:
break;
case SELLER_WAIT_TX_CONF:
showItem(waitTxInBlockchain);

View file

@ -33,8 +33,8 @@ public abstract class TradeSubView extends HBox {
protected VBox leftVBox;
protected AnchorPane contentPane;
protected PendingTradesViewModel model;
protected ChangeListener<PendingTradesViewModel.ViewState> offererStateChangeListener;
protected TradeStepDetailsView tradeStepDetailsView;
protected ChangeListener<PendingTradesViewModel.ViewState> offererStateChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -24,7 +24,6 @@ import io.bitsquare.gui.main.portfolio.pending.PendingTradesViewModel;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.locale.BSResources;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
@ -84,7 +83,7 @@ public class StartFiatView extends TradeStepDetailsView {
super.activate();
model.txId.addListener(txIdChangeListener);
Platform.runLater(() -> txIdTextField.setup(model.getWalletService(), model.txId.get()));
txIdTextField.setup(model.getWalletService(), model.txId.get());
}
@Override

View file

@ -54,6 +54,7 @@ public abstract class TradeStepDetailsView extends AnchorPane {
buildGridEntries();
}
// That is called at every state change!
public void activate() {
log.debug("activate");
}

View file

@ -35,7 +35,6 @@ import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.offer.OffersView;
import io.bitsquare.gui.main.portfolio.pending.PendingTradesView;
import io.bitsquare.gui.main.trade.TradeView;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.BSResources;
@ -295,7 +294,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
// TODO temp just for testing
newValue = false;
close();
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class, OffersView.class);
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
if (newValue) {
overlayManager.blurContent();

View file

@ -282,7 +282,7 @@ public class Offer implements Serializable {
", fiatPrice=" + fiatPrice +
", amount=" + amount +
", minAmount=" + minAmount +
", p2pSigPubKey=" + p2pSigPubKey +
/* ", p2pSigPubKey=" + p2pSigPubKey +*/
", fiatAccountType=" + fiatAccountType +
", bankAccountCountry=" + bankAccountCountry +
", securityDeposit=" + securityDeposit +
@ -292,6 +292,7 @@ public class Offer implements Serializable {
", arbitratorIds=" + arbitratorIds +
", offerFeePaymentTxID='" + offerFeePaymentTxID + '\'' +
", state=" + state +
", stateProperty=" + stateProperty +
'}';
}
}

View file

@ -75,7 +75,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class FileManager<T> {
private static final Logger log = LoggerFactory.getLogger(FileManager.class);
private static final ReentrantLock lock = Threading.lock("FileUtil");
private static final ReentrantLock lock = Threading.lock("FileManager");
private final File dir;
private final File storageFile;
@ -164,6 +164,7 @@ public class FileManager<T> {
}
public T read(File file) throws IOException, ClassNotFoundException {
log.debug("read" + file);
lock.lock();
try (final FileInputStream fileInputStream = new FileInputStream(file);
final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
@ -256,6 +257,9 @@ public class FileManager<T> {
fileOutputStream = new FileOutputStream(tempFile);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
// TODO ConcurrentModificationException happens sometimes at that line
//log.debug("serializable " + serializable.toString());
log.debug("storageFile " + storageFile.toString());
objectOutputStream.writeObject(serializable);
// Attempt to force the bits to hit the disk. In reality the OS or hard disk itself may still decide
@ -271,6 +275,7 @@ public class FileManager<T> {
renameTempFileToFile(tempFile, storageFile);
} catch (Throwable t) {
t.printStackTrace();
log.error("Error at saveToFile: " + t.getMessage());
} finally {
if (tempFile != null && tempFile.exists()) {
log.warn("Temp file still exists after failed save. storageFile=" + storageFile);
@ -286,7 +291,7 @@ public class FileManager<T> {
} catch (IOException e) {
// We swallow that
e.printStackTrace();
log.error("Cannot close resources.");
log.error("Cannot close resources." + e.getMessage());
}
lock.unlock();
}

View file

@ -427,7 +427,6 @@ abstract public class Trade implements Model, Serializable {
abstract protected void initStates();
@Override
public String toString() {
return "Trade{" +
@ -446,10 +445,10 @@ abstract public class Trade implements Model, Serializable {
", lifeCycleState=" + lifeCycleState +
", mailboxMessage=" + mailboxMessage +
", depositTx=" + depositTx +
", contract=" + contract +
", contractAsJson='" + contractAsJson + '\'' +
", sellerContractSignature='" + sellerContractSignature + '\'' +
", buyerContractSignature='" + buyerContractSignature + '\'' +
/* ", contract=" + contract +
", contractAsJson='" + contractAsJson + '\'' +*/
/* ", sellerContractSignature='" + sellerContractSignature + '\'' +
", buyerContractSignature='" + buyerContractSignature + '\'' +*/
", payoutTx=" + payoutTx +
", errorMessage='" + errorMessage + '\'' +
", throwable=" + throwable +

View file

@ -167,14 +167,6 @@ public class ProcessModel implements Model, Serializable {
return mailboxMessage;
}
@Override
public String toString() {
return "ProcessModel{" +
"offer=" + offer +
'}';
}
@Nullable
public Transaction getPayoutTx() {
return payoutTx;
@ -280,11 +272,9 @@ public class ProcessModel implements Model, Serializable {
@Override
public void persist() {
}
@Override
public void onComplete() {
}
}

View file

@ -29,7 +29,6 @@ import java.io.Serializable;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
@ -178,24 +177,4 @@ public class TradingPeer implements Serializable {
public void setContractSignature(String contractSignature) {
this.contractSignature = contractSignature;
}
@Override
public String toString() {
return "TradingPeer{" +
"accountId='" + accountId + '\'' +
", p2pSigPubKey=" + p2pSigPubKey +
", p2pEncryptPubKey=" + p2pEncryptPubKey +
", tradeWalletPubKey=" + Arrays.toString(tradeWalletPubKey) +
", fiatAccount=" + fiatAccount +
", preparedDepositTx=" + preparedDepositTx +
", connectedOutputsForAllInputs=" + connectedOutputsForAllInputs +
", outputs=" + outputs +
", payoutAmount=" + payoutAmount +
", payoutAddressString='" + payoutAddressString + '\'' +
", signature=" + Arrays.toString(signature) +
", contractAsJson='" + contractAsJson + '\'' +
", contractSignature='" + contractSignature + '\'' +
'}';
}
}

View file

@ -1,136 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.trade.protocol.placeoffer;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TaskRunner {
private static final Logger log = LoggerFactory.getLogger(TaskRunner.class);
private Queue<Class> tasks;
private SharedModel sharedModel = new SharedModel();
private FaultHandler faultHandler;
private ResultHandler taskCompleted;
private final boolean[] failed = {false};
@Test
public void test() {
// Task1.run();
//Task2.run();
tasks = new LinkedBlockingQueue<>();
tasks.add(Task1.class);
tasks.add(Task2.class);
faultHandler = (throwable) -> {
log.debug(throwable.getMessage());
failed[0] = true;
};
taskCompleted = () -> {
next();
};
next();
/* ResultHandler handleResult = () -> {
Class task = tasks.poll();
try {
if (!failed[0])
((Task) task.newInstance()).run(sharedModel, taskCompleted, faultHandler);
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
};*/
/* tasks.stream().forEach((e) -> {
try {
((Task) e.newInstance()).run(sharedModel, faultHandler);
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
});*/
}
private void next() {
Class task = tasks.poll();
if (task != null) {
try {
if (!failed[0])
((Task) task.newInstance()).run(sharedModel, taskCompleted, faultHandler);
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
}
}
}
interface ResultHandler {
void handleResult();
}
interface FaultHandler {
void handleFault(Throwable throwable);
}
class SharedModel {
public int data = 42;
}
class Task {
protected void run(SharedModel sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
}
}
class Task1 extends Task {
private static final Logger log = LoggerFactory.getLogger(Task1.class);
@Override
public void run(SharedModel sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
log.debug("run " + Task1.class);
log.debug("data " + sharedModel.data);
// faultHandler.handleFault(new Exception("test"));
sharedModel.data++;
resultHandler.handleResult();
}
}
class Task2 extends Task {
private static final Logger log = LoggerFactory.getLogger(Task2.class);
@Override
public void run(SharedModel sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
log.debug("run " + Task2.class);
log.debug("data " + sharedModel.data);
resultHandler.handleResult();
}
}