Use PopupManager for queuing popups, improve version handling, deactivate focus requests, add popup when getting disconnection because of version conflict

This commit is contained in:
Manfred Karrer 2016-02-04 13:16:40 +01:00
parent ba4a228fed
commit a264fa4e0b
94 changed files with 421 additions and 288 deletions

View file

@ -128,18 +128,24 @@ public class BitsquareApp extends Application {
injector = Guice.createInjector(bitsquareAppModule);
injector.getInstance(InjectorViewFactory.class).setInjector(injector);
Version.setNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
// load the main view and create the main scene
CachingViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
mainView = (MainView) viewLoader.load(MainView.class);
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
Version.setBtcNetworkId(injector.getInstance(BitsquareEnvironment.class).getBitcoinNetwork().ordinal());
Storage.setDatabaseCorruptionHandler((String fileName) -> {
corruptedDatabaseFiles.add(fileName);
if (mainView != null)
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
});
// load the main view and create the main scene
CachingViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
mainView = (MainView) viewLoader.load(MainView.class);
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
/* Storage.setDatabaseCorruptionHandler((String fileName) -> {
corruptedDatabaseFiles.add(fileName);
if (mainView != null)
mainView.setPersistedFilesCorrupted(corruptedDatabaseFiles);
});*/
scene = new Scene(mainView.getRoot(), 1000, 740);
scene.getStylesheets().setAll(

View file

@ -73,7 +73,8 @@ public class AddressTextField extends AnchorPane {
}
});
textField.focusTraversableProperty().set(focusTraversableProperty().get());
focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
//TODO app wide focus
//focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
Label copyIcon = new Label();
copyIcon.setLayoutY(3);

View file

@ -67,7 +67,8 @@ public class TextFieldWithCopyIcon extends AnchorPane {
AnchorPane.setRightAnchor(textField, 30.0);
AnchorPane.setLeftAnchor(textField, 0.0);
textField.focusTraversableProperty().set(focusTraversableProperty().get());
focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
//TODO app wide focus
//focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
getChildren().addAll(textField, copyIcon);
}

View file

@ -85,7 +85,8 @@ public class TxIdTextField extends AnchorPane {
AnchorPane.setRightAnchor(textField, 55.0);
AnchorPane.setLeftAnchor(textField, 0.0);
textField.focusTraversableProperty().set(focusTraversableProperty().get());
focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
//TODO app wide focus
//focusedProperty().addListener((ov, oldValue, newValue) -> textField.requestFocus());
getChildren().addAll(textField, copyIcon, progressIndicator);
}

View file

@ -18,6 +18,7 @@
package io.bitsquare.gui.main;
import io.bitsquare.BitsquareException;
import io.bitsquare.app.BitsquareApp;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.util.Tuple2;
import io.bitsquare.gui.Navigation;
@ -184,11 +185,18 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
if (!persistedFilesCorrupted.isEmpty()) {
// show warning that some files has been corrupted
new Popup().warning("Those data base file(s) are not compatible with our current code base." +
"\n" + persistedFilesCorrupted.toString() +
"\n\nWe made a backup of the corrupted file(s) and applied the default values." +
"\n\nThe backup is located at: [data directory]/db/corrupted"
).show();
new Popup().warning("We detected incompatible data base files!\n\n" +
"Those database file(s) are not compatible with our current code base:" +
"\n" + persistedFilesCorrupted.toString() +
"\n\nWe made a backup of the corrupted file(s) and applied the default values to a new " +
"database version." +
"\n\nThe backup is located at:\n[you local app data directory]/db/backup_of_corrupted_data.\n\n" +
"Please check if you have the latest version of Bitsquare installed.\n" +
"You can download it at:\nhttps://github.com/bitsquare/bitsquare/releases\n\n" +
"Please restart the application.")
.closeButtonText("Shut down")
.onClose(BitsquareApp.shutDownHandler::run)
.show();
}
transitions.fadeOutAndRemove(splashScreen, 1500, actionEvent -> disposeSplashScreen());
@ -358,7 +366,8 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
model.walletServiceErrorMsg.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
btcInfoLabel.setId("splash-error-state-msg");
btcNetworkWarnMsgPopup = new Popup().warning(newValue).show();
btcNetworkWarnMsgPopup = new Popup().warning(newValue);
btcNetworkWarnMsgPopup.show();
} else {
btcInfoLabel.setId("footer-pane");
if (btcNetworkWarnMsgPopup != null)
@ -407,7 +416,8 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
p2PNetworkLabel.idProperty().bind(model.p2PNetworkLabelId);
model.p2PNetworkWarnMsg.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
p2PNetworkWarnMsgPopup = new Popup().warning(newValue).show();
p2PNetworkWarnMsgPopup = new Popup().warning(newValue);
p2PNetworkWarnMsgPopup.show();
} else if (p2PNetworkWarnMsgPopup != null) {
p2PNetworkWarnMsgPopup.hide();
}

View file

@ -41,6 +41,9 @@ import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.p2p.P2PService;
import io.bitsquare.p2p.P2PServiceListener;
import io.bitsquare.p2p.network.CloseConnectionReason;
import io.bitsquare.p2p.network.Connection;
import io.bitsquare.p2p.network.ConnectionListener;
import io.bitsquare.payment.OKPayAccount;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeManager;
@ -187,7 +190,7 @@ public class MainViewModel implements ViewModel {
"There might be some network connection problems.\n\n" +
"Please restart and try again.")
.closeButtonText("Shut down")
.onClose(() -> BitsquareApp.shutDownHandler.run())
.onClose(BitsquareApp.shutDownHandler::run)
.show();
});
}
@ -211,6 +214,34 @@ public class MainViewModel implements ViewModel {
private BooleanProperty initP2PNetwork() {
final BooleanProperty p2pNetworkInitialized = new SimpleBooleanProperty();
p2PNetworkInfo.set("Connecting to Tor network...");
p2PService.getNetworkNode().addConnectionListener(new ConnectionListener() {
@Override
public void onConnection(Connection connection) {
}
@Override
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
// We only check at seed nodes as they are running the latest version
// Other disconnects might be caused by peers running an older version
if (connection.getPeerType() == Connection.PeerType.SEED_NODE &&
closeConnectionReason == CloseConnectionReason.RULE_VIOLATION) {
new Popup()
.warning("You got disconnected from a seed node.\n\n" +
"Reason for getting disconnected: " + connection.getRuleViolation().name() + "\n\n" +
"It might be that your installed version is not compatible with " +
"the network.\n\n" +
"Please check if you run the latest software version.\n" +
"You can download the latest version of Bitsquare at:\n" +
"https://github.com/bitsquare/bitsquare/releases/\n\n" +
"")
.show();
}
}
@Override
public void onError(Throwable throwable) {
}
});
p2PService.start(new P2PServiceListener() {
@Override
public void onTorNodeReady() {
@ -348,8 +379,9 @@ public class MainViewModel implements ViewModel {
if (walletService.getWallet().isEncrypted() &&
(openOfferManager.getOpenOffers().size() > 0
|| tradeManager.getTrades().size() > 0
|| disputeManager.getDisputesAsObservableList().size() > 0))
walletPasswordPopup.show().onAesKey(aesKey -> tradeWalletService.setAesKey(aesKey));
|| disputeManager.getDisputesAsObservableList().size() > 0)) {
walletPasswordPopup.onAesKey(aesKey -> tradeWalletService.setAesKey(aesKey)).show();
}
if (tradeManager.pendingTradesInitializedProperty().get() && isSplashScreenRemoved.get())
applyTradePeriodState();

View file

@ -24,6 +24,7 @@ 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.popups.EnterPrivKeyPopup;
import io.bitsquare.gui.popups.Popup;
import io.bitsquare.gui.util.FormBuilder;
import io.bitsquare.gui.util.ImageUtil;

View file

@ -114,13 +114,13 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
private void askForPassword() {
walletPasswordPopup.show().onAesKey(aesKey -> {
walletPasswordPopup.onAesKey(aesKey -> {
Wallet wallet = walletService.getWallet();
KeyCrypter keyCrypter = wallet.getKeyCrypter();
keyChainSeed = wallet.getKeyChainSeed();
DeterministicSeed decryptedSeed = keyChainSeed.decrypt(keyCrypter, "", aesKey);
showSeedScreen(decryptedSeed);
});
}).show();
}
private void showSeedScreen(DeterministicSeed seed) {

View file

@ -21,9 +21,9 @@ import io.bitsquare.arbitration.Dispute;
import io.bitsquare.arbitration.DisputeManager;
import io.bitsquare.common.crypto.KeyRing;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.main.disputes.DisputeSummaryPopup;
import io.bitsquare.gui.main.disputes.trader.TraderDisputeView;
import io.bitsquare.gui.popups.ContractPopup;
import io.bitsquare.gui.popups.DisputeSummaryPopup;
import io.bitsquare.gui.popups.TradeDetailsPopup;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.TradeManager;

View file

@ -29,8 +29,8 @@ import io.bitsquare.gui.common.view.ActivatableView;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.components.HyperlinkWithIcon;
import io.bitsquare.gui.components.TableGroupHeadline;
import io.bitsquare.gui.main.disputes.DisputeSummaryPopup;
import io.bitsquare.gui.popups.ContractPopup;
import io.bitsquare.gui.popups.DisputeSummaryPopup;
import io.bitsquare.gui.popups.Popup;
import io.bitsquare.gui.popups.TradeDetailsPopup;
import io.bitsquare.gui.util.BSFormatter;

View file

@ -310,10 +310,11 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
}
private void doWithdraw(Coin amount, FutureCallback<Transaction> callback) {
if (walletService.getWallet().isEncrypted())
walletPasswordPopup.show().onAesKey(aesKey -> sendFunds(amount, aesKey, callback));
else
if (walletService.getWallet().isEncrypted()) {
walletPasswordPopup.onAesKey(aesKey -> sendFunds(amount, aesKey, callback)).show();
} else {
sendFunds(amount, null, callback);
}
}
private void sendFunds(Coin amount, KeyParameter aesKey, FutureCallback<Transaction> callback) {

View file

@ -253,10 +253,10 @@ class CreateOfferDataModel extends ActivatableDataModel {
void onPlaceOffer(Offer offer, TransactionResultHandler resultHandler) {
if (walletService.getWallet().isEncrypted() && tradeWalletService.getAesKey() == null) {
walletPasswordPopup.show().onAesKey(aesKey -> {
walletPasswordPopup.onAesKey(aesKey -> {
tradeWalletService.setAesKey(aesKey);
doPlaceOffer(offer, resultHandler);
});
}).show();
} else {
doPlaceOffer(offer, resultHandler);
}

View file

@ -220,7 +220,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
}
}
private void onShowInfo(boolean isPaymentAccountValidForOffer, boolean hasMatchingArbitrator) {
private void onShowInfo(boolean isPaymentAccountValidForOffer, boolean hasMatchingArbitrator, boolean hasSameProtocolVersion) {
if (!hasMatchingArbitrator) {
showWarning("You don't have an arbitrator selected.",
"You need to setup at least one arbitrator to be able to trade.\n" +
@ -229,6 +229,13 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
showWarning("You don't have a payment account with the payment method required for that offer.",
"You need to setup a payment account with that payment method if you want to take that offer.\n" +
"Do you want to do this now?", PaymentAccountView.class);
} else if (!hasSameProtocolVersion) {
new Popup().information("That offer requires a different protocol version as the one used in your " +
"version of the software." +
"\n\n" + "Please check if you have the latest version installed, otherwise the user " +
"who created the offer has used an older version.\n" +
"You cannot trade with an incompatible protocol version.")
.show();
}
}
@ -418,39 +425,42 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
boolean isTradable;
boolean isPaymentAccountValidForOffer;
boolean hasMatchingArbitrator;
boolean hasSameProtocolVersion;
{
button.setGraphic(iconView);
button.setMinWidth(70);
}
private void verifyIfTradable(final Offer offer) {
TableRow tableRow = getTableRow();
if (tableRow != null) {
isPaymentAccountValidForOffer = model.isPaymentAccountValidForOffer(offer);
hasMatchingArbitrator = model.hasMatchingArbitrator(offer);
isTradable = isPaymentAccountValidForOffer && hasMatchingArbitrator;
tableRow.setOpacity(isTradable ? 1 : 0.4);
if (isTradable) {
// set first row button as default
button.setDefaultButton(getIndex() == 0);
tableRow.setOnMouseClicked(null);
} else {
button.setDefaultButton(false);
tableRow.setOnMouseClicked(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator));
}
}
}
@Override
public void updateItem(final OfferBookListItem newItem, boolean empty) {
super.updateItem(newItem, empty);
if (newItem != null && !empty) {
final Offer offer = newItem.getOffer();
verifyIfTradable(offer);
TableRow tableRow = getTableRow();
if (tableRow != null) {
isPaymentAccountValidForOffer = model.isPaymentAccountValidForOffer(offer);
hasMatchingArbitrator = model.hasMatchingArbitrator(offer);
hasSameProtocolVersion = model.hasSameProtocolVersion(offer);
isTradable = isPaymentAccountValidForOffer && hasMatchingArbitrator &&
hasSameProtocolVersion;
tableRow.setOpacity(isTradable ? 1 : 0.4);
if (isTradable) {
// set first row button as default
button.setDefaultButton(getIndex() == 0);
tableRow.setOnMouseClicked(null);
} else {
button.setDefaultButton(false);
tableRow.setOnMouseClicked(e ->
onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator,
hasSameProtocolVersion));
}
}
String title;
if (isTradable) {
if (model.isMyOffer(offer)) {
@ -465,7 +475,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
} else {
title = "Not matching";
iconView.setId(null);
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator));
button.setOnAction(e -> onShowInfo(isPaymentAccountValidForOffer, hasMatchingArbitrator, hasSameProtocolVersion));
}
button.setText(title);

View file

@ -18,6 +18,7 @@
package io.bitsquare.gui.main.offer.offerbook;
import com.google.inject.Inject;
import io.bitsquare.app.Version;
import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.gui.common.model.ActivatableViewModel;
@ -281,7 +282,6 @@ class OfferBookViewModel extends ActivatableViewModel {
});
}
public boolean hasMatchingArbitrator(Offer offer) {
for (NodeAddress offerArbitratorNodeAddress : offer.getArbitratorNodeAddresses()) {
for (NodeAddress acceptedArbitratorNodeAddress : user.getAcceptedArbitratorAddresses()) {
@ -291,4 +291,8 @@ class OfferBookViewModel extends ActivatableViewModel {
}
return false;
}
public boolean hasSameProtocolVersion(Offer offer) {
return offer.getProtocolVersion() == Version.TRADE_PROTOCOL_VERSION;
}
}

View file

@ -167,10 +167,10 @@ class TakeOfferDataModel extends ActivatableDataModel {
// have it persisted as well.
void onTakeOffer(TradeResultHandler tradeResultHandler) {
if (walletService.getWallet().isEncrypted() && tradeWalletService.getAesKey() == null) {
walletPasswordPopup.show().onAesKey(aesKey -> {
walletPasswordPopup.onAesKey(aesKey -> {
tradeWalletService.setAesKey(aesKey);
doTakeOffer(tradeResultHandler);
});
}).show();
} else {
doTakeOffer(tradeResultHandler);
}

View file

@ -182,11 +182,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
.subscribe((observable, oldValue, newValue) -> {
if (!oldValue && newValue) {
isOfferAvailablePopup = new Popup().information(BSResources.get("takeOffer.fundsBox.isOfferAvailable"))
.show()
.onClose(() -> {
model.resetErrorMessage();
close();
}).show();
});
isOfferAvailablePopup.show();
}
});

View file

@ -170,9 +170,9 @@ public class PendingTradesDataModel extends ActivatableDataModel {
void onWithdrawRequest(String toAddress) {
checkNotNull(trade, "trade must not be null");
if (walletService.getWallet().isEncrypted())
walletPasswordPopup.show().onAesKey(aesKey -> doWithdrawRequest(toAddress, aesKey));
else
if (walletService.getWallet().isEncrypted()) {
walletPasswordPopup.onAesKey(aesKey -> doWithdrawRequest(toAddress, aesKey)).show();
} else
doWithdrawRequest(toAddress, null);
}

View file

@ -110,8 +110,9 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
// Focus selectedItem from model
int index = table.getItems().indexOf(model.getSelectedItem());
UserThread.execute(() -> {
table.requestFocus();
UserThread.execute(() -> table.getFocusModel().focus(index));
//TODO app wide focus
//table.requestFocus();
//UserThread.execute(() -> table.getFocusModel().focus(index));
});
}
};
@ -151,9 +152,10 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
// Select and focus selectedItem from model
int index = table.getItems().indexOf(selectedItem);
UserThread.execute(() -> {
//TODO app wide focus
table.getSelectionModel().select(index);
table.requestFocus();
UserThread.execute(() -> table.getFocusModel().focus(index));
//table.requestFocus();
//UserThread.execute(() -> table.getFocusModel().focus(index));
});
}
}

View file

@ -69,11 +69,12 @@ public class CompletedView extends TradeStepDetailsView {
// We need to handle both cases: Address not set and address already set (when returning from other view)
// We get address validation after focus out, so first make sure we loose focus and then set it again as hint for user to put address in
UserThread.execute(() -> {
withdrawAddressTextField.requestFocus();
UserThread.execute(() -> {
//TODO app wide focus
// withdrawAddressTextField.requestFocus();
/* UserThread.execute(() -> {
this.requestFocus();
UserThread.execute(() -> withdrawAddressTextField.requestFocus());
});
});*/
});
}

View file

@ -62,7 +62,7 @@ public class ContractPopup extends Popup {
width = 850;
createGridPane();
addContent();
createPopup();
display();
return this;
}
@ -152,7 +152,8 @@ public class ContractPopup extends Popup {
addLabelTxIdTextField(gridPane, ++rowIndex, "Payout transaction ID:", dispute.getPayoutTxId());
Button cancelButton = addButtonAfterGroup(gridPane, ++rowIndex, "Close");
cancelButton.requestFocus();
//TODO app wide focus
//cancelButton.requestFocus();
cancelButton.setOnAction(e -> {
closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run());
hide();

View file

@ -46,15 +46,14 @@ public class DisplayAlertMessagePopup extends Popup {
public DisplayAlertMessagePopup() {
}
public DisplayAlertMessagePopup show() {
public void show() {
width = 700;
// need to set headLine, otherwise the fields will not be created in addHeadLine
headLine = "Important information!";
createGridPane();
addHeadLine();
addContent();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public DisplayAlertMessagePopup alertMessage(Alert alert) {

View file

@ -15,7 +15,7 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.disputes;
package io.bitsquare.gui.popups;
import io.bitsquare.arbitration.Dispute;
import io.bitsquare.arbitration.DisputeManager;
@ -26,7 +26,6 @@ import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.exceptions.TransactionVerificationException;
import io.bitsquare.common.util.Tuple2;
import io.bitsquare.gui.popups.Popup;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.Transitions;
@ -89,7 +88,7 @@ public class DisputeSummaryPopup extends Popup {
width = 850;
createGridPane();
addContent();
createPopup();
PopupManager.queueForDisplay(this);
}
public DisputeSummaryPopup onClose(Runnable closeHandler) {

View file

@ -64,7 +64,7 @@ public class EmptyWalletPopup extends Popup {
this.formatter = formatter;
}
public EmptyWalletPopup show() {
public void show() {
if (headLine == null)
headLine = "Empty wallet";
@ -72,8 +72,7 @@ public class EmptyWalletPopup extends Popup {
createGridPane();
addHeadLine();
addContent();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public EmptyWalletPopup onClose(Runnable closeHandler) {

View file

@ -15,11 +15,10 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.arbitratorregistration;
package io.bitsquare.gui.popups;
import io.bitsquare.app.BitsquareApp;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.popups.Popup;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
@ -50,7 +49,7 @@ public class EnterPrivKeyPopup extends Popup {
public EnterPrivKeyPopup() {
}
public EnterPrivKeyPopup show() {
public void show() {
if (gridPane != null) {
rowIndex = -1;
gridPane.getChildren().clear();
@ -63,9 +62,7 @@ public class EnterPrivKeyPopup extends Popup {
addHeadLine();
addInputFields();
addButtons();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public EnterPrivKeyPopup onClose(Runnable closeHandler) {

View file

@ -79,7 +79,7 @@ public class OfferDetailsPopup extends Popup {
width = 850;
createGridPane();
addContent();
createPopup();
display();
return this;
}
@ -90,7 +90,7 @@ public class OfferDetailsPopup extends Popup {
width = 850;
createGridPane();
addContent();
createPopup();
display();
return this;
}

View file

@ -42,7 +42,7 @@ public class OpenEmergencyTicketPopup extends Popup {
public OpenEmergencyTicketPopup() {
}
public OpenEmergencyTicketPopup show() {
public void show() {
if (headLine == null)
headLine = "Open support ticket";
@ -50,8 +50,7 @@ public class OpenEmergencyTicketPopup extends Popup {
createGridPane();
addHeadLine();
addContent();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public OpenEmergencyTicketPopup onOpenTicket(ResultHandler openTicketHandler) {

View file

@ -78,7 +78,7 @@ public class Popup {
public Popup() {
}
public Popup show() {
public void show() {
createGridPane();
addHeadLine();
@ -91,13 +91,16 @@ public class Popup {
addCloseButton();
addDontShowAgainCheckBox();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public void hide() {
MainView.removeBlur();
stage.hide();
if (stage != null)
stage.hide();
else
log.warn("Stage is null");
PopupManager.isHidden(this);
}
public Popup onClose(Runnable closeHandler) {
@ -207,7 +210,7 @@ public class Popup {
FxTimer.runLater(Duration.ofMillis(Transitions.DEFAULT_DURATION), () -> MainView.blurLight());
}
protected void createPopup() {
public void display() {
if (owner == null)
owner = MainView.getRootContainer();
@ -333,7 +336,8 @@ public class Popup {
if (actionHandlerOptional.isPresent() || actionButtonText != null) {
actionButton = new Button(actionButtonText == null ? "Ok" : actionButtonText);
actionButton.setDefaultButton(true);
actionButton.requestFocus();
//TODO app wide focus
//actionButton.requestFocus();
actionButton.setOnAction(event -> {
hide();
actionHandlerOptional.ifPresent(actionHandler -> actionHandler.run());
@ -367,4 +371,12 @@ public class Popup {
else
truncatedMessage = message;
}
@Override
public String toString() {
return "Popup{" +
"headLine='" + headLine + '\'' +
", message='" + message + '\'' +
'}';
}
}

View file

@ -0,0 +1,40 @@
package io.bitsquare.gui.popups;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
class PopupManager {
private static final Logger log = LoggerFactory.getLogger(PopupManager.class);
private static Queue<Popup> popups = new LinkedBlockingQueue<>(3);
private static Popup displayedPopup;
static void queueForDisplay(Popup popup) {
boolean result = popups.offer(popup);
if (!result)
log.warn("The capacity is full with popups in the queue.\n\t" +
"Not added new popup=" + popup);
displayNext();
}
static void isHidden(Popup popup) {
if (displayedPopup == null || displayedPopup == popup) {
displayedPopup = null;
displayNext();
} else {
log.warn("We got a isHidden called with a wrong popup.\n\t" +
"popup (argument)=" + popup + "\n\tdisplayedPopup=" + displayedPopup);
}
}
private static void displayNext() {
if (displayedPopup == null) {
if (!popups.isEmpty()) {
displayedPopup = popups.poll();
displayedPopup.display();
}
}
}
}

View file

@ -51,7 +51,7 @@ public class SelectDepositTxPopup extends Popup {
public SelectDepositTxPopup() {
}
public SelectDepositTxPopup show() {
public void show() {
if (headLine == null)
headLine = "Select deposit transaction for dispute";
@ -60,8 +60,7 @@ public class SelectDepositTxPopup extends Popup {
addHeadLine();
addContent();
addCloseButton();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public SelectDepositTxPopup onSelect(Consumer<Transaction> selectHandler) {

View file

@ -59,7 +59,7 @@ public class SendAlertMessagePopup extends Popup {
public SendAlertMessagePopup() {
}
public SendAlertMessagePopup show() {
public void show() {
if (headLine == null)
headLine = "Send global notification";
@ -67,8 +67,7 @@ public class SendAlertMessagePopup extends Popup {
createGridPane();
addHeadLine();
addContent();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public SendAlertMessagePopup onAddAlertMessage(SendAlertMessageHandler sendAlertMessageHandler) {

View file

@ -65,7 +65,7 @@ public class TradeDetailsPopup extends Popup {
width = 850;
createGridPane();
addContent();
createPopup();
display();
return this;
}
@ -191,7 +191,8 @@ public class TradeDetailsPopup extends Popup {
}
Button cancelButton = addButtonAfterGroup(gridPane, ++rowIndex, "Close");
cancelButton.requestFocus();
//TODO app wide focus
//cancelButton.requestFocus();
cancelButton.setOnAction(e -> {
closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run());
hide();

View file

@ -64,7 +64,7 @@ public class WalletPasswordPopup extends Popup {
this.walletService = walletService;
}
public WalletPasswordPopup show() {
public void show() {
if (gridPane != null) {
rowIndex = -1;
gridPane.getChildren().clear();
@ -77,9 +77,7 @@ public class WalletPasswordPopup extends Popup {
addHeadLine();
addInputFields();
addButtons();
createPopup();
return this;
PopupManager.queueForDisplay(this);
}
public WalletPasswordPopup onClose(Runnable closeHandler) {

View file

@ -10,7 +10,12 @@
<appender-ref ref="CONSOLE_APPENDER"/>
</root>
<!-- <logger name="io.bitsquare.p2p.peers.PeerGroup" level="TRACE"/>
<logger name="io.bitsquare.storage.Storage" level="WARN"/>
<logger name="io.bitsquare.storage.FileManager" level="WARN"/>
<logger name="io.bitsquare.p2p.P2PService" level="TRACE"/>
<logger name="io.bitsquare.p2p.storage.ProtectedExpirableDataStorage" level="TRACE"/>
<logger name="io.bitsquare.p2p.network.LocalhostNetworkNode" level="TRACE"/>