Add connection icons, handleError cases in one method

This commit is contained in:
Manfred Karrer 2014-11-10 15:15:49 +01:00
parent 7ccfd98fb9
commit bdcd60d1fe
14 changed files with 112 additions and 74 deletions

View file

@ -139,10 +139,9 @@ public class Main extends Application {
// For now we exit when closing/quit the app.
// Later we will only hide the window (systemTray.hideStage()) and use the exit item in the system tray for
// shut down.
if (new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN).match(keyEvent))
systemTray.exit();
if (new KeyCodeCombination(KeyCode.Q, KeyCombination.SHORTCUT_DOWN).match(keyEvent))
systemTray.exit();
if (new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN).match(keyEvent) ||
new KeyCodeCombination(KeyCode.Q, KeyCombination.SHORTCUT_DOWN).match(keyEvent))
stop();
});

View file

@ -94,12 +94,7 @@ public class SystemTray {
}
});
exitItem.addActionListener(e -> exit());
}
public void exit() {
java.awt.SystemTray.getSystemTray().remove(trayIcon);
onExit.run();
exitItem.addActionListener(e -> onExit.run());
}
public void hideStage() {

View file

@ -122,3 +122,20 @@
#image-arrow-grey {
-fx-image: url("../../../images/arrow_grey.png");
}
/* connection state*/
#image-connection-direct {
-fx-image: url("../../../images/connection/direct.png");
}
#image-connection-nat {
-fx-image: url("../../../images/connection/nat.png");
}
#image-connection-relay {
-fx-image: url("../../../images/connection/relay.png");
}
#image-connection-synced {
-fx-image: url("../../../images/connection/synced.png");
}

View file

@ -48,16 +48,19 @@ class MainPM extends PresentationModel<MainModel> {
final BooleanProperty backendReady = new SimpleBooleanProperty();
final StringProperty bankAccountsComboBoxPrompt = new SimpleStringProperty();
final BooleanProperty bankAccountsComboBoxDisable = new SimpleBooleanProperty();
final StringProperty blockchainSyncState = new SimpleStringProperty("Initializing");
final IntegerProperty numPendingTrades = new SimpleIntegerProperty();
final StringProperty blockchainSyncState = new SimpleStringProperty("Initializing");
final DoubleProperty blockchainSyncProgress = new SimpleDoubleProperty();
final BooleanProperty blockchainSyncIndicatorVisible = new SimpleBooleanProperty(true);
final StringProperty blockchainSyncIconId = new SimpleStringProperty();
final StringProperty walletFacadeErrorMsg = new SimpleStringProperty();
final DoubleProperty bootstrapProgress = new SimpleDoubleProperty(-1);
final BooleanProperty bootstrapFailed = new SimpleBooleanProperty();
final BooleanProperty bootstrapIndicatorVisible = new SimpleBooleanProperty(true);
final StringProperty bootstrapState = new SimpleStringProperty();
final StringProperty bootstrapErrorMsg = new SimpleStringProperty();
final StringProperty walletFacadeErrorMsg = new SimpleStringProperty();
final StringProperty bootstrapIconId = new SimpleStringProperty();
///////////////////////////////////////////////////////////////////////////////////////////
@ -88,8 +91,14 @@ class MainPM extends PresentationModel<MainModel> {
newValue == BootstrapState.NAT_SUCCESS ||
newValue == BootstrapState.RELAY_SUCCESS) {
bootstrapState.set("Successfully connected to P2P network: " + newValue.getMessage());
bootstrapIndicatorVisible.set(false);
bootstrapProgress.set(1);
if (newValue == BootstrapState.DIRECT_SUCCESS)
bootstrapIconId.set("image-connection-direct");
else if (newValue == BootstrapState.NAT_SUCCESS)
bootstrapIconId.set("image-connection-nat");
else if (newValue == BootstrapState.RELAY_SUCCESS)
bootstrapIconId.set("image-connection-relay");
}
else if (newValue == BootstrapState.PEER_CREATION_FAILED ||
newValue == BootstrapState.DIRECT_FAILED ||
@ -98,7 +107,6 @@ class MainPM extends PresentationModel<MainModel> {
bootstrapErrorMsg.set(newValue.getMessage());
bootstrapState.set("Connection to P2P network failed.");
bootstrapIndicatorVisible.set(false);
bootstrapProgress.set(0);
bootstrapFailed.set(true);
}
@ -115,9 +123,15 @@ class MainPM extends PresentationModel<MainModel> {
walletFacadeErrorMsg.set(((Throwable) newValue).getMessage());
});
model.networkSyncProgress.addListener((ov, oldValue, newValue) -> setNetworkSyncProgress((double) newValue));
model.networkSyncProgress.addListener((ov, oldValue, newValue) -> {
setNetworkSyncProgress((double) newValue);
if ((double) newValue >= 1)
blockchainSyncIconId.set("image-connection-synced");
});
setNetworkSyncProgress(model.networkSyncProgress.get());
model.getBankAccounts().addListener((ListChangeListener<BankAccount>) change -> {
bankAccountsComboBoxDisable.set(change.getList().isEmpty());
bankAccountsComboBoxPrompt.set(change.getList().isEmpty() ? "No accounts" : "");

View file

@ -297,39 +297,64 @@ public class MainViewCB extends ViewCB<MainPM> {
ProgressBar blockchainSyncIndicator = new ProgressBar(-1);
blockchainSyncIndicator.setPrefWidth(120);
blockchainSyncIndicator.progressProperty().bind(presentationModel.blockchainSyncProgress);
blockchainSyncIndicator.visibleProperty().bind(presentationModel.blockchainSyncIndicatorVisible);
blockchainSyncIndicator.managedProperty().bind(presentationModel.blockchainSyncIndicatorVisible);
ImageView blockchainSyncIcon = new ImageView();
blockchainSyncIcon.setVisible(false);
blockchainSyncIcon.setManaged(false);
presentationModel.blockchainSyncIconId.addListener((ov, oldValue, newValue) -> {
blockchainSyncIcon.setId(newValue);
blockchainSyncIcon.setVisible(true);
blockchainSyncIcon.setManaged(true);
blockchainSyncIndicator.setVisible(false);
blockchainSyncIndicator.setManaged(false);
});
HBox blockchainSyncBox = new HBox();
blockchainSyncBox.setSpacing(10);
blockchainSyncBox.setAlignment(Pos.CENTER);
blockchainSyncBox.setPadding(new Insets(60, 0, 0, 0));
blockchainSyncBox.getChildren().addAll(blockchainSyncLabel, blockchainSyncIndicator);
blockchainSyncBox.getChildren().addAll(blockchainSyncLabel, blockchainSyncIndicator, blockchainSyncIcon);
Label bootstrapStateLabel = new Label();
bootstrapStateLabel.setWrapText(true);
bootstrapStateLabel.setMaxWidth(500);
bootstrapStateLabel.setTextAlignment(TextAlignment.CENTER);
bootstrapStateLabel.textProperty().bind(presentationModel.bootstrapState);
ProgressIndicator bootstrapIndicator = new ProgressIndicator();
bootstrapIndicator.setMaxSize(24, 24);
bootstrapIndicator.progressProperty().bind(presentationModel.bootstrapProgress);
presentationModel.bootstrapFailed.addListener((ov, oldValue, newValue) -> {
if (newValue) {
bootstrapStateLabel.setId("splash-error-state-msg");
bootstrapIndicator.setVisible(false);
Popups.openErrorPopup("Error", "Cannot connect to P2P network. \n\nError message:\n" +
presentationModel.bootstrapErrorMsg.get());
}
});
ProgressIndicator bootstrapIndicator = new ProgressIndicator();
bootstrapIndicator.setMaxSize(24, 24);
bootstrapIndicator.progressProperty().bind(presentationModel.bootstrapProgress);
bootstrapIndicator.visibleProperty().bind(presentationModel.bootstrapIndicatorVisible);
bootstrapIndicator.managedProperty().bind(presentationModel.bootstrapIndicatorVisible);
ImageView bootstrapIcon = new ImageView();
bootstrapIcon.setVisible(false);
bootstrapIcon.setManaged(false);
presentationModel.bootstrapIconId.addListener((ov, oldValue, newValue) -> {
bootstrapIcon.setId(newValue);
bootstrapIcon.setVisible(true);
bootstrapIcon.setManaged(true);
bootstrapIndicator.setVisible(false);
bootstrapIndicator.setManaged(false);
});
HBox bootstrapBox = new HBox();
bootstrapBox.setSpacing(10);
bootstrapBox.setAlignment(Pos.CENTER);
bootstrapBox.setPadding(new Insets(10, 0, 0, 0));
bootstrapBox.getChildren().addAll(bootstrapStateLabel, bootstrapIndicator);
bootstrapBox.getChildren().addAll(bootstrapStateLabel, bootstrapIndicator, bootstrapIcon);
vBox.getChildren().addAll(logo, blockchainSyncBox, bootstrapBox);
return vBox;

View file

@ -152,42 +152,44 @@ class BootstrappedPeerFactory {
});
// We save last successful bootstrap method.
// Reset it to "default" after 5 start ups.
// Reset it to BootstrapState.DIRECT_SUCCESS after 5 start ups.
Object bootstrapCounterObject = persistence.read(this, "bootstrapCounter");
int bootstrapCounter = 0;
if (bootstrapCounterObject instanceof Integer)
bootstrapCounter = (int) bootstrapCounterObject + 1;
if (bootstrapCounter > 5) {
persistence.write(this, "lastSuccessfulBootstrap", "default");
persistence.write(this, "lastSuccessfulBootstrap", BootstrapState.DIRECT_SUCCESS);
bootstrapCounter = 0;
}
persistence.write(this, "bootstrapCounter", bootstrapCounter);
String lastSuccessfulBootstrap = (String) persistence.read(this, "lastSuccessfulBootstrap");
if (lastSuccessfulBootstrap == null)
lastSuccessfulBootstrap = "default";
BootstrapState lastSuccessfulBootstrap = BootstrapState.DIRECT_SUCCESS;
Object lastSuccessfulBootstrapObject = persistence.read(this, "lastSuccessfulBootstrap");
if (lastSuccessfulBootstrapObject instanceof BootstrapState)
lastSuccessfulBootstrap = (BootstrapState) lastSuccessfulBootstrapObject;
else
persistence.write(this, "lastSuccessfulBootstrap", lastSuccessfulBootstrap);
log.debug("lastSuccessfulBootstrap = " + lastSuccessfulBootstrap);
// just temporary while port forwarding is not working
lastSuccessfulBootstrap = "default";
// just temporary always start with trying direct connection
lastSuccessfulBootstrap = BootstrapState.DIRECT_SUCCESS;
switch (lastSuccessfulBootstrap) {
case "relay":
case RELAY_SUCCESS:
bootstrapWithRelay();
break;
case "portForwarding":
case NAT_SUCCESS:
tryPortForwarding();
break;
case "default":
case DIRECT_SUCCESS:
default:
discover();
break;
}
} catch (IOException e) {
setState(BootstrapState.PEER_CREATION, "Cannot create peer with port: " + port + ". Exeption: " + e, false);
settableFuture.setException(e);
handleError(BootstrapState.PEER_CREATION, "Cannot create peer with port: " + port + ". Exeption: " + e);
}
return settableFuture;
@ -202,7 +204,7 @@ class BootstrappedPeerFactory {
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
setState(BootstrapState.DIRECT_SUCCESS, "We are directly connected and visible to other peers.");
bootstrap("default");
bootstrap(BootstrapState.DIRECT_SUCCESS);
}
else {
setState(BootstrapState.DIRECT_NOT_SUCCEEDED, "We are probably behind a NAT and not reachable to " +
@ -213,9 +215,7 @@ class BootstrappedPeerFactory {
@Override
public void exceptionCaught(Throwable t) throws Exception {
setState(BootstrapState.DIRECT_FAILED, "Exception at discover: " + t.getMessage(), false);
peerDHT.shutdown();
settableFuture.setException(t);
handleError(BootstrapState.DIRECT_FAILED, "Exception at discover: " + t.getMessage());
}
});
}
@ -244,9 +244,7 @@ class BootstrappedPeerFactory {
@Override
public void exceptionCaught(Throwable t) throws Exception {
setState(BootstrapState.NAT_FAILED, "Exception at port forwarding: " + t.getMessage(), false);
peerDHT.shutdown();
settableFuture.setException(t);
handleError(BootstrapState.NAT_FAILED, "Exception at port forwarding: " + t.getMessage());
}
});
}
@ -259,24 +257,17 @@ class BootstrappedPeerFactory {
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
setState(BootstrapState.NAT_SUCCESS, "Discover with automatic port forwarding was successful.");
bootstrap("portForwarding");
bootstrap(BootstrapState.NAT_SUCCESS);
}
else {
setState(BootstrapState.NAT_FAILED, "Discover with automatic port forwarding has failed " +
futureDiscover.failedReason(), false);
persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default");
peerDHT.shutdown();
settableFuture.setException(new Exception("Discover with automatic port forwarding failed " +
futureDiscover.failedReason()));
handleError(BootstrapState.NAT_FAILED, "Discover with automatic port forwarding has failed " +
futureDiscover.failedReason());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception {
setState(BootstrapState.NAT_FAILED, "Exception at discover: " + t, false);
persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default");
peerDHT.shutdown();
settableFuture.setException(t);
handleError(BootstrapState.NAT_FAILED, "Exception at discover: " + t.getMessage());
}
});
}
@ -293,50 +284,40 @@ class BootstrappedPeerFactory {
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
setState(BootstrapState.RELAY_SUCCESS, "Bootstrap using relay was successful.");
bootstrap("relay");
bootstrap(BootstrapState.RELAY_SUCCESS);
}
else {
setState(BootstrapState.RELAY_FAILED, "Bootstrap using relay has failed " + futureRelayNAT
.failedReason(), false);
persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default");
futureRelayNAT.shutdown();
peerDHT.shutdown();
settableFuture.setException(new Exception("Bootstrap using relay failed " +
futureRelayNAT.failedReason()));
handleError(BootstrapState.RELAY_FAILED, "Bootstrap using relay has failed " +
futureRelayNAT.failedReason());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception {
setState(BootstrapState.RELAY_FAILED, "Exception at bootstrapWithRelay: " + t, false);
persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", "default");
futureRelayNAT.shutdown();
peerDHT.shutdown();
settableFuture.setException(t);
handleError(BootstrapState.RELAY_FAILED, "Exception at bootstrapWithRelay: " + t.getMessage());
}
});
}
private void bootstrap(String state) {
private void bootstrap(BootstrapState state) {
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(getBootstrapAddress()).start();
futureBootstrap.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
if (futureBootstrap.isSuccess()) {
setState(BootstrapState.DIRECT_SUCCESS, "Bootstrap successful.");
setState(state, "Bootstrap successful.");
persistence.write(BootstrappedPeerFactory.this, "lastSuccessfulBootstrap", state);
settableFuture.set(peerDHT);
}
else {
setState(BootstrapState.DIRECT_NOT_SUCCEEDED, "Bootstrapping failed.");
handleError(BootstrapState.DIRECT_NOT_SUCCEEDED, "Bootstrapping failed. " +
futureBootstrap.failedReason());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception {
setState(BootstrapState.DIRECT_FAILED, "Exception at bootstrap: " + t.getMessage(), false);
peerDHT.shutdown();
settableFuture.setException(t);
handleError(BootstrapState.DIRECT_FAILED, "Exception at bootstrap: " + t.getMessage());
}
});
}
@ -366,4 +347,11 @@ class BootstrappedPeerFactory {
bootstrapState.setMessage(message);
Platform.runLater(() -> this.bootstrapState.set(bootstrapState));
}
private void handleError(BootstrapState state, String errorMessage) {
setState(state, errorMessage, false);
persistence.write(this, "lastSuccessfulBootstrap", BootstrapState.DIRECT_SUCCESS);
peerDHT.shutdown();
settableFuture.setException(new Exception(errorMessage));
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB