improved startup, add splash screen, make it smoother

This commit is contained in:
Manfred Karrer 2014-08-11 13:40:16 +02:00
parent 89d5c9ee86
commit 17697afa24
17 changed files with 387 additions and 247 deletions

View File

@ -21,13 +21,9 @@ import java.util.Arrays;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -47,8 +43,7 @@ public class BitSquare extends Application
public static void main(String[] args)
{
Profiler.init();
Profiler.printMsgWithTime("main called");
log.debug("Startup: main " + Arrays.asList(args).toString());
Profiler.printMsgWithTime("BitSquare.main called with args " + Arrays.asList(args).toString());
if (args != null && args.length > 0) APP_NAME = args[0];
launch(args);
@ -67,7 +62,7 @@ public class BitSquare extends Application
@Override
public void start(Stage primaryStage) throws IOException
{
Profiler.printMsgWithTime("start called");
Profiler.printMsgWithTime("BitSquare.start called");
BitSquare.primaryStage = primaryStage;
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable)));
@ -81,7 +76,7 @@ public class BitSquare extends Application
walletFacade = injector.getInstance(WalletFacade.class);
messageFacade = injector.getInstance(MessageFacade.class);
Profiler.printMsgWithTime("Startup: messageFacade, walletFacade inited");
Profiler.printMsgWithTime("BitSquare: messageFacade, walletFacade created");
// apply stored data
final User user = injector.getInstance(User.class);
@ -100,14 +95,9 @@ public class BitSquare extends Application
GuiceFXMLLoader.setInjector(injector);
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()));
final Parent mainView = loader.load();
BorderPane rootPane = new BorderPane();
rootPane.setTop(getMenuBar());
rootPane.setCenter(mainView);
final Scene scene = new Scene(rootPane, 1000, 750);
scene.getStylesheets().setAll(getClass().getResource("/io/bitsquare/gui/bitsquare.css").toExternalForm(),
getClass().getResource("/io/bitsquare/gui/validation.css").toExternalForm());
final Parent view = loader.load();
final Scene scene = new Scene(view, 1000, 750);
scene.getStylesheets().setAll(getClass().getResource("/io/bitsquare/gui/bitsquare.css").toExternalForm());
setupCloseHandlers(primaryStage, scene);
@ -117,7 +107,7 @@ public class BitSquare extends Application
primaryStage.show();
Profiler.printMsgWithTime("Startup: primaryStage.show");
Profiler.printMsgWithTime("BitSquare: start finished");
}
private void setupCloseHandlers(Stage primaryStage, Scene scene)
@ -130,34 +120,6 @@ public class BitSquare extends Application
});
}
private MenuBar getMenuBar()
{
MenuBar menuBar = new MenuBar();
// on mac we could placemenu bar in the systems menu
// menuBar.setUseSystemMenuBar(true);
menuBar.setUseSystemMenuBar(false);
Menu fileMenu = new Menu("_File");
fileMenu.setMnemonicParsing(true);
MenuItem backupMenuItem = new MenuItem("Backup wallet");
fileMenu.getItems().addAll(backupMenuItem);
Menu settingsMenu = new Menu("_Settings");
settingsMenu.setMnemonicParsing(true);
MenuItem changePwMenuItem = new MenuItem("Change password");
settingsMenu.getItems().addAll(changePwMenuItem);
Menu helpMenu = new Menu("_Help");
helpMenu.setMnemonicParsing(true);
MenuItem faqMenuItem = new MenuItem("FAQ");
MenuItem forumMenuItem = new MenuItem("Forum");
helpMenu.getItems().addAll(faqMenuItem, forumMenuItem);
menuBar.getMenus().setAll(fileMenu, settingsMenu, helpMenu);
return menuBar;
}
@Override
public void stop() throws Exception
{

View File

@ -8,7 +8,8 @@ import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.components.NetworkSyncPane;
import io.bitsquare.gui.market.MarketController;
import io.bitsquare.gui.orders.OrdersController;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.gui.util.Profiler;
import io.bitsquare.gui.util.Transitions;
import io.bitsquare.msg.BootstrapListener;
import io.bitsquare.msg.MessageFacade;
@ -20,24 +21,29 @@ import io.bitsquare.util.AWTSystemTray;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.*;
import javafx.util.StringConverter;
import javax.inject.Inject;
import net.tomp2p.peers.PeerAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Holds the splash screen and the application views.
* It builds up all the views and initializes the facades.
* We use a sequence of Platform.runLater cascaded calls to make the startup more smooth, otherwise the rendering is frozen for too long.
* Pre-loading of views is not implemented yet, and after a quick test it seemed that it does not give much improvements.
*/
public class MainController implements Initializable, NavigationController
{
private static final Logger log = LoggerFactory.getLogger(MainController.class);
@ -49,7 +55,7 @@ public class MainController implements Initializable, NavigationController
private final TradeManager tradeManager;
private final Persistence persistence;
private final ToggleGroup toggleGroup = new ToggleGroup();
private final ViewBuilder viewBuilder;
private ChildController controller;
private ToggleButton prevToggleButton;
@ -59,18 +65,7 @@ public class MainController implements Initializable, NavigationController
private boolean messageFacadeInited;
private boolean walletFacadeInited;
@FXML
private Pane contentPane;
@FXML
private HBox leftNavPane, rightNavPane;
@FXML
private ProgressBar loadingBar;
@FXML
private AnchorPane rootPane;
@FXML
private Label loadingLabel;
@FXML
private NetworkSyncPane networkSyncPane;
@FXML private BorderPane root;
///////////////////////////////////////////////////////////////////////////////////////////
@ -86,6 +81,8 @@ public class MainController implements Initializable, NavigationController
this.tradeManager = tradeManager;
this.persistence = persistence;
viewBuilder = new ViewBuilder();
MainController.INSTANCE = this;
}
@ -107,49 +104,14 @@ public class MainController implements Initializable, NavigationController
@Override
public void initialize(URL url, ResourceBundle rb)
{
messageFacade.init(new BootstrapListener()
{
@Override
public void onCompleted()
{
messageFacadeInited = true;
if (walletFacadeInited) initialisationDone();
}
@Override
public void onFailed(Throwable throwable)
{
}
});
walletFacade.addDownloadListener(new WalletFacade.DownloadListener()
{
@Override
public void progress(double percent)
{
networkSyncPane.setProgress(percent);
}
@Override
public void doneDownload()
{
networkSyncPane.doneDownload();
}
});
walletFacade.initialize(() -> {
walletFacadeInited = true;
if (messageFacadeInited) initialisationDone();
});
tradeManager.addTakeOfferRequestListener(this::onTakeOfferRequested);
Profiler.printMsgWithTime("MainController.initialize");
Platform.runLater(() -> viewBuilder.buildSplashScreen(root, this));
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: NavigationController
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public ChildController navigateToView(NavigationItem navigationItem)
{
@ -181,57 +143,69 @@ public class MainController implements Initializable, NavigationController
}
private ChildController loadView(NavigationItem navigationItem)
{
if (controller != null)
{
controller.cleanup();
}
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
try
{
final Node view = loader.load();
contentPane.getChildren().setAll(view);
controller = loader.getController();
controller.setNavigationController(this);
} catch (IOException e)
{
e.printStackTrace();
log.error("Loading view failed. " + navigationItem.getFxmlUrl());
}
return controller;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
// Startup Handlers
///////////////////////////////////////////////////////////////////////////////////////////
private void initialisationDone()
public void onViewInitialized()
{
addNavigation();
Transitions.fadeOutAndRemove(loadingLabel);
Transitions.fadeOutAndRemove(loadingBar);
Transitions.fadeIn(leftNavPane);
Transitions.fadeIn(rightNavPane);
Transitions.fadeIn(contentPane);
NavigationItem selectedNavigationItem = (NavigationItem) persistence.read(this, "selectedNavigationItem");
if (selectedNavigationItem == null)
{
selectedNavigationItem = NavigationItem.HOME;
}
navigateToView(selectedNavigationItem);
Profiler.printMsgWithTime("MainController.onViewInitialized");
Platform.runLater(this::initFacades);
}
private void onFacadesInitialised()
{
Profiler.printMsgWithTime("MainController.onFacadesInitialised");
// never called on regtest
walletFacade.addDownloadListener(new WalletFacade.DownloadListener()
{
@Override
public void progress(double percent)
{
viewBuilder.loadingLabel.setText("Synchronise with network...");
}
@Override
public void doneDownload()
{
viewBuilder.loadingLabel.setText("Synchronise with network done.");
}
});
tradeManager.addTakeOfferRequestListener(this::onTakeOfferRequested);
Platform.runLater(this::addNavigation);
}
private void onNavigationAdded()
{
Profiler.printMsgWithTime("MainController.onNavigationAdded");
Platform.runLater(this::loadContentView);
}
private void onContentViewLoaded()
{
Profiler.printMsgWithTime("MainController.onContentViewLoaded");
root.setId("main-view");
Platform.runLater(this::fadeOutSplash);
}
private void fadeOutSplash()
{
Profiler.printMsgWithTime("MainController.fadeOutSplash");
Transitions.blurOutAndRemove(viewBuilder.splashVBox);
Transitions.fadeIn(viewBuilder.menuBar);
Transitions.fadeIn(viewBuilder.anchorPane);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Handlers
///////////////////////////////////////////////////////////////////////////////////////////
//TODO make ordersButton also reacting to jump to pending tab
private void onTakeOfferRequested(String offerId, PeerAddress sender)
{
final Button alertButton = new Button("", Icons.getIconImageView(Icons.MSG_ALERT));
final Button alertButton = new Button("", ImageUtil.getIconImageView(ImageUtil.MSG_ALERT));
alertButton.setId("nav-alert-button");
alertButton.relocate(36, 19);
alertButton.setOnAction((e) -> {
@ -244,36 +218,103 @@ public class MainController implements Initializable, NavigationController
AWTSystemTray.setAlert();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private startup methods
///////////////////////////////////////////////////////////////////////////////////////////
private void initFacades()
{
Profiler.printMsgWithTime("MainController.initFacades");
messageFacade.init(new BootstrapListener()
{
@Override
public void onCompleted()
{
messageFacadeInited = true;
if (walletFacadeInited) onFacadesInitialised();
}
@Override
public void onFailed(Throwable throwable)
{
log.error(throwable.toString());
}
});
walletFacade.initialize(() -> {
walletFacadeInited = true;
if (messageFacadeInited) onFacadesInitialised();
});
}
private void addNavigation()
{
homeButton = addNavButton(leftNavPane, "Overview", NavigationItem.HOME);
buyButton = addNavButton(leftNavPane, "Buy BTC", NavigationItem.BUY);
sellButton = addNavButton(leftNavPane, "Sell BTC", NavigationItem.SELL);
Profiler.printMsgWithTime("MainController.addNavigation");
homeButton = addNavButton(viewBuilder.leftNavPane, "Overview", NavigationItem.HOME);
buyButton = addNavButton(viewBuilder.leftNavPane, "Buy BTC", NavigationItem.BUY);
sellButton = addNavButton(viewBuilder.leftNavPane, "Sell BTC", NavigationItem.SELL);
ordersButtonButtonHolder = new Pane();
ordersButton = addNavButton(ordersButtonButtonHolder, "Orders", NavigationItem.ORDERS);
leftNavPane.getChildren().add(ordersButtonButtonHolder);
viewBuilder.leftNavPane.getChildren().add(ordersButtonButtonHolder);
fundsButton = addNavButton(leftNavPane, "Funds", NavigationItem.FUNDS);
fundsButton = addNavButton(viewBuilder.leftNavPane, "Funds", NavigationItem.FUNDS);
final Pane msgButtonHolder = new Pane();
msgButton = addNavButton(msgButtonHolder, "Message", NavigationItem.MSG);
leftNavPane.getChildren().add(msgButtonHolder);
viewBuilder.leftNavPane.getChildren().add(msgButtonHolder);
addBalanceInfo(rightNavPane);
addAccountComboBox(rightNavPane);
addBalanceInfo(viewBuilder.rightNavPane);
addAccountComboBox(viewBuilder.rightNavPane);
settingsButton = addNavButton(rightNavPane, "Settings", NavigationItem.SETTINGS);
settingsButton = addNavButton(viewBuilder.rightNavPane, "Settings", NavigationItem.SETTINGS);
Platform.runLater(this::onNavigationAdded);
}
private void loadContentView()
{
Profiler.printMsgWithTime("MainController.loadContentView");
NavigationItem selectedNavigationItem = (NavigationItem) persistence.read(this, "selectedNavigationItem");
if (selectedNavigationItem == null)
selectedNavigationItem = NavigationItem.BUY;
navigateToView(selectedNavigationItem);
Platform.runLater(this::onContentViewLoaded);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private ChildController loadView(NavigationItem navigationItem)
{
if (controller != null)
controller.cleanup();
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()));
try
{
final Node view = loader.load();
viewBuilder.contentPane.getChildren().setAll(view);
controller = loader.getController();
controller.setNavigationController(this);
} catch (IOException e)
{
e.printStackTrace();
log.error("Loading view failed. " + navigationItem.getFxmlUrl());
}
return controller;
}
private ToggleButton addNavButton(Pane parent, String title, NavigationItem navigationItem)
{
final Pane pane = new Pane();
pane.setPrefSize(50, 50);
final ToggleButton toggleButton = new ToggleButton("", Icons.getIconImageView(navigationItem.getIcon()));
final ToggleButton toggleButton = new ToggleButton("", ImageUtil.getIconImageView(navigationItem.getIcon()));
toggleButton.setToggleGroup(toggleGroup);
toggleButton.setId("nav-button");
toggleButton.setPrefSize(50, 50);
@ -283,7 +324,7 @@ public class MainController implements Initializable, NavigationController
((ImageView) (prevToggleButton.getGraphic())).setImage(prevToggleButtonIcon);
}
prevToggleButtonIcon = ((ImageView) (toggleButton.getGraphic())).getImage();
((ImageView) (toggleButton.getGraphic())).setImage(Icons.getIconImage(navigationItem.getActiveIcon()));
((ImageView) (toggleButton.getGraphic())).setImage(ImageUtil.getIconImage(navigationItem.getActiveIcon()));
controller = loadView(navigationItem);
@ -313,7 +354,7 @@ public class MainController implements Initializable, NavigationController
{
final TextField balanceTextField = new TextField();
balanceTextField.setEditable(false);
balanceTextField.setPrefWidth(90);
balanceTextField.setPrefWidth(110);
balanceTextField.setId("nav-balance-label");
balanceTextField.setText(walletFacade.getWalletBalance().toFriendlyString());
walletFacade.addBalanceListener(new BalanceListener()
@ -325,12 +366,9 @@ public class MainController implements Initializable, NavigationController
}
});
final Label balanceCurrencyLabel = new Label("BTC");
balanceCurrencyLabel.setPadding(new Insets(6, 0, 0, 0));
final HBox hBox = new HBox();
hBox.setSpacing(2);
hBox.getChildren().setAll(balanceTextField, balanceCurrencyLabel);
hBox.getChildren().setAll(balanceTextField);
final Label titleLabel = new Label("Balance");
titleLabel.setMouseTransparent(true);
@ -382,4 +420,134 @@ public class MainController implements Initializable, NavigationController
parent.getChildren().add(vBox);
}
}
}
}
class ViewBuilder
{
HBox leftNavPane, rightNavPane;
AnchorPane contentPane;
NetworkSyncPane networkSyncPane;
StackPane stackPane;
AnchorPane anchorPane;
VBox splashVBox;
MenuBar menuBar;
BorderPane root;
Label loadingLabel;
void buildSplashScreen(BorderPane root, MainController controller)
{
Profiler.printMsgWithTime("MainController.ViewBuilder.buildSplashScreen");
this.root = root;
stackPane = new StackPane();
splashVBox = getSplashScreen();
stackPane.getChildren().add(splashVBox);
root.setCenter(stackPane);
menuBar = getMenuBar();
root.setTop(menuBar);
Platform.runLater(() -> buildContentView(controller));
}
void buildContentView(MainController controller)
{
Profiler.printMsgWithTime("MainController.ViewBuilder.buildContentView");
anchorPane = getContentScreen();
stackPane.getChildren().add(anchorPane);
Platform.runLater(controller::onViewInitialized);
}
AnchorPane getContentScreen()
{
AnchorPane anchorPane = new AnchorPane();
anchorPane.setId("content-pane");
leftNavPane = new HBox();
leftNavPane.setAlignment(Pos.CENTER);
leftNavPane.setSpacing(10);
AnchorPane.setLeftAnchor(leftNavPane, 0d);
AnchorPane.setTopAnchor(leftNavPane, 0d);
rightNavPane = new HBox();
rightNavPane.setAlignment(Pos.CENTER);
rightNavPane.setSpacing(10);
AnchorPane.setRightAnchor(rightNavPane, 10d);
AnchorPane.setTopAnchor(rightNavPane, 0d);
contentPane = new AnchorPane();
contentPane.setId("content-pane");
AnchorPane.setLeftAnchor(contentPane, 0d);
AnchorPane.setRightAnchor(contentPane, 0d);
AnchorPane.setTopAnchor(contentPane, 60d);
AnchorPane.setBottomAnchor(contentPane, 20d);
networkSyncPane = new NetworkSyncPane();
networkSyncPane.setSpacing(10);
networkSyncPane.setPrefHeight(20);
AnchorPane.setLeftAnchor(networkSyncPane, 0d);
AnchorPane.setBottomAnchor(networkSyncPane, 0d);
anchorPane.getChildren().addAll(leftNavPane, rightNavPane, contentPane, networkSyncPane);
anchorPane.setOpacity(0);
return anchorPane;
}
VBox getSplashScreen()
{
VBox splashVBox = new VBox();
splashVBox.setAlignment(Pos.CENTER);
splashVBox.setSpacing(10);
ImageView logo = ImageUtil.getIconImageView(ImageUtil.SPLASH_LOGO);
logo.setFitWidth(270);
logo.setFitHeight(200);
ImageView titleLabel = ImageUtil.getIconImageView(ImageUtil.SPLASH_LABEL);
titleLabel.setFitWidth(300);
titleLabel.setFitHeight(79);
Label subTitle = new Label("The P2P Fiat-Bitcoin Exchange");
subTitle.setAlignment(Pos.CENTER);
subTitle.setId("logo-sub-title-label");
loadingLabel = new Label("Initializing...");
loadingLabel.setAlignment(Pos.CENTER);
loadingLabel.setPadding(new Insets(80, 0, 0, 0));
splashVBox.getChildren().addAll(logo, titleLabel, subTitle, loadingLabel);
return splashVBox;
}
MenuBar getMenuBar()
{
MenuBar menuBar = new MenuBar();
// on mac we could place menu bar in the systems menu
// menuBar.setUseSystemMenuBar(true);
menuBar.setUseSystemMenuBar(false);
Menu fileMenu = new Menu("_File");
fileMenu.setMnemonicParsing(true);
MenuItem backupMenuItem = new MenuItem("Backup wallet");
fileMenu.getItems().addAll(backupMenuItem);
Menu settingsMenu = new Menu("_Settings");
settingsMenu.setMnemonicParsing(true);
MenuItem changePwMenuItem = new MenuItem("Change password");
settingsMenu.getItems().addAll(changePwMenuItem);
Menu helpMenu = new Menu("_Help");
helpMenu.setMnemonicParsing(true);
MenuItem faqMenuItem = new MenuItem("FAQ");
MenuItem forumMenuItem = new MenuItem("Forum");
helpMenu.getItems().addAll(faqMenuItem, forumMenuItem);
menuBar.getMenus().setAll(fileMenu, settingsMenu, helpMenu);
menuBar.setOpacity(0);
return menuBar;
}
}

View File

@ -1,16 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import io.bitsquare.gui.components.NetworkSyncPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="rootPane" id="root-pane" fx:controller="io.bitsquare.gui.MainController" stylesheets="/io/bitsquare/gui/bitsquare.css"
<?import javafx.scene.layout.BorderPane?>
<BorderPane fx:id="root" id="splash" fx:controller="io.bitsquare.gui.MainController" prefHeight="750" prefWidth="1000" stylesheets="/io/bitsquare/gui/bitsquare.css"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<HBox fx:id="leftNavPane" opacity="0" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/>
<HBox fx:id="rightNavPane" opacity="0" spacing="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="0"/>
<AnchorPane fx:id="contentPane" id="content-pane" opacity="0" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="60"/>
<NetworkSyncPane fx:id="networkSyncPane" spacing="10" prefHeight="20" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"/>
<ProgressBar fx:id="loadingBar" progress="-1" prefHeight="20" prefWidth="200" AnchorPane.topAnchor="250" AnchorPane.leftAnchor="300"/>
<Label fx:id="loadingLabel" text="Loading..." textAlignment="CENTER" alignment="CENTER" prefHeight="20" prefWidth="200" AnchorPane.topAnchor="280" AnchorPane.leftAnchor="300"/>
</AnchorPane>
</BorderPane>

View File

@ -1,17 +1,17 @@
package io.bitsquare.gui;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
public enum NavigationItem
{
MAIN("/io/bitsquare/gui/MainView.fxml"),
HOME("/io/bitsquare/gui/home/HomeView.fxml", Icons.HOME, Icons.HOME_ACTIVE),
BUY("/io/bitsquare/gui/market/MarketView.fxml", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE),
SELL("/io/bitsquare/gui/market/MarketView.fxml", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE),
ORDERS("/io/bitsquare/gui/orders/OrdersView.fxml", Icons.ORDERS, Icons.ORDERS_ACTIVE),
FUNDS("/io/bitsquare/gui/funds/FundsView.fxml", Icons.FUNDS, Icons.FUNDS_ACTIVE),
MSG("/io/bitsquare/gui/msg/MsgView.fxml", Icons.MSG, Icons.MSG_ACTIVE),
SETTINGS("/io/bitsquare/gui/settings/SettingsView.fxml", Icons.SETTINGS, Icons.SETTINGS_ACTIVE),
HOME("/io/bitsquare/gui/home/HomeView.fxml", ImageUtil.HOME, ImageUtil.HOME_ACTIVE),
BUY("/io/bitsquare/gui/market/MarketView.fxml", ImageUtil.NAV_BUY, ImageUtil.NAV_BUY_ACTIVE),
SELL("/io/bitsquare/gui/market/MarketView.fxml", ImageUtil.NAV_SELL, ImageUtil.NAV_SELL_ACTIVE),
ORDERS("/io/bitsquare/gui/orders/OrdersView.fxml", ImageUtil.ORDERS, ImageUtil.ORDERS_ACTIVE),
FUNDS("/io/bitsquare/gui/funds/FundsView.fxml", ImageUtil.FUNDS, ImageUtil.FUNDS_ACTIVE),
MSG("/io/bitsquare/gui/msg/MsgView.fxml", ImageUtil.MSG, ImageUtil.MSG_ACTIVE),
SETTINGS("/io/bitsquare/gui/settings/SettingsView.fxml", ImageUtil.SETTINGS, ImageUtil.SETTINGS_ACTIVE),
ORDER_BOOK("/io/bitsquare/gui/market/orderbook/OrderBookView.fxml"),
CREATE_OFFER("/io/bitsquare/gui/market/createOffer/CreateOfferView.fxml"),

View File

@ -1,4 +1,13 @@
#root-pane {
#splash {
-fx-background-color: #ffffff;
}
#logo-sub-title-label{
-fx-font-weight: bold;
-fx-font-size: 24;
}
#main-view {
-fx-background-color: #dddddd;
}
@ -53,7 +62,7 @@
.text-field:readonly {
-fx-text-fill: #000000;
-fx-background-color: #FAFAFA;
-fx-background-color: #FBFBFB;
}
#feedback-text {

View File

@ -15,7 +15,7 @@ import io.bitsquare.gui.market.createOffer.CreateOfferController;
import io.bitsquare.gui.market.trade.TakerOfferController;
import io.bitsquare.gui.popups.Popups;
import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.locale.Localisation;
@ -65,8 +65,8 @@ public class OrderBookController implements Initializable, ChildController
private final Settings settings;
private final Persistence persistence;
private final Image buyIcon = Icons.getIconImage(Icons.BUY);
private final Image sellIcon = Icons.getIconImage(Icons.SELL);
private final Image buyIcon = ImageUtil.getIconImage(ImageUtil.BUY);
private final Image sellIcon = ImageUtil.getIconImage(ImageUtil.SELL);
@FXML
public AnchorPane holderPane;
@FXML
@ -433,7 +433,7 @@ public class OrderBookController implements Initializable, ChildController
if (offer.getMessagePublicKey().equals(user.getMessagePublicKey()))
{
icon = Icons.getIconImage(Icons.REMOVE);
icon = ImageUtil.getIconImage(ImageUtil.REMOVE);
title = "Remove";
button.setOnAction(event -> removeOffer(orderBookListItem.getOffer()));
}
@ -499,7 +499,7 @@ public class OrderBookController implements Initializable, ChildController
Country country = orderBookListItem.getOffer().getBankAccountCountry();
try
{
hBox.getChildren().add(Icons.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png"));
hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png"));
} catch (Exception e)
{

View File

@ -3,7 +3,7 @@ package io.bitsquare.gui.orders.offer;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.trade.Offer;
import io.bitsquare.trade.TradeManager;
import java.net.URL;
@ -172,7 +172,7 @@ public class OfferController implements Initializable, ChildController, Hibernat
{
return new TableCell<String, OfferListItem>()
{
final ImageView iconView = Icons.getIconImageView(Icons.REMOVE);
final ImageView iconView = ImageUtil.getIconImageView(ImageUtil.REMOVE);
final Button button = new Button();
{

View File

@ -14,7 +14,7 @@ import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.util.BitSquareFormatter;
import io.bitsquare.gui.util.ConfidenceDisplay;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.Localisation;
import io.bitsquare.trade.Direction;
@ -52,8 +52,8 @@ public class PendingTradeController implements Initializable, ChildController, H
private Trade currentTrade;
private NavigationController navigationController;
private Image buyIcon = Icons.getIconImage(Icons.BUY);
private Image sellIcon = Icons.getIconImage(Icons.SELL);
private Image buyIcon = ImageUtil.getIconImage(ImageUtil.BUY);
private Image sellIcon = ImageUtil.getIconImage(ImageUtil.SELL);
private ConfidenceDisplay confidenceDisplay;
@FXML
@ -390,7 +390,7 @@ public class PendingTradeController implements Initializable, ChildController, H
Country country = tradesTableItem.getTrade().getOffer().getBankAccountCountry();
try
{
hBox.getChildren().add(Icons.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png"));
hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png"));
} catch (Exception e)
{

View File

@ -10,7 +10,7 @@ import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.util.BitSquareValidator;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.*;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.Settings;
@ -358,7 +358,7 @@ public class SettingsController implements Initializable, ChildController, Navig
final HBox hBox = new HBox();
final Label label = new Label();
final Button removeButton = new Button();
final ImageView icon = Icons.getIconImageView(Icons.REMOVE);
final ImageView icon = ImageUtil.getIconImageView(ImageUtil.REMOVE);
{
label.setPrefWidth(565);
@ -443,7 +443,7 @@ public class SettingsController implements Initializable, ChildController, Navig
final HBox hBox = new HBox();
final Label label = new Label();
final Button removeButton = new Button();
final ImageView icon = Icons.getIconImageView(Icons.REMOVE);
final ImageView icon = ImageUtil.getIconImageView(ImageUtil.REMOVE);
{
label.setPrefWidth(565);
@ -513,7 +513,7 @@ public class SettingsController implements Initializable, ChildController, Navig
final HBox hBox = new HBox();
final Label label = new Label();
final Button removeButton = new Button();
final ImageView icon = Icons.getIconImageView(Icons.REMOVE);
final ImageView icon = ImageUtil.getIconImageView(ImageUtil.REMOVE);
{
label.setPrefWidth(565);

View File

@ -3,8 +3,11 @@ package io.bitsquare.gui.util;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class Icons
public class ImageUtil
{
public static final String SPLASH_LOGO = "/images/logo_200_270.png";
public static final String SPLASH_LABEL = "/images/bitsquare_logo_label_300_69.png";
public static final String SYS_TRAY = "/images/systemTrayIcon.png";
public static final String SYS_TRAY_ALERT = "/images/systemTrayAlertIcon.png";
@ -32,12 +35,12 @@ public class Icons
public static Image getIconImage(String iconName)
{
return new Image(Icons.class.getResourceAsStream(iconName));
return new Image(ImageUtil.class.getResourceAsStream(iconName));
}
public static ImageView getIconImageView(String iconName)
{
return new ImageView(new Image(Icons.class.getResourceAsStream(iconName)));
return new ImageView(new Image(ImageUtil.class.getResourceAsStream(iconName)));
}
}

View File

@ -6,74 +6,104 @@ import javafx.scene.Node;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.Pane;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkState;
@SuppressWarnings("WeakerAccess")
public class Transitions
{
private static final Logger log = LoggerFactory.getLogger(Transitions.class);
public static final int UI_ANIMATION_TIME = 800;
public static void fadeIn(Node ui)
public static void fadeIn(Node node)
{
fadeIn(ui, UI_ANIMATION_TIME);
fadeIn(node, UI_ANIMATION_TIME);
}
@SuppressWarnings("SameParameterValue")
public static void fadeIn(Node ui, int time)
public static void fadeIn(Node node, int duration)
{
FadeTransition ft = new FadeTransition(Duration.millis(time), ui);
FadeTransition ft = new FadeTransition(Duration.millis(duration), node);
ft.setFromValue(0.0);
ft.setToValue(1.0);
ft.play();
}
public static Animation fadeOut(Node ui)
public static Animation fadeOut(Node node)
{
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME), ui);
ft.setFromValue(ui.getOpacity());
return fadeOut(node, UI_ANIMATION_TIME);
}
public static Animation fadeOut(Node node, int duration)
{
FadeTransition ft = new FadeTransition(Duration.millis(duration), node);
ft.setFromValue(node.getOpacity());
ft.setToValue(0.0);
ft.play();
return ft;
}
@SuppressWarnings("UnusedReturnValue")
public static Animation fadeOutAndRemove(Node ui)
public static Animation fadeOutAndRemove(Node node)
{
Animation animation = fadeOut(ui);
animation.setOnFinished(actionEvent -> ((Pane) (ui.getParent())).getChildren().remove(ui));
return fadeOutAndRemove(node, UI_ANIMATION_TIME);
}
public static Animation fadeOutAndRemove(Node node, int duration)
{
Animation animation = fadeOut(node, duration);
animation.setOnFinished(actionEvent -> {
((Pane) (node.getParent())).getChildren().remove(node);
Profiler.printMsgWithTime("fadeOutAndRemove");
});
return animation;
}
public static Timeline blurOutAndRemove(Node node)
{
return blurOutAndRemove(node, UI_ANIMATION_TIME);
}
public static Timeline blurOutAndRemove(Node node, int duration)
{
Timeline timeline = blurOut(node, duration);
timeline.setOnFinished(actionEvent -> {
((Pane) (node.getParent())).getChildren().remove(node);
Profiler.printMsgWithTime("blurOutAndRemove");
});
return timeline;
}
public static void blurOut(Node node)
{
blurOut(node, UI_ANIMATION_TIME);
}
@SuppressWarnings("SameParameterValue")
public static void blurOut(Node node, int time)
public static Timeline blurOut(Node node, int duration)
{
GaussianBlur blur = new GaussianBlur(0.0);
node.setEffect(blur);
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 10.0);
KeyFrame kf = new KeyFrame(Duration.millis(time), kv);
KeyFrame kf = new KeyFrame(Duration.millis(duration), kv);
timeline.getKeyFrames().add(kf);
timeline.play();
return timeline;
}
public static void blurIn(Node node)
{
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline timeline = new Timeline();
Timeline durationline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME), kv);
timeline.getKeyFrames().add(kf);
timeline.setOnFinished(actionEvent -> node.setEffect(null));
timeline.play();
durationline.getKeyFrames().add(kf);
durationline.setOnFinished(actionEvent -> node.setEffect(null));
durationline.play();
}
public static void checkGuiThread()

View File

@ -1,22 +0,0 @@
.text-field.validation_error, .text-area.validation_error .content, .date-picker.validation_error > .text-field {
-fx-effect: innershadow(three-pass-box, red, 12 , 0.5, 1, 1);
}
#error-msg-item .label {
-fx-text-fill: white;
}
#error-msg-item:focused {
-fx-background-color: #B80000;
}
#error-msg-item:focused .label {
-fx-text-fill: white;
}
#error-msg {
-fx-background-color: #B80000;
-fx-padding: 0;
-fx-background-radius: 4 4 4 4;
}

View File

@ -258,7 +258,7 @@ public class MessageFacade implements MessageBroker
Platform.runLater(() -> orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOffersReceived(futureGet.dataMap(), baseFuture.isSuccess())));
if (baseFuture.isSuccess())
{
log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey + ", values: " + futureGet.dataMap() + "]");
//log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey + ", values: " + futureGet.dataMap() + "]");
}
else
{

View File

@ -2,7 +2,7 @@ package io.bitsquare.util;
import io.bitsquare.BitSquare;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.ImageUtil;
import java.awt.*;
import javafx.application.Platform;
import javafx.stage.Stage;
@ -27,7 +27,7 @@ public class AWTSystemTray
Platform.setImplicitExit(false);
SystemTray systemTray = SystemTray.getSystemTray();
trayIcon = new TrayIcon(getImage(Icons.SYS_TRAY));
trayIcon = new TrayIcon(getImage(ImageUtil.SYS_TRAY));
trayIcon.setToolTip("BitSquare P2P Fiat-Bitcoin exchange");
PopupMenu popupMenu = new PopupMenu();
@ -78,12 +78,12 @@ public class AWTSystemTray
public static void setAlert()
{
trayIcon.setImage(getImage(Icons.SYS_TRAY_ALERT));
trayIcon.setImage(getImage(ImageUtil.SYS_TRAY_ALERT));
}
public static void unSetAlert()
{
trayIcon.setImage(getImage(Icons.SYS_TRAY));
trayIcon.setImage(getImage(ImageUtil.SYS_TRAY));
}
public static void setStageHidden()

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB