Introduce @FxmlView, replace Navigation.Item

This commit is contained in:
Chris Beams 2014-11-25 00:12:57 +01:00
parent 5a5bfd0826
commit 70d9577e32
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
41 changed files with 645 additions and 601 deletions

View file

@ -19,9 +19,9 @@ package io.bitsquare.app.gui;
import io.bitsquare.BitsquareException; import io.bitsquare.BitsquareException;
import io.bitsquare.account.AccountSettings; import io.bitsquare.account.AccountSettings;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.SystemTray; import io.bitsquare.gui.SystemTray;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -97,7 +97,7 @@ public class BitsquareApp extends Application {
// load the main view and create the main scene // load the main view and create the main scene
ViewLoader viewLoader = injector.getInstance(CachingViewLoader.class); ViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
View view = viewLoader.load(FxmlView.MAIN.getLocation()); View view = viewLoader.load(MainView.class);
Scene scene = new Scene((Parent) view.getRoot(), 1000, 600); Scene scene = new Scene((Parent) view.getRoot(), 1000, 600);
scene.getStylesheets().setAll( scene.getStylesheets().setAll(

View file

@ -1,120 +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.gui;
import io.bitsquare.BitsquareException;
import java.net.URL;
public enum FxmlView {
// ~ Application ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MAIN("/io/bitsquare/gui/main/MainView.fxml"),
// ~ Main menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HOME("/io/bitsquare/gui/main/home/HomeView.fxml", "Overview"),
BUY("/io/bitsquare/gui/main/trade/BuyView.fxml", "Buy BTC"),
SELL("/io/bitsquare/gui/main/trade/SellView.fxml", "Sell BTC"),
PORTFOLIO("/io/bitsquare/gui/main/portfolio/PortfolioView.fxml", "Portfolio"),
FUNDS("/io/bitsquare/gui/main/funds/FundsView.fxml", "Funds"),
MSG("/io/bitsquare/gui/main/msg/MsgView.fxml", "Messages"),
SETTINGS("/io/bitsquare/gui/main/settings/SettingsView.fxml", "Settings"),
ACCOUNT("/io/bitsquare/gui/main/account/AccountView.fxml", "Account"),
// ~ Sub menus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// buy/sell (trade)
OFFER_BOOK("/io/bitsquare/gui/main/trade/offerbook/OfferBookView.fxml"),
CREATE_OFFER("/io/bitsquare/gui/main/trade/createoffer/CreateOfferView.fxml"),
TAKE_OFFER("/io/bitsquare/gui/main/trade/takeoffer/TakeOfferView.fxml"),
// portfolio
OFFERS("/io/bitsquare/gui/main/portfolio/offer/OffersView.fxml"),
PENDING_TRADES("/io/bitsquare/gui/main/portfolio/pending/PendingTradesView.fxml"),
CLOSED_TRADES("/io/bitsquare/gui/main/portfolio/closed/ClosedTradesView.fxml"),
// funds
WITHDRAWAL("/io/bitsquare/gui/main/funds/withdrawal/WithdrawalView.fxml"),
TRANSACTIONS("/io/bitsquare/gui/main/funds/transactions/TransactionsView.fxml"),
// settings
PREFERENCES("/io/bitsquare/gui/main/settings/application/PreferencesView.fxml"),
NETWORK_SETTINGS("/io/bitsquare/gui/main/settings/network/NetworkSettingsView.fxml"),
// account
ACCOUNT_SETUP("/io/bitsquare/gui/main/account/setup/AccountSetupWizard.fxml"),
ACCOUNT_SETTINGS("/io/bitsquare/gui/main/account/settings/AccountSettingsView.fxml"),
ARBITRATOR_SETTINGS("/io/bitsquare/gui/main/account/arbitrator/ArbitratorSettingsView.fxml"),
// ~ Content in sub menus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// account content
SEED_WORDS("/io/bitsquare/gui/main/account/content/seedwords/SeedWordsView.fxml"),
ADD_PASSWORD("/io/bitsquare/gui/main/account/content/password/PasswordView.fxml"),
CHANGE_PASSWORD("/io/bitsquare/gui/main/account/content/password/PasswordView.fxml"),
RESTRICTIONS("/io/bitsquare/gui/main/account/content/restrictions/RestrictionsView.fxml"),
REGISTRATION("/io/bitsquare/gui/main/account/content/registration/RegistrationView.fxml"),
FIAT_ACCOUNT("/io/bitsquare/gui/main/account/content/irc/IrcAccountView.fxml"),
// ~ Popups ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// arbitration
ARBITRATOR_PROFILE("/io/bitsquare/gui/main/account/arbitrator/profile/ArbitratorProfileView.fxml"),
ARBITRATOR_BROWSER("/io/bitsquare/gui/main/account/arbitrator/browser/ArbitratorBrowserView.fxml"),
ARBITRATOR_REGISTRATION(
"/io/bitsquare/gui/main/account/arbitrator/registration/ArbitratorRegistrationView.fxml"),
// ~ Testing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BOGUS("/io/bitsquare/BogusView.fxml");
private final String location;
private final String displayName;
FxmlView(String location) {
this(location, "NONE");
}
FxmlView(String location, String displayName) {
this.location = location;
this.displayName = displayName;
}
public URL getLocation() {
URL url = Navigation.class.getResource(location);
if (url == null)
throw new BitsquareException("'%s' could not be loaded as a resource", location);
return url;
}
public String getDisplayName() {
return displayName;
}
public String getId() {
return location.substring(location.lastIndexOf("/") + 1, location.lastIndexOf("View.fxml")).toLowerCase();
}
}

View file

@ -17,20 +17,26 @@
package io.bitsquare.gui; package io.bitsquare.gui;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.trade.BuyView;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import viewfx.view.View;
import viewfx.view.ViewPath;
public class Navigation { public class Navigation {
private static final String CURRENT_PATH_KEY = "currentPath"; private static final String CURRENT_PATH_KEY = "currentPath";
// TODO: MAIN->BUY is the default view for now; should be MAIN->HOME later private static final ViewPath DEFAULT_VIEW_PATH = ViewPath.to(MainView.class, BuyView.class);
private static final FxmlView[] DEFAULT_PATH = new FxmlView[]{ FxmlView.MAIN, FxmlView.BUY };
// New listeners can be added during iteration so we use CopyOnWriteArrayList to // New listeners can be added during iteration so we use CopyOnWriteArrayList to
// prevent invalid array modification // prevent invalid array modification
@ -38,11 +44,11 @@ public class Navigation {
private final Persistence persistence; private final Persistence persistence;
private FxmlView[] currentPath; private ViewPath currentPath;
// Used for returning to the last important view. After setup is done we want to // Used for returning to the last important view. After setup is done we want to
// return to the last opened view (e.g. sell/buy) // return to the last opened view (e.g. sell/buy)
private FxmlView[] returnPath; private ViewPath returnPath;
@Inject @Inject
@ -50,46 +56,50 @@ public class Navigation {
this.persistence = persistence; this.persistence = persistence;
} }
public void navigateTo(FxmlView... newPath) { public void navigateTo(Class<? extends View>... viewClasses) {
navigateTo(ViewPath.to(viewClasses));
}
public void navigateTo(ViewPath newPath) {
if (newPath == null) if (newPath == null)
return; return;
List<FxmlView> temp = new ArrayList<>(); ArrayList<Class<? extends View>> temp = new ArrayList<>();
for (int i = 0; i < newPath.length; i++) { for (int i = 0; i < newPath.size(); i++) {
FxmlView element = newPath[i]; Class<? extends View> viewClass = newPath.get(i);
temp.add(element); temp.add(viewClass);
if (currentPath == null || if (currentPath == null ||
(currentPath != null && (currentPath != null &&
currentPath.length > i && currentPath.size() > i &&
element != currentPath[i] && viewClass != currentPath.get(i) &&
i != newPath.length - 1)) { i != newPath.size() - 1)) {
List<FxmlView> temp2 = new ArrayList<>(temp); ArrayList<Class<? extends View>> temp2 = new ArrayList<>(temp);
for (int n = i + 1; n < newPath.length; n++) { for (int n = i + 1; n < newPath.size(); n++) {
FxmlView[] newTemp = new FxmlView[i + 1]; Class<? extends View>[] newTemp = new Class[i + 1];
currentPath = temp2.toArray(newTemp); currentPath = ViewPath.to(temp2.toArray(newTemp));
navigateTo(currentPath); navigateTo(currentPath);
element = newPath[n]; viewClass = newPath.get(n);
temp2.add(element); temp2.add(viewClass);
} }
} }
} }
currentPath = newPath; currentPath = newPath;
persistence.write(this, CURRENT_PATH_KEY, currentPath); persistence.write(this, CURRENT_PATH_KEY, (List<? extends Serializable>)currentPath);
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath)); listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
} }
public void navigateToLastOpenView() { public void navigateToLastOpenView() {
FxmlView[] lastPath = (FxmlView[]) persistence.read(this, CURRENT_PATH_KEY); ViewPath lastPath = (ViewPath) persistence.read(this, CURRENT_PATH_KEY);
if (lastPath == null || lastPath.length == 0) if (lastPath == null || lastPath.size() == 0)
lastPath = DEFAULT_PATH; lastPath = DEFAULT_VIEW_PATH;
navigateTo(lastPath); navigateTo(lastPath);
} }
public static interface Listener { public static interface Listener {
void onNavigationRequested(FxmlView... path); void onNavigationRequested(ViewPath path);
} }
public void addListener(Listener listener) { public void addListener(Listener listener) {
@ -100,16 +110,15 @@ public class Navigation {
listeners.remove(listener); listeners.remove(listener);
} }
public FxmlView[] getReturnPath() { public ViewPath getReturnPath() {
return returnPath; return returnPath;
} }
public FxmlView[] getCurrentPath() { public ViewPath getCurrentPath() {
return currentPath; return currentPath;
} }
public void setReturnPath(FxmlView[] returnPath) { public void setReturnPath(ViewPath returnPath) {
this.returnPath = returnPath; this.returnPath = returnPath;
} }
} }

View file

@ -19,16 +19,24 @@ package io.bitsquare.gui.main;
import io.bitsquare.BitsquareException; import io.bitsquare.BitsquareException;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.components.SystemNotification; import io.bitsquare.gui.components.SystemNotification;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.funds.FundsView;
import io.bitsquare.gui.main.home.HomeView;
import io.bitsquare.gui.main.msg.MsgView;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.settings.SettingsView;
import io.bitsquare.gui.main.trade.BuyView;
import io.bitsquare.gui.main.trade.SellView;
import io.bitsquare.gui.util.Transitions; import io.bitsquare.gui.util.Transitions;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
@ -44,9 +52,9 @@ import javafx.scene.layout.*;
import javafx.scene.paint.*; import javafx.scene.paint.*;
import javafx.scene.text.*; import javafx.scene.text.*;
import static io.bitsquare.gui.FxmlView.*;
import static javafx.scene.layout.AnchorPane.*; import static javafx.scene.layout.AnchorPane.*;
@FxmlView
public class MainView extends ActivatableView<StackPane, MainViewModel> { public class MainView extends ActivatableView<StackPane, MainViewModel> {
public static final String TITLE_KEY = "view.title"; public static final String TITLE_KEY = "view.title";
@ -79,18 +87,18 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
@Override @Override
protected void activate() { protected void activate() {
ToggleButton homeButton = new NavButton(HOME) {{ ToggleButton homeButton = new NavButton(HomeView.class, "Overview") {{
setDisable(true); // during irc demo setDisable(true); // during irc demo
}}; }};
ToggleButton buyButton = new NavButton(BUY); ToggleButton buyButton = new NavButton(BuyView.class, "Buy BTC");
ToggleButton sellButton = new NavButton(SELL); ToggleButton sellButton = new NavButton(SellView.class, "Sell BTC");
ToggleButton portfolioButton = new NavButton(PORTFOLIO); ToggleButton portfolioButton = new NavButton(PortfolioView.class, "Portfolio");
ToggleButton fundsButton = new NavButton(FUNDS); ToggleButton fundsButton = new NavButton(FundsView.class, "Funds");
ToggleButton msgButton = new NavButton(MSG) {{ ToggleButton msgButton = new NavButton(MsgView.class, "Messages") {{
setDisable(true); // during irc demo setDisable(true); // during irc demo
}}; }};
ToggleButton settingsButton = new NavButton(SETTINGS); ToggleButton settingsButton = new NavButton(SettingsView.class, "Settings");
ToggleButton accountButton = new NavButton(ACCOUNT); ToggleButton accountButton = new NavButton(AccountView.class, "Account");
Pane portfolioButtonHolder = new Pane(portfolioButton); Pane portfolioButtonHolder = new Pane(portfolioButton);
Pane bankAccountComboBoxHolder = new Pane(); Pane bankAccountComboBoxHolder = new Pane();
@ -123,19 +131,19 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
setId("base-content-container"); setId("base-content-container");
}}; }};
navigation.addListener(navItems -> { navigation.addListener(viewPath -> {
if (navItems == null || navItems.length != 2 || navItems[0] != FxmlView.MAIN) if (viewPath.size() != 2 || viewPath.indexOf(MainView.class) != 0)
return; return;
View view = viewLoader.load(navItems[1].getLocation()); Class<? extends View> viewClass = viewPath.tip();
View view = viewLoader.load(viewClass);
contentContainer.getChildren().setAll(view.getRoot()); contentContainer.getChildren().setAll(view.getRoot());
navButtons.getToggles().stream() navButtons.getToggles().stream()
.filter(toggle -> toggle instanceof ToggleButton) .filter(toggle -> toggle instanceof NavButton)
.filter(button -> navItems[1].getDisplayName().equals(((ToggleButton) button).getText())) .filter(button -> viewClass == ((NavButton) button).viewClass)
.findFirst() .findFirst()
.orElseThrow(() -> .orElseThrow(() -> new BitsquareException("No button matching %s found", viewClass))
new BitsquareException("No button matching %s found", navItems[1].getDisplayName()))
.setSelected(true); .setSelected(true);
}); });
@ -334,11 +342,15 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
private class NavButton extends ToggleButton { private class NavButton extends ToggleButton {
public NavButton(FxmlView item) { private final Class<? extends View> viewClass;
super(item.getDisplayName(), new ImageView() {{
setId("image-nav-" + item.getId()); public NavButton(Class<? extends View> viewClass, String title) {
super(title, new ImageView() {{
setId("image-nav-" + viewId(viewClass));
}}); }});
this.viewClass = viewClass;
this.setToggleGroup(navButtons); this.setToggleGroup(navButtons);
this.setId("nav-button"); this.setId("nav-button");
this.setPadding(new Insets(0, -10, -10, -10)); this.setPadding(new Insets(0, -10, -10, -10));
@ -353,14 +365,24 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
this.setMaxSize(50, 50); this.setMaxSize(50, 50);
this.setGraphicTextGap(newValue ? -1 : 0); this.setGraphicTextGap(newValue ? -1 : 0);
if (newValue) { if (newValue) {
this.getGraphic().setId("image-nav-" + item.getId() + "-active"); this.getGraphic().setId("image-nav-" + viewId(viewClass) + "-active");
} }
else { else {
this.getGraphic().setId("image-nav-" + item.getId()); this.getGraphic().setId("image-nav-" + viewId(viewClass));
} }
}); });
this.setOnAction(e -> navigation.navigateTo(FxmlView.MAIN, item)); this.setOnAction(e -> navigation.navigateTo(MainView.class, viewClass));
} }
}
private static String viewId(Class<? extends View> viewClass) {
String viewName = viewClass.getSimpleName();
String suffix = "View";
int suffixIdx = viewName.indexOf(suffix);
if (suffixIdx != viewName.length() - suffix.length())
throw new IllegalArgumentException("Cannot get ID for " + viewClass + ": class must end in " + suffix);
return viewName.substring(0, suffixIdx).toLowerCase();
} }
} }

View file

@ -17,19 +17,25 @@
package io.bitsquare.gui.main.account; package io.bitsquare.gui.main.account;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.arbitrator.ArbitratorSettingsView;
import io.bitsquare.gui.main.account.settings.AccountSettingsView;
import io.bitsquare.gui.main.account.setup.AccountSetupWizard;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.ViewPath;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
@FxmlView
public class AccountView extends ActivatableView<TabPane, AccountViewModel> { public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
@FXML Tab accountSettingsTab, arbitratorSettingsTab; @FXML Tab accountSettingsTab, arbitratorSettingsTab;
@ -49,21 +55,16 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
@Override @Override
public void initialize() { public void initialize() {
navigationListener = navigationItems -> { navigationListener = viewPath -> {
if (navigationItems != null && if (viewPath.size() == 3 && viewPath.indexOf(AccountView.class) == 1)
navigationItems.length == 3 && loadView(viewPath);
navigationItems[1] == FxmlView.ACCOUNT)
loadView(navigationItems[2]);
}; };
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == accountSettingsTab) if (newValue == accountSettingsTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class);
FxmlView.ACCOUNT_SETTINGS);
else else
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(MainView.class, AccountView.class, ArbitratorSettingsView.class);
FxmlView.ARBITRATOR_SETTINGS);
}; };
} }
@ -72,21 +73,16 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener); root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
if (navigation.getCurrentPath().length == 2 && if (!navigation.getCurrentPath().contains(AccountView.class))
navigation.getCurrentPath()[1] == FxmlView.ACCOUNT) { return;
if (model.getNeedRegistration()) {
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, if (model.getNeedRegistration())
FxmlView.ACCOUNT_SETUP); navigation.navigateTo(MainView.class, AccountView.class, AccountSetupWizard.class);
}
else { else if (root.getSelectionModel().getSelectedItem() == accountSettingsTab)
if (root.getSelectionModel().getSelectedItem() == accountSettingsTab) navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class);
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS); navigation.navigateTo(MainView.class, AccountView.class, ArbitratorSettingsView.class);
else
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT,
FxmlView.ARBITRATOR_SETTINGS);
}
}
} }
@Override @Override
@ -95,31 +91,31 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener); root.getSelectionModel().selectedItemProperty().removeListener(tabChangeListener);
} }
private void loadView(ViewPath viewPath) {
Tab tab;
Class<? extends View> viewClass = viewPath.tip();
private void loadView(FxmlView navigationItem) { if (viewClass == AccountSettingsView.class) {
View view = viewLoader.load(navigationItem.getLocation());
final Tab tab;
switch (navigationItem) {
case ACCOUNT_SETTINGS:
tab = accountSettingsTab; tab = accountSettingsTab;
tab.setText("Account settings"); tab.setText("Account settings");
arbitratorSettingsTab.setDisable(false); arbitratorSettingsTab.setDisable(false);
break; }
case ACCOUNT_SETUP: else if (viewClass == AccountSetupWizard.class) {
tab = accountSettingsTab; tab = accountSettingsTab;
tab.setText("Account setup"); tab.setText("Account setup");
arbitratorSettingsTab.setDisable(true); arbitratorSettingsTab.setDisable(true);
break; }
case ARBITRATOR_SETTINGS: else if (viewClass == ArbitratorSettingsView.class) {
tab = arbitratorSettingsTab; tab = arbitratorSettingsTab;
break; }
default: else {
throw new IllegalArgumentException("navigation item of type " + navigationItem + " is not allowed"); throw new IllegalArgumentException("Loading " + viewClass + " from " + this + " is not supported");
} }
// for IRC demo we deactivate the arbitratorSettingsTab // for IRC demo we deactivate the arbitratorSettingsTab
arbitratorSettingsTab.setDisable(true); arbitratorSettingsTab.setDisable(true);
View view = viewLoader.load(viewClass);
tab.setContent(view.getRoot()); tab.setContent(view.getRoot());
root.getSelectionModel().select(tab); root.getSelectionModel().select(tab);
} }

View file

@ -17,43 +17,48 @@
package io.bitsquare.gui.main.account.arbitrator; package io.bitsquare.gui.main.account.arbitrator;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrationView; import io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrationView;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.CachingViewLoader;
import viewfx.view.support.AbstractView; import viewfx.view.support.AbstractView;
import viewfx.view.support.CachingViewLoader;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.*; import javafx.scene.*;
import javafx.stage.Modality; import javafx.stage.Modality;
import javafx.stage.Stage; import javafx.stage.Stage;
// TODO Arbitration is very basic yet @FxmlView
class ArbitratorSettingsView extends AbstractView { public class ArbitratorSettingsView extends AbstractView {
private ArbitratorRegistrationView arbitratorRegistrationView;
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation;
private final Stage primaryStage; private final Stage primaryStage;
@Inject @Inject
private ArbitratorSettingsView(CachingViewLoader viewLoader, Navigation navigation, Stage primaryStage) { private ArbitratorSettingsView(CachingViewLoader viewLoader, Stage primaryStage) {
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.navigation = navigation;
this.primaryStage = primaryStage; this.primaryStage = primaryStage;
} }
private void loadView(FxmlView navigationItem) { @FXML
View view = viewLoader.load(navigationItem.getLocation()); public void onArbitratorRegistration() {
arbitratorRegistrationView = (ArbitratorRegistrationView) view; View view = viewLoader.load(ArbitratorRegistrationView.class);
showStage(view);
}
final Stage stage = new Stage(); @FXML
public void onArbitratorEdit() {
View view = viewLoader.load(ArbitratorRegistrationView.class);
showStage(view);
((ArbitratorRegistrationView) view).setEditMode(true);
}
private void showStage(View view) {
Stage stage = new Stage();
stage.setTitle("Arbitrator"); stage.setTitle("Arbitrator");
stage.setMinWidth(800); stage.setMinWidth(800);
stage.setMinHeight(400); stage.setMinHeight(400);
@ -67,16 +72,5 @@ class ArbitratorSettingsView extends AbstractView {
stage.setScene(scene); stage.setScene(scene);
stage.show(); stage.show();
} }
@FXML
public void onArbitratorRegistration() {
loadView(FxmlView.ARBITRATOR_REGISTRATION);
}
@FXML
public void onArbitratorEdit() {
loadView(FxmlView.ARBITRATOR_REGISTRATION);
arbitratorRegistrationView.setEditMode(true);
}
} }

View file

@ -19,7 +19,6 @@ package io.bitsquare.gui.main.account.arbitrator.browser;
import io.bitsquare.account.AccountSettings; import io.bitsquare.account.AccountSettings;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileView; import io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileView;
import io.bitsquare.locale.LanguageUtil; import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.msg.MessageService; import io.bitsquare.msg.MessageService;
@ -31,6 +30,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
@ -40,8 +40,8 @@ import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.stage.Stage; import javafx.stage.Stage;
// TODO Arbitration is very basic yet @FxmlView
class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements ArbitratorListener { public class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements ArbitratorListener {
@FXML Button prevButton, nextButton, selectButton, closeButton; @FXML Button prevButton, nextButton, selectButton, closeButton;
@FXML Pane arbitratorProfile; @FXML Pane arbitratorProfile;
@ -71,30 +71,11 @@ class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements Arbit
messageService.addArbitratorListener(this); messageService.addArbitratorListener(this);
messageService.getArbitrators(LanguageUtil.getDefaultLanguageLocale()); messageService.getArbitrators(LanguageUtil.getDefaultLanguageLocale());
loadView(FxmlView.ARBITRATOR_PROFILE); View view = viewLoader.load(ArbitratorProfileView.class);
checkButtonState();
}
/* public Initializable loadViewAndGetChildController(Navigation.Item item) {
final ViewLoader loader = new ViewLoader(getClass().getResource(item.getFxmlUrl()));
try {
final Node view = loader.load();
arbitratorProfileView = loader.getController();
arbitratorProfileView.setParentController(this);
root.getChildren().set(0, view);
return arbitratorProfileView;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}*/
private void loadView(FxmlView navigationItem) {
View view = viewLoader.load(navigationItem.getLocation());
root.getChildren().set(0, view.getRoot()); root.getChildren().set(0, view.getRoot());
arbitratorProfileView = (ArbitratorProfileView) view; arbitratorProfileView = (ArbitratorProfileView) view;
checkButtonState();
} }
@Override @Override
@ -118,7 +99,6 @@ class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements Arbit
public void onArbitratorRemoved(Arbitrator arbitrator) { public void onArbitratorRemoved(Arbitrator arbitrator) {
} }
@FXML @FXML
public void onPrevious() { public void onPrevious() {
if (index > 0) { if (index > 0) {
@ -151,7 +131,6 @@ class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements Arbit
stage.close(); stage.close();
} }
private void checkButtonState() { private void checkButtonState() {
prevButton.setDisable(index < 1); prevButton.setDisable(index < 1);
nextButton.setDisable(index == allArbitrators.size() - 1 || index == -1); nextButton.setDisable(index == allArbitrators.size() - 1 || index == -1);

View file

@ -19,17 +19,16 @@ package io.bitsquare.gui.main.account.arbitrator.profile;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.settings.Preferences;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.AbstractView; import viewfx.view.support.AbstractView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
// TODO Arbitration is very basic yet @FxmlView
public class ArbitratorProfileView extends AbstractView { public class ArbitratorProfileView extends AbstractView {
@FXML Label nameLabel; @FXML Label nameLabel;
@ -37,14 +36,10 @@ public class ArbitratorProfileView extends AbstractView {
@FXML TextField nameTextField, languagesTextField, reputationTextField, feeTextField, methodsTextField, @FXML TextField nameTextField, languagesTextField, reputationTextField, feeTextField, methodsTextField,
passiveServiceFeeTextField, idVerificationsTextField, webPageTextField, maxTradeVolumeTextField; passiveServiceFeeTextField, idVerificationsTextField, webPageTextField, maxTradeVolumeTextField;
private final Preferences preferences;
private final Persistence persistence;
private final BSFormatter formatter; private final BSFormatter formatter;
@Inject @Inject
public ArbitratorProfileView(Preferences preferences, Persistence persistence, BSFormatter formatter) { public ArbitratorProfileView(BSFormatter formatter) {
this.preferences = preferences;
this.persistence = persistence;
this.formatter = formatter; this.formatter = formatter;
} }

View file

@ -44,6 +44,7 @@ import java.util.Locale;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@ -56,7 +57,7 @@ import javafx.util.StringConverter;
import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
// TODO Arbitration is very basic yet @FxmlView
public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void> { public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void> {
@FXML Accordion accordion; @FXML Accordion accordion;
@ -119,7 +120,6 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
return locale.getDisplayLanguage(); return locale.getDisplayLanguage();
} }
@Override @Override
public Locale fromString(String s) { public Locale fromString(String s) {
return null; return null;
@ -129,13 +129,11 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
idTypeComboBox.setItems(FXCollections.observableArrayList( idTypeComboBox.setItems(FXCollections.observableArrayList(
new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class)))); new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class))));
idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() { idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() {
@Override @Override
public String toString(Arbitrator.ID_TYPE item) { public String toString(Arbitrator.ID_TYPE item) {
return BSResources.get(item.toString()); return BSResources.get(item.toString());
} }
@Override @Override
public Arbitrator.ID_TYPE fromString(String s) { public Arbitrator.ID_TYPE fromString(String s) {
return null; return null;
@ -145,13 +143,11 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD
.class)))); .class))));
methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() { methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() {
@Override @Override
public String toString(Arbitrator.METHOD item) { public String toString(Arbitrator.METHOD item) {
return BSResources.get(item.toString()); return BSResources.get(item.toString());
} }
@Override @Override
public Arbitrator.METHOD fromString(String s) { public Arbitrator.METHOD fromString(String s) {
return null; return null;
@ -161,13 +157,11 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
idVerificationsComboBox.setItems( idVerificationsComboBox.setItems(
FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class)))); FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class))));
idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() { idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() {
@Override @Override
public String toString(Arbitrator.ID_VERIFICATION item) { public String toString(Arbitrator.ID_VERIFICATION item) {
return BSResources.get(item.toString()); return BSResources.get(item.toString());
} }
@Override @Override
public Arbitrator.ID_VERIFICATION fromString(String s) { public Arbitrator.ID_VERIFICATION fromString(String s) {
return null; return null;
@ -375,7 +369,6 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
} }
} }
private Arbitrator getEditedArbitrator() { private Arbitrator getEditedArbitrator() {
String pubKeyAsHex = walletService.getArbitratorDepositAddressEntry().getPubKeyAsHexString(); String pubKeyAsHex = walletService.getArbitratorDepositAddressEntry().getPubKeyAsHexString();
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePublicKey()); String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePublicKey());

View file

@ -22,14 +22,16 @@ import io.bitsquare.gui.main.help.HelpId;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.support.InitializableView; import viewfx.view.FxmlView;
import viewfx.view.Wizard; import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
class ChangePasswordView extends InitializableView<GridPane, ChangePasswordViewModel> implements Wizard.Step { @FxmlView
public class ChangePasswordView extends InitializableView<GridPane, ChangePasswordViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton; @FXML Button saveButton, skipButton;

View file

@ -35,8 +35,9 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.FxmlView;
import viewfx.view.Wizard; import viewfx.view.Wizard;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
@ -50,7 +51,8 @@ import org.controlsfx.dialog.Dialog;
import static javafx.beans.binding.Bindings.createBooleanBinding; import static javafx.beans.binding.Bindings.createBooleanBinding;
class FiatAccountView extends ActivatableViewAndModel<GridPane, FiatAccountViewModel> implements Wizard.Step { @FxmlView
public class FiatAccountView extends ActivatableViewAndModel<GridPane, FiatAccountViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;
@FXML ComboBox<Region> regionComboBox; @FXML ComboBox<Region> regionComboBox;

View file

@ -28,6 +28,7 @@ import java.util.Currency;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import viewfx.view.Wizard; import viewfx.view.Wizard;
@ -40,6 +41,7 @@ import javafx.util.Callback;
/** /**
* Just temporary for giving the user a possibility to test the app via simulating the bank transfer in a IRC chat. * Just temporary for giving the user a possibility to test the app via simulating the bank transfer in a IRC chat.
*/ */
@FxmlView
public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccountViewModel> implements Wizard.Step { public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccountViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;

View file

@ -22,13 +22,15 @@ import io.bitsquare.gui.main.help.HelpId;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.support.InitializableView; import viewfx.view.FxmlView;
import viewfx.view.Wizard; import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
@FxmlView
public class PasswordView extends InitializableView<GridPane, PasswordViewModel> implements Wizard.Step { public class PasswordView extends InitializableView<GridPane, PasswordViewModel> implements Wizard.Step {
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;

View file

@ -30,8 +30,9 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.support.InitializableView; import viewfx.view.FxmlView;
import viewfx.view.Wizard; import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -42,6 +43,7 @@ import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
@FxmlView
public class RegistrationView extends InitializableView<GridPane, RegistrationViewModel> implements Wizard.Step { public class RegistrationView extends InitializableView<GridPane, RegistrationViewModel> implements Wizard.Step {
@FXML TextField feeTextField; @FXML TextField feeTextField;

View file

@ -18,7 +18,7 @@
package io.bitsquare.gui.main.account.content.restrictions; package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.arbitrator.Arbitrator; import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.FxmlView; import io.bitsquare.gui.main.account.arbitrator.browser.ArbitratorBrowserView;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
@ -29,6 +29,7 @@ import java.util.Locale;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.Wizard; import viewfx.view.Wizard;
@ -45,6 +46,7 @@ import javafx.stage.Stage;
import javafx.util.Callback; import javafx.util.Callback;
import javafx.util.StringConverter; import javafx.util.StringConverter;
@FxmlView
public class RestrictionsView extends ActivatableViewAndModel<GridPane, RestrictionsViewModel> implements Wizard.Step { public class RestrictionsView extends ActivatableViewAndModel<GridPane, RestrictionsViewModel> implements Wizard.Step {
@FXML ListView<Locale> languagesListView; @FXML ListView<Locale> languagesListView;
@ -121,7 +123,8 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
@FXML @FXML
private void onOpenArbitratorScreen(){ private void onOpenArbitratorScreen(){
loadView(FxmlView.ARBITRATOR_BROWSER); View view = viewLoader.load(ArbitratorBrowserView.class);
showStage(view);
} }
@ -146,9 +149,7 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
Help.openWindow(HelpId.SETUP_RESTRICTION_ARBITRATORS); Help.openWindow(HelpId.SETUP_RESTRICTION_ARBITRATORS);
} }
private void loadView(FxmlView navigationItem) { private void showStage(View view) {
View view = viewLoader.load(navigationItem.getLocation());
final Stage stage = new Stage(); final Stage stage = new Stage();
stage.setTitle("Arbitrator selection"); stage.setTitle("Arbitrator selection");
stage.setMinWidth(800); stage.setMinWidth(800);
@ -162,7 +163,7 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
Scene scene = new Scene((Parent) view.getRoot(), 800, 600); Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
stage.setScene(scene); stage.setScene(scene);
stage.setOnHidden(windowEvent -> { stage.setOnHidden(windowEvent -> {
if (navigationItem == FxmlView.ARBITRATOR_BROWSER) if (view instanceof ArbitratorBrowserView)
updateArbitratorList(); updateArbitratorList();
}); });
stage.show(); stage.show();

View file

@ -22,13 +22,15 @@ import io.bitsquare.gui.main.help.HelpId;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.support.InitializableView; import viewfx.view.FxmlView;
import viewfx.view.Wizard; import viewfx.view.Wizard;
import viewfx.view.support.InitializableView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
@FxmlView
public class SeedWordsView extends InitializableView<GridPane, SeedWordsViewModel> implements Wizard.Step { public class SeedWordsView extends InitializableView<GridPane, SeedWordsViewModel> implements Wizard.Step {
@FXML Button completedButton; @FXML Button completedButton;

View file

@ -17,14 +17,23 @@
package io.bitsquare.gui.main.account.settings; package io.bitsquare.gui.main.account.settings;
import io.bitsquare.gui.FxmlView; import io.bitsquare.BitsquareException;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.account.content.changepassword.ChangePasswordView;
import io.bitsquare.gui.main.account.content.fiat.FiatAccountView;
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
import io.bitsquare.gui.util.Colors; import io.bitsquare.gui.util.Colors;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.ViewPath;
import viewfx.view.Wizard; import viewfx.view.Wizard;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
@ -37,7 +46,8 @@ import javafx.scene.paint.*;
import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
class AccountSettingsView extends ActivatableViewAndModel { @FxmlView
public class AccountSettingsView extends ActivatableViewAndModel {
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;
@ -56,51 +66,40 @@ class AccountSettingsView extends ActivatableViewAndModel {
@Override @Override
public void initialize() { public void initialize() {
listener = navigationItems -> { listener = viewPath -> {
if (navigationItems != null && if (viewPath.size() != 4 || !viewPath.contains(AccountSettingsView.class))
navigationItems.length == 4 && return;
navigationItems[2] == FxmlView.ACCOUNT_SETTINGS) {
loadView(navigationItems[3]); loadView(viewPath.tip());
selectMainMenuButton(navigationItems[3]); selectMainMenuButton(viewPath.tip());
}
}; };
ToggleGroup toggleGroup = new ToggleGroup(); ToggleGroup toggleGroup = new ToggleGroup();
seedWords = new MenuItem(navigation, "Wallet seed", seedWords = new MenuItem(navigation, toggleGroup, "Wallet seed", SeedWordsView.class);
FxmlView.SEED_WORDS, toggleGroup); password = new MenuItem(navigation, toggleGroup, "Wallet password", ChangePasswordView.class);
password = new MenuItem(navigation, "Wallet password", restrictions = new MenuItem(navigation, toggleGroup, "Arbitrator selection", RestrictionsView.class);
FxmlView.CHANGE_PASSWORD, toggleGroup); fiatAccount = new MenuItem(navigation, toggleGroup, "Payments account(s)", FiatAccountView.class);
restrictions = new MenuItem(navigation, "Arbitrator selection", registration = new MenuItem(navigation, toggleGroup, "Renew your account", RegistrationView.class);
FxmlView.RESTRICTIONS, toggleGroup);
fiatAccount = new MenuItem(navigation, "Payments account(s)",
FxmlView.FIAT_ACCOUNT, toggleGroup);
registration = new MenuItem(navigation, "Renew your account",
FxmlView.REGISTRATION, toggleGroup);
seedWords.setDisable(true); seedWords.setDisable(true);
password.setDisable(true); password.setDisable(true);
restrictions.setDisable(true); restrictions.setDisable(true);
registration.setDisable(true); registration.setDisable(true);
leftVBox.getChildren().addAll(seedWords, password, leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
restrictions, fiatAccount, registration);
} }
@Override @Override
public void doActivate() { public void doActivate() {
navigation.addListener(listener); navigation.addListener(listener);
FxmlView[] items = navigation.getCurrentPath(); ViewPath viewPath = navigation.getCurrentPath();
if (items.length == 3 && if (viewPath.size() == 3 && viewPath.indexOf(AccountSettingsView.class) == 2) {
items[2] == FxmlView.ACCOUNT_SETTINGS) { navigation.navigateTo(
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, ViewPath.to(MainView.class, AccountView.class, AccountSettingsView.class, FiatAccountView.class));
FxmlView.ACCOUNT_SETTINGS, FxmlView.FIAT_ACCOUNT);
}
else {
if (items.length == 4 &&
items[2] == FxmlView.ACCOUNT_SETTINGS) {
loadView(items[3]);
selectMainMenuButton(items[3]);
} }
else if (viewPath.size() == 4 && viewPath.indexOf(AccountSettingsView.class) == 2) {
loadView(viewPath.get(3));
selectMainMenuButton(viewPath.get(3));
} }
} }
@ -109,42 +108,27 @@ class AccountSettingsView extends ActivatableViewAndModel {
navigation.removeListener(listener); navigation.removeListener(listener);
} }
private void loadView(FxmlView navigationItem) { private void loadView(Class<? extends View> viewClass) {
View view = viewLoader.load(navigationItem.getLocation()); View view = viewLoader.load(viewClass);
content.getChildren().setAll(view.getRoot()); content.getChildren().setAll(view.getRoot());
if (view instanceof Wizard.Step) if (view instanceof Wizard.Step)
((Wizard.Step) view).hideWizardNavigation(); ((Wizard.Step) view).hideWizardNavigation();
} }
private void selectMainMenuButton(FxmlView item) { private void selectMainMenuButton(Class<? extends View> viewClass) {
switch (item) { if (viewClass == SeedWordsView.class) seedWords.setSelected(true);
case SEED_WORDS: else if (viewClass == ChangePasswordView.class) password.setSelected(true);
seedWords.setSelected(true); else if (viewClass == RestrictionsView.class) restrictions.setSelected(true);
break; else if (viewClass == FiatAccountView.class) fiatAccount.setSelected(true);
case CHANGE_PASSWORD: else if (viewClass == RegistrationView.class) registration.setSelected(true);
password.setSelected(true); else throw new BitsquareException("Selecting main menu button for " + viewClass + " is not supported");
break;
case RESTRICTIONS:
restrictions.setSelected(true);
break;
case FIAT_ACCOUNT:
fiatAccount.setSelected(true);
break;
case REGISTRATION:
registration.setSelected(true);
break;
default:
log.error(item.getLocation() + " is invalid");
break;
}
} }
} }
class MenuItem extends ToggleButton { class MenuItem extends ToggleButton {
MenuItem(Navigation navigation, String title, FxmlView navigationItem, MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Class<? extends View> viewClass) {
ToggleGroup toggleGroup) {
setToggleGroup(toggleGroup); setToggleGroup(toggleGroup);
setText(title); setText(title);
@ -155,17 +139,17 @@ class MenuItem extends ToggleButton {
Label icon = new Label(); Label icon = new Label();
icon.setTextFill(Paint.valueOf("#999")); icon.setTextFill(Paint.valueOf("#999"));
if (navigationItem.equals(FxmlView.SEED_WORDS)) if (viewClass == SeedWordsView.class)
AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN); AwesomeDude.setIcon(icon, AwesomeIcon.INFO_SIGN);
else if (navigationItem.equals(FxmlView.REGISTRATION)) else if (viewClass == RegistrationView.class)
AwesomeDude.setIcon(icon, AwesomeIcon.BRIEFCASE); AwesomeDude.setIcon(icon, AwesomeIcon.BRIEFCASE);
else else
AwesomeDude.setIcon(icon, AwesomeIcon.EDIT_SIGN); AwesomeDude.setIcon(icon, AwesomeIcon.EDIT_SIGN);
setGraphic(icon); setGraphic(icon);
setOnAction((event) -> navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, setOnAction((event) -> navigation.navigateTo(
FxmlView.ACCOUNT_SETTINGS, navigationItem)); ViewPath.to(MainView.class, AccountView.class, AccountSettingsView.class, viewClass)));
selectedProperty().addListener((ov, oldValue, newValue) -> { selectedProperty().addListener((ov, oldValue, newValue) -> {
if (newValue) { if (newValue) {

View file

@ -17,16 +17,19 @@
package io.bitsquare.gui.main.account.setup; package io.bitsquare.gui.main.account.setup;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.content.fiat.FiatAccountView;
import io.bitsquare.gui.main.account.content.irc.IrcAccountView; import io.bitsquare.gui.main.account.content.irc.IrcAccountView;
import io.bitsquare.gui.main.account.content.password.PasswordView; import io.bitsquare.gui.main.account.content.password.PasswordView;
import io.bitsquare.gui.main.account.content.registration.RegistrationView; import io.bitsquare.gui.main.account.content.registration.RegistrationView;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView; import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView; import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
import io.bitsquare.gui.main.trade.BuyView;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.Wizard; import viewfx.view.Wizard;
@ -38,7 +41,8 @@ import javafx.scene.control.*;
import javafx.scene.image.*; import javafx.scene.image.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
class AccountSetupWizard extends ActivatableView implements Wizard { @FxmlView
public class AccountSetupWizard extends ActivatableView implements Wizard {
@FXML VBox leftVBox; @FXML VBox leftVBox;
@FXML AnchorPane content; @FXML AnchorPane content;
@ -57,54 +61,49 @@ class AccountSetupWizard extends ActivatableView implements Wizard {
@Override @Override
public void initialize() { public void initialize() {
listener = navigationItems -> { listener = viewPath -> {
if (navigationItems != null && if (viewPath.size() != 4 || !viewPath.contains(this.getClass()))
navigationItems.length == 4 && return;
navigationItems[2] == FxmlView.ACCOUNT_SETUP) {
switch (navigationItems[3]) { Class<? extends View> viewClass = viewPath.tip();
case SEED_WORDS:
if (viewClass == SeedWordsView.class) {
seedWords.show(); seedWords.show();
break; }
case ADD_PASSWORD: else if (viewClass == PasswordView.class) {
seedWords.onCompleted(); seedWords.onCompleted();
password.show(); password.show();
break; }
case RESTRICTIONS: else if (viewClass == RestrictionsView.class) {
seedWords.onCompleted(); seedWords.onCompleted();
password.onCompleted(); password.onCompleted();
restrictions.show(); restrictions.show();
break; }
case FIAT_ACCOUNT: else if (viewClass == FiatAccountView.class) {
seedWords.onCompleted(); seedWords.onCompleted();
password.onCompleted(); password.onCompleted();
restrictions.onCompleted(); restrictions.onCompleted();
fiatAccount.show(); fiatAccount.show();
break; }
case REGISTRATION: else if (viewClass == RegistrationView.class) {
seedWords.onCompleted(); seedWords.onCompleted();
password.onCompleted(); password.onCompleted();
restrictions.onCompleted(); restrictions.onCompleted();
fiatAccount.onCompleted(); fiatAccount.onCompleted();
registration.show(); registration.show();
break;
}
} }
}; };
seedWords = new WizardItem(this, "Backup wallet seed", "Write down the seed word for your wallet", seedWords = new WizardItem(SeedWordsView.class,
FxmlView.SEED_WORDS); "Backup wallet seed", "Write down the seed word for your wallet");
password = new WizardItem(this, "Setup password", "Protect your wallet with a password", password = new WizardItem(PasswordView.class,
FxmlView.ADD_PASSWORD); "Setup password", "Protect your wallet with a password");
restrictions = new WizardItem(this, "Select arbitrators", restrictions = new WizardItem(RestrictionsView.class,
"Select which arbitrators you want to use for trading", "Select arbitrators", "Select which arbitrators you want to use for trading");
FxmlView.RESTRICTIONS); fiatAccount = new WizardItem(FiatAccountView.class,
fiatAccount = new WizardItem(this, " Setup Payments account(s)", " Setup Payments account(s)", "You need to setup at least one payment account");
"You need to setup at least one payment account", registration = new WizardItem(RegistrationView.class,
FxmlView.FIAT_ACCOUNT); "Register your account", "The registration in the Blockchain requires a payment of 0.0002 BTC");
registration = new WizardItem(this, "Register your account",
"The registration in the Blockchain requires a payment of 0.0002 BTC",
FxmlView.REGISTRATION);
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration); leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
@ -149,31 +148,27 @@ class AccountSetupWizard extends ActivatableView implements Wizard {
if (navigation.getReturnPath() != null) if (navigation.getReturnPath() != null)
navigation.navigateTo(navigation.getReturnPath()); navigation.navigateTo(navigation.getReturnPath());
else else
navigation.navigateTo(FxmlView.MAIN, FxmlView.BUY); navigation.navigateTo(MainView.class, BuyView.class);
} }
} }
protected void loadView(FxmlView navigationItem) { protected void loadView(Class<? extends View> viewClass) {
View view = viewLoader.load(navigationItem.getLocation()); View view = viewLoader.load(viewClass);
content.getChildren().setAll(view.getRoot()); content.getChildren().setAll(view.getRoot());
if (view instanceof Wizard.Step) if (view instanceof Wizard.Step)
((Step) view).setParent(this); ((Step) view).setParent(this);
} }
}
class WizardItem extends HBox { private class WizardItem extends HBox {
private final ImageView imageView; private final ImageView imageView;
private final Label titleLabel; private final Label titleLabel;
private final Label subTitleLabel; private final Label subTitleLabel;
private final AccountSetupWizard parent; private final Class<? extends View> viewClass;
private final FxmlView navigationItem;
WizardItem(AccountSetupWizard parent, String title, String subTitle, WizardItem(Class<? extends View> viewClass, String title, String subTitle) {
FxmlView navigationItem) { this.viewClass = viewClass;
this.parent = parent;
this.navigationItem = navigationItem;
setId("wizard-item-background-deactivated"); setId("wizard-item-background-deactivated");
setSpacing(5); setSpacing(5);
@ -210,10 +205,7 @@ class WizardItem extends HBox {
} }
void show() { void show() {
parent.loadView(navigationItem); loadView(viewClass);
/* navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT, Navigation
.Item.ACCOUNT_SETUP,
navigationItem);*/
setId("wizard-item-background-active"); setId("wizard-item-background-active");
imageView.setId("image-arrow-blue"); imageView.setId("image-arrow-blue");
@ -228,4 +220,5 @@ class WizardItem extends HBox {
subTitleLabel.setId("wizard-sub-title-completed"); subTitleLabel.setId("wizard-sub-title-completed");
} }
} }
}

View file

@ -17,12 +17,15 @@
package io.bitsquare.gui.main.funds; package io.bitsquare.gui.main.funds;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.funds.transactions.TransactionsView;
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.model.Activatable; import viewfx.model.Activatable;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
@ -31,7 +34,8 @@ import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
class FundsView extends ActivatableViewAndModel<TabPane, Activatable> { @FxmlView
public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab withdrawalTab, transactionsTab; @FXML Tab withdrawalTab, transactionsTab;
@ -43,24 +47,23 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
private final Navigation navigation; private final Navigation navigation;
@Inject @Inject
FundsView(ViewLoader viewLoader, Navigation navigation) { public FundsView(ViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.navigation = navigation; this.navigation = navigation;
} }
@Override @Override
public void initialize() { public void initialize() {
navigationListener = navigationItems -> { navigationListener = viewPath -> {
if (navigationItems != null && navigationItems.length == 3 if (viewPath.size() == 3 && viewPath.indexOf(FundsView.class) == 1)
&& navigationItems[1] == FxmlView.FUNDS) loadView(viewPath.tip());
loadView(navigationItems[2]);
}; };
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == withdrawalTab) if (newValue == withdrawalTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.WITHDRAWAL); navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
else if (newValue == transactionsTab) else if (newValue == transactionsTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.TRANSACTIONS); navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
}; };
} }
@ -70,9 +73,9 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == transactionsTab) if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.TRANSACTIONS); navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
else else
navigation.navigateTo(FxmlView.MAIN, FxmlView.FUNDS, FxmlView.WITHDRAWAL); navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
} }
@Override @Override
@ -81,20 +84,17 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.removeListener(navigationListener); navigation.removeListener(navigationListener);
} }
private void loadView(FxmlView navigationItem) { private void loadView(Class<? extends View> viewClass) {
// we want to get activate/deactivate called, so we remove the old view on tab change // we want to get activate/deactivate called, so we remove the old view on tab change
if (currentTab != null) if (currentTab != null)
currentTab.setContent(null); currentTab.setContent(null);
View view = viewLoader.load(navigationItem.getLocation()); if (viewClass == WithdrawalView.class)
switch (navigationItem) {
case WITHDRAWAL:
currentTab = withdrawalTab; currentTab = withdrawalTab;
break; if (viewClass == TransactionsView.class)
case TRANSACTIONS:
currentTab = transactionsTab; currentTab = transactionsTab;
break;
} View view = viewLoader.load(viewClass);
currentTab.setContent(view.getRoot()); currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab); root.getSelectionModel().select(currentTab);
} }

View file

@ -28,6 +28,7 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
@ -37,7 +38,8 @@ import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.util.Callback; import javafx.util.Callback;
class TransactionsView extends ActivatableViewAndModel { @FxmlView
public class TransactionsView extends ActivatableViewAndModel {
@FXML TableView<TransactionsListItem> table; @FXML TableView<TransactionsListItem> table;
@FXML TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn, @FXML TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn,

View file

@ -38,6 +38,7 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
@ -54,7 +55,8 @@ import org.controlsfx.control.action.Action;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
class WithdrawalView extends ActivatableViewAndModel { @FxmlView
public class WithdrawalView extends ActivatableViewAndModel {
@FXML TableView<WithdrawalListItem> table; @FXML TableView<WithdrawalListItem> table;
@FXML Button addNewAddressButton; @FXML Button addNewAddressButton;

View file

@ -17,9 +17,11 @@
package io.bitsquare.gui.main.home; package io.bitsquare.gui.main.home;
import viewfx.view.FxmlView;
import viewfx.view.support.AbstractView; import viewfx.view.support.AbstractView;
// home is just hosting the arbiters buttons yet, but that's just for dev, not clear yet what will be in home, // home is just hosting the arbiters buttons yet, but that's just for dev, not clear yet what will be in home,
// probably overview, event history, news, charts,... -> low prio // probably overview, event history, news, charts,... -> low prio
class HomeView extends AbstractView { @FxmlView
public class HomeView extends AbstractView {
} }

View file

@ -17,9 +17,11 @@
package io.bitsquare.gui.main.msg; package io.bitsquare.gui.main.msg;
import viewfx.view.FxmlView;
import viewfx.view.support.AbstractView; import viewfx.view.support.AbstractView;
// will be probably only used for arbitration communication, will be renamed and the icon changed // will be probably only used for arbitration communication, will be renamed and the icon changed
class MsgView extends AbstractView { @FxmlView
public class MsgView extends AbstractView {
} }

View file

@ -17,13 +17,17 @@
package io.bitsquare.gui.main.portfolio; package io.bitsquare.gui.main.portfolio;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.portfolio.closed.ClosedTradesView;
import io.bitsquare.gui.main.portfolio.offer.OffersView;
import io.bitsquare.gui.main.portfolio.pending.PendingTradesView;
import io.bitsquare.trade.TradeManager; import io.bitsquare.trade.TradeManager;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.model.Activatable; import viewfx.model.Activatable;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
@ -32,7 +36,8 @@ import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> { @FxmlView
public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab offersTab, openTradesTab, closedTradesTab; @FXML Tab offersTab, openTradesTab, closedTradesTab;
@ -53,20 +58,18 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
@Override @Override
public void initialize() { public void initialize() {
navigationListener = navigationItems -> { navigationListener = viewPath -> {
if (navigationItems != null && navigationItems.length == 3 if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1)
&& navigationItems[1] == FxmlView.PORTFOLIO) loadView(viewPath.tip());
loadView(navigationItems[2]);
}; };
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == offersTab) if (newValue == offersTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS); navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
else if (newValue == openTradesTab) else if (newValue == openTradesTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
FxmlView.PENDING_TRADES);
else if (newValue == closedTradesTab) else if (newValue == closedTradesTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.CLOSED_TRADES); navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
}; };
} }
@ -76,9 +79,9 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
if (tradeManager.getPendingTrades().size() == 0) if (tradeManager.getPendingTrades().size() == 0)
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS); navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
else else
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.PENDING_TRADES); navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
} }
@Override @Override
@ -88,24 +91,19 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
currentTab = null; currentTab = null;
} }
private void loadView(FxmlView navigationItem) { private void loadView(Class<? extends View> viewClass) {
// we want to get activate/deactivate called, so we remove the old view on tab change // we want to get activate/deactivate called, so we remove the old view on tab change
if (currentTab != null) if (currentTab != null)
currentTab.setContent(null); currentTab.setContent(null);
View view = viewLoader.load(navigationItem.getLocation()); if (viewClass == OffersView.class)
switch (navigationItem) {
case OFFERS:
currentTab = offersTab; currentTab = offersTab;
break; if (viewClass == PendingTradesView.class)
case PENDING_TRADES:
currentTab = openTradesTab; currentTab = openTradesTab;
break; if (viewClass == ClosedTradesView.class)
case CLOSED_TRADES:
currentTab = closedTradesTab; currentTab = closedTradesTab;
break;
} View view = viewLoader.load(viewClass);
currentTab.setContent(view.getRoot()); currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab); root.getSelectionModel().select(currentTab);
} }

View file

@ -21,6 +21,7 @@ import io.bitsquare.gui.components.Popups;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
@ -29,7 +30,8 @@ import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.util.Callback; import javafx.util.Callback;
class ClosedTradesView extends ActivatableViewAndModel<GridPane, ClosedTradesViewModel> { @FxmlView
public class ClosedTradesView extends ActivatableViewAndModel<GridPane, ClosedTradesViewModel> {
@FXML TableView<ClosedTradesListItem> table; @FXML TableView<ClosedTradesListItem> table;
@FXML TableColumn<ClosedTradesListItem, ClosedTradesListItem> priceColumn, amountColumn, volumeColumn, @FXML TableColumn<ClosedTradesListItem, ClosedTradesListItem> priceColumn, amountColumn, volumeColumn,

View file

@ -22,6 +22,7 @@ import io.bitsquare.util.Utilities;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
@ -31,7 +32,8 @@ import javafx.scene.image.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.util.Callback; import javafx.util.Callback;
class OffersView extends ActivatableViewAndModel<GridPane, OffersViewModel> { @FxmlView
public class OffersView extends ActivatableViewAndModel<GridPane, OffersViewModel> {
@FXML TableView<OfferListItem> table; @FXML TableView<OfferListItem> table;
@FXML TableColumn<OfferListItem, OfferListItem> priceColumn, amountColumn, volumeColumn, @FXML TableColumn<OfferListItem, OfferListItem> priceColumn, amountColumn, volumeColumn,

View file

@ -17,7 +17,6 @@
package io.bitsquare.gui.main.portfolio.pending; package io.bitsquare.gui.main.portfolio.pending;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.components.InfoDisplay; import io.bitsquare.gui.components.InfoDisplay;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
@ -27,8 +26,11 @@ import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.components.TxIdTextField; import io.bitsquare.gui.components.TxIdTextField;
import io.bitsquare.gui.components.processbar.ProcessStepBar; import io.bitsquare.gui.components.processbar.ProcessStepBar;
import io.bitsquare.gui.components.processbar.ProcessStepItem; import io.bitsquare.gui.components.processbar.ProcessStepItem;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.closed.ClosedTradesView;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import io.bitsquare.util.Utilities; import io.bitsquare.util.Utilities;
@ -41,6 +43,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.application.Platform; import javafx.application.Platform;
@ -54,7 +57,8 @@ import javafx.scene.layout.*;
import javafx.util.Callback; import javafx.util.Callback;
import javafx.util.StringConverter; import javafx.util.StringConverter;
class PendingTradesView extends ActivatableViewAndModel<AnchorPane, PendingTradesViewModel> { @FxmlView
public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, PendingTradesViewModel> {
@FXML GridPane gridPane; @FXML GridPane gridPane;
@FXML ScrollPane scrollPane; @FXML ScrollPane scrollPane;
@ -180,9 +184,7 @@ class PendingTradesView extends ActivatableViewAndModel<AnchorPane, PendingTrade
public void onWithdraw() { public void onWithdraw() {
setSummaryControlsVisible(false); setSummaryControlsVisible(false);
model.withdraw(withdrawAddressTextField.getText()); model.withdraw(withdrawAddressTextField.getText());
Platform.runLater(() -> Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO,
FxmlView.CLOSED_TRADES));
} }
@FXML @FXML

View file

@ -17,13 +17,16 @@
package io.bitsquare.gui.main.settings; package io.bitsquare.gui.main.settings;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.settings.application.PreferencesView;
import io.bitsquare.gui.main.settings.network.NetworkSettingsView;
import io.bitsquare.settings.Preferences; import io.bitsquare.settings.Preferences;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.model.Activatable; import viewfx.model.Activatable;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
@ -32,7 +35,8 @@ import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> { @FxmlView
public class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab preferencesTab, networkSettingsTab; @FXML Tab preferencesTab, networkSettingsTab;
@ -52,19 +56,16 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
@Override @Override
public void initialize() { public void initialize() {
navigationListener = navigationItems -> { navigationListener = viewPath -> {
if (navigationItems != null && navigationItems.length == 3 if (viewPath.size() == 3 && viewPath.indexOf(SettingsView.class) == 1)
&& navigationItems[1] == FxmlView.SETTINGS) loadView(viewPath.tip());
loadView(navigationItems[2]);
}; };
tabChangeListener = (ov, oldValue, newValue) -> { tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == preferencesTab) if (newValue == preferencesTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.SETTINGS, navigation.navigateTo(MainView.class, SettingsView.class, PreferencesView.class);
FxmlView.PREFERENCES);
else if (newValue == networkSettingsTab) else if (newValue == networkSettingsTab)
navigation.navigateTo(FxmlView.MAIN, FxmlView.SETTINGS, navigation.navigateTo(MainView.class, SettingsView.class, NetworkSettingsView.class);
FxmlView.NETWORK_SETTINGS);
}; };
} }
@ -74,13 +75,9 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.addListener(navigationListener); navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == preferencesTab) if (root.getSelectionModel().getSelectedItem() == preferencesTab)
navigation.navigateTo(FxmlView.MAIN, navigation.navigateTo(MainView.class, SettingsView.class, PreferencesView.class);
FxmlView.SETTINGS,
FxmlView.PREFERENCES);
else else
navigation.navigateTo(FxmlView.MAIN, navigation.navigateTo(MainView.class, SettingsView.class, NetworkSettingsView.class);
FxmlView.SETTINGS,
FxmlView.NETWORK_SETTINGS);
} }
@Override @Override
@ -89,19 +86,17 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
navigation.removeListener(navigationListener); navigation.removeListener(navigationListener);
} }
private void loadView(FxmlView navigationItem) { private void loadView(Class<? extends View> viewClass) {
View view = viewLoader.load(navigationItem.getLocation());
final Tab tab; final Tab tab;
switch (navigationItem) {
case PREFERENCES: if (viewClass == PreferencesView.class)
tab = preferencesTab; tab = preferencesTab;
break; else if (viewClass == NetworkSettingsView.class)
case NETWORK_SETTINGS:
tab = networkSettingsTab; tab = networkSettingsTab;
break; else
default: throw new IllegalArgumentException("Navigation to " + viewClass + " is not supported");
throw new IllegalArgumentException("navigation item of type " + navigationItem + " is not allowed");
} View view = viewLoader.load(viewClass);
tab.setContent(view.getRoot()); tab.setContent(view.getRoot());
root.getSelectionModel().select(tab); root.getSelectionModel().select(tab);
} }

View file

@ -19,13 +19,15 @@ package io.bitsquare.gui.main.settings.application;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> { @FxmlView
public class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> {
@FXML ComboBox<String> btcDenominationComboBox; @FXML ComboBox<String> btcDenominationComboBox;
@FXML CheckBox useAnimationsCheckBox, useEffectsCheckBox; @FXML CheckBox useAnimationsCheckBox, useEffectsCheckBox;

View file

@ -22,12 +22,14 @@ import io.bitsquare.network.ClientNode;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.InitializableView; import viewfx.view.support.InitializableView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
class NetworkSettingsView extends InitializableView { @FxmlView
public class NetworkSettingsView extends InitializableView {
private final String bitcoinNetworkValue; private final String bitcoinNetworkValue;
private final ClientNode clientNode; private final ClientNode clientNode;

View file

@ -21,9 +21,11 @@ import io.bitsquare.gui.Navigation;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.CachingViewLoader; import viewfx.view.support.CachingViewLoader;
class BuyView extends TradeView { @FxmlView
public class BuyView extends TradeView {
@Inject @Inject
public BuyView(CachingViewLoader viewLoader, Navigation navigation) { public BuyView(CachingViewLoader viewLoader, Navigation navigation) {

View file

@ -21,9 +21,11 @@ import io.bitsquare.gui.Navigation;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.CachingViewLoader; import viewfx.view.support.CachingViewLoader;
class SellView extends TradeView { @FxmlView
public class SellView extends TradeView {
@Inject @Inject
public SellView(CachingViewLoader viewLoader, Navigation navigation) { public SellView(CachingViewLoader viewLoader, Navigation navigation) {

View file

@ -17,9 +17,9 @@
package io.bitsquare.gui.main.trade; package io.bitsquare.gui.main.trade;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.trade.createoffer.CreateOfferView; import io.bitsquare.gui.main.trade.createoffer.CreateOfferView;
import io.bitsquare.gui.main.trade.offerbook.OfferBookView; import io.bitsquare.gui.main.trade.offerbook.OfferBookView;
import io.bitsquare.gui.main.trade.takeoffer.TakeOfferView; import io.bitsquare.gui.main.trade.takeoffer.TakeOfferView;
@ -33,15 +33,16 @@ import java.util.List;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import viewfx.view.support.CachingViewLoader;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
import viewfx.view.support.CachingViewLoader;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.scene.*; import javafx.scene.*;
import javafx.scene.control.*; import javafx.scene.control.*;
public class TradeView extends ActivatableView<TabPane, Void> {
public abstract class TradeView extends ActivatableView<TabPane, Void> {
private OfferBookView offerBookView; private OfferBookView offerBookView;
private CreateOfferView createOfferView; private CreateOfferView createOfferView;
@ -49,28 +50,25 @@ public class TradeView extends ActivatableView<TabPane, Void> {
private Node createOfferRoot; private Node createOfferRoot;
private Node takeOfferRoot; private Node takeOfferRoot;
private Navigation.Listener listener; private Navigation.Listener listener;
private FxmlView navigationItem;
private Direction direction;
private Coin amount; private Coin amount;
private Fiat price; private Fiat price;
private Offer offer; private Offer offer;
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;
private final Direction direction;
protected TradeView(CachingViewLoader viewLoader, Navigation navigation) { protected TradeView(CachingViewLoader viewLoader, Navigation navigation) {
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.navigation = navigation; this.navigation = navigation;
this.direction = (this instanceof BuyView) ? Direction.BUY : Direction.SELL;
} }
@Override @Override
protected void initialize() { protected void initialize() {
direction = (this instanceof BuyView) ? Direction.BUY : Direction.SELL; listener = viewPath -> {
navigationItem = (direction == Direction.BUY) ? FxmlView.BUY : FxmlView.SELL; if (viewPath.size() == 3 && viewPath.indexOf(this.getClass()) == 1) {
loadView(viewPath.tip());
listener = navigationItems -> {
if (navigationItems != null && navigationItems.length == 3 && navigationItems[1] == navigationItem) {
loadView(navigationItems[2]);
} }
}; };
} }
@ -98,7 +96,7 @@ public class TradeView extends ActivatableView<TabPane, Void> {
}); });
navigation.addListener(listener); navigation.addListener(listener);
navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK); navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class);
} }
@Override @Override
@ -110,21 +108,21 @@ public class TradeView extends ActivatableView<TabPane, Void> {
public void createOffer(Coin amount, Fiat price) { public void createOffer(Coin amount, Fiat price) {
this.amount = amount; this.amount = amount;
this.price = price; this.price = price;
navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.CREATE_OFFER); navigation.navigateTo(MainView.class, this.getClass(), CreateOfferView.class);
} }
public void takeOffer(Coin amount, Fiat price, Offer offer) { public void takeOffer(Coin amount, Fiat price, Offer offer) {
this.amount = amount; this.amount = amount;
this.price = price; this.price = price;
this.offer = offer; this.offer = offer;
navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.TAKE_OFFER); navigation.navigateTo(MainView.class, this.getClass(), TakeOfferView.class);
} }
private View loadView(FxmlView navigationItem) { private View loadView(Class<? extends View> viewClass) {
TabPane tabPane = root; TabPane tabPane = root;
if (navigationItem == FxmlView.OFFER_BOOK && offerBookView == null) { if (viewClass == OfferBookView.class && offerBookView == null) {
// Offerbook must not be cached by ViewLoader as we use 2 instances for sell and buy screens. // Offerbook must not be cached by ViewLoader as we use 2 instances for sell and buy screens.
View view = viewLoader.load(navigationItem.getLocation()); View view = viewLoader.load(viewClass);
final Tab tab = new Tab(direction == Direction.BUY ? "Buy Bitcoin" : "Sell Bitcoin"); final Tab tab = new Tab(direction == Direction.BUY ? "Buy Bitcoin" : "Sell Bitcoin");
tab.setClosable(false); tab.setClosable(false);
tab.setContent(view.getRoot()); tab.setContent(view.getRoot());
@ -136,10 +134,10 @@ public class TradeView extends ActivatableView<TabPane, Void> {
return offerBookView; return offerBookView;
} }
else if (navigationItem == FxmlView.CREATE_OFFER && createOfferView == null) { else if (viewClass == CreateOfferView.class && createOfferView == null) {
// CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times // CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times
// in different graphs // in different graphs
View view = viewLoader.load(navigationItem.getLocation()); View view = viewLoader.load(viewClass);
createOfferView = (CreateOfferView) view; createOfferView = (CreateOfferView) view;
createOfferView.initWithData(direction, amount, price); createOfferView.initWithData(direction, amount, price);
createOfferRoot = view.getRoot(); createOfferRoot = view.getRoot();
@ -150,11 +148,11 @@ public class TradeView extends ActivatableView<TabPane, Void> {
tabPane.getSelectionModel().select(tab); tabPane.getSelectionModel().select(tab);
return createOfferView; return createOfferView;
} }
else if (navigationItem == FxmlView.TAKE_OFFER && takeOfferView == null && else if (viewClass == TakeOfferView.class && takeOfferView == null &&
offer != null) { offer != null) {
// CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times // CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times
// in different graphs // in different graphs
View view = viewLoader.load(FxmlView.TAKE_OFFER.getLocation()); View view = viewLoader.load(TakeOfferView.class);
takeOfferView = (TakeOfferView) view; takeOfferView = (TakeOfferView) view;
takeOfferView.initWithData(direction, amount, offer); takeOfferView.initWithData(direction, amount, offer);
takeOfferRoot = view.getRoot(); takeOfferRoot = view.getRoot();
@ -173,14 +171,14 @@ public class TradeView extends ActivatableView<TabPane, Void> {
offerBookView.enableCreateOfferButton(); offerBookView.enableCreateOfferButton();
// update the navigation state // update the navigation state
navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK); navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class);
} }
private void onTakeOfferViewRemoved() { private void onTakeOfferViewRemoved() {
takeOfferView = null; takeOfferView = null;
// update the navigation state // update the navigation state
navigation.navigateTo(FxmlView.MAIN, navigationItem, FxmlView.OFFER_BOOK); navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class);
} }
} }

View file

@ -17,7 +17,6 @@
package io.bitsquare.gui.main.trade.createoffer; package io.bitsquare.gui.main.trade.createoffer;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.components.AddressTextField; import io.bitsquare.gui.components.AddressTextField;
@ -26,8 +25,14 @@ import io.bitsquare.gui.components.InfoDisplay;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.components.TitledGroupBg; import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
import io.bitsquare.gui.main.account.settings.AccountSettingsView;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; 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.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import io.bitsquare.offer.Direction; import io.bitsquare.offer.Direction;
@ -40,6 +45,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
@ -67,6 +73,7 @@ import static javafx.beans.binding.Bindings.createStringBinding;
// TODO Implement other positioning method in InoutTextField to display it over the field instead of right side // TODO Implement other positioning method in InoutTextField to display it over the field instead of right side
// priceAmountHBox is too large after redesign as to be used as layoutReference. // priceAmountHBox is too large after redesign as to be used as layoutReference.
@FxmlView
public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateOfferViewModel> { public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateOfferViewModel> {
@FXML ScrollPane scrollPane; @FXML ScrollPane scrollPane;
@ -222,17 +229,14 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
} }
private void openAccountSettings() { private void openAccountSettings() {
navigation.navigateTo(FxmlView.MAIN, navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, RestrictionsView.class);
FxmlView.ACCOUNT,
FxmlView.ACCOUNT_SETTINGS,
FxmlView.RESTRICTIONS);
} }
private void close() { private void close() {
TabPane tabPane = ((TabPane) (root.getParent().getParent())); TabPane tabPane = ((TabPane) (root.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, FxmlView.OFFERS); navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
} }
private void setupListeners() { private void setupListeners() {

View file

@ -17,11 +17,15 @@
package io.bitsquare.gui.main.trade.offerbook; package io.bitsquare.gui.main.trade.offerbook;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
import io.bitsquare.gui.main.account.settings.AccountSettingsView;
import io.bitsquare.gui.main.account.setup.AccountSetupWizard;
import io.bitsquare.gui.main.trade.TradeView; import io.bitsquare.gui.main.trade.TradeView;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.gui.util.validation.OptionalBtcValidator; import io.bitsquare.gui.util.validation.OptionalBtcValidator;
@ -36,8 +40,9 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.support.ActivatableViewAndModel;
import viewfx.view.ChildView; import viewfx.view.ChildView;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.transformation.SortedList; import javafx.collections.transformation.SortedList;
@ -55,6 +60,7 @@ import org.controlsfx.dialog.Dialog;
import static javafx.beans.binding.Bindings.createStringBinding; import static javafx.beans.binding.Bindings.createStringBinding;
@FxmlView
public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookViewModel> public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookViewModel>
implements ChildView<TradeView> { implements ChildView<TradeView> {
@ -204,8 +210,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
Dialog.Actions.OK.handle(actionEvent); Dialog.Actions.OK.handle(actionEvent);
overlayManager.removeBlurContent(); overlayManager.removeBlurContent();
navigation.setReturnPath(navigation.getCurrentPath()); navigation.setReturnPath(navigation.getCurrentPath());
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(MainView.class, AccountView.class, AccountSetupWizard.class);
FxmlView.ACCOUNT_SETUP);
} }
}); });
Popups.openInfoPopup("You don't have setup a trading account.", Popups.openInfoPopup("You don't have setup a trading account.",
@ -255,9 +260,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
actions); actions);
if (Popups.isYes(response)) if (Popups.isYes(response))
navigation.navigateTo(FxmlView.MAIN, FxmlView.ACCOUNT, navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, RestrictionsView.class);
FxmlView.ACCOUNT_SETTINGS,
FxmlView.RESTRICTIONS);
else else
table.getSelectionModel().clearSelection(); table.getSelectionModel().clearSelection();
} }

View file

@ -18,7 +18,6 @@
package io.bitsquare.gui.main.trade.takeoffer; package io.bitsquare.gui.main.trade.takeoffer;
import io.bitsquare.gui.FxmlView;
import io.bitsquare.gui.Navigation; import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.components.AddressTextField; import io.bitsquare.gui.components.AddressTextField;
@ -27,8 +26,11 @@ import io.bitsquare.gui.components.InfoDisplay;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.components.TitledGroupBg; import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.pending.PendingTradesView;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import io.bitsquare.offer.Direction; import io.bitsquare.offer.Direction;
@ -41,6 +43,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.FxmlView;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
@ -64,6 +67,7 @@ import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action; import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialog;
@FxmlView
public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOfferViewModel> { public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOfferViewModel> {
@FXML ScrollPane scrollPane; @FXML ScrollPane scrollPane;
@ -281,8 +285,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
getProperties().put("type", "CLOSE"); getProperties().put("type", "CLOSE");
try { try {
close(); close();
navigation.navigateTo(FxmlView.MAIN, FxmlView.PORTFOLIO, navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
FxmlView.PENDING_TRADES);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View file

@ -0,0 +1,25 @@
/*
* 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 viewfx;
public class ViewfxException extends RuntimeException {
public ViewfxException(Throwable cause, String format, Object... args) {
super(String.format(format, args), cause);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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 viewfx.view;
import java.util.function.Function;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.util.ClassUtils;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FxmlView {
/**
* The location of the FXML file associated with annotated {@link View} class. By default the location will be
* determined by {@link #convention()}.
*/
String location() default "";
/**
* The function used to determine the location of the FXML file associated with the annotated {@link View} class.
* By default it is the fully-qualified view class name, converted to a resource path, replacing the
* {@code .class} suffix replaced with {@code .fxml}.
*/
Class<? extends Function<Class<? extends View>, String>> convention() default DefaultFxmlPathConvention.class;
static class DefaultFxmlPathConvention implements Function<Class<? extends View>, String> {
@Override
public String apply(Class<? extends View> viewClass) {
return ClassUtils.convertClassNameToResourcePath(viewClass.getName()).concat(".fxml");
}
}
}

View file

@ -0,0 +1,46 @@
/*
* 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 viewfx.view;
import java.util.ArrayList;
import java.util.Arrays;
public class ViewPath extends ArrayList<Class<? extends View>> {
public ViewPath() {
}
public static ViewPath to(Class<? extends View>... elements) {
ViewPath path = new ViewPath();
path.addAll(Arrays.asList(elements));
return path;
}
public static ViewPath from(ViewPath original) {
ViewPath path = new ViewPath();
path.addAll(original);
return path;
}
public Class<? extends View> tip() {
if (size() == 0)
return null;
return get(size()-1);
}
}

View file

@ -25,12 +25,16 @@ import java.util.ResourceBundle;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.ViewfxException;
import viewfx.view.FxmlView;
import viewfx.view.View; import viewfx.view.View;
import viewfx.view.ViewFactory; import viewfx.view.ViewFactory;
import viewfx.view.ViewLoader; import viewfx.view.ViewLoader;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import org.springframework.core.annotation.AnnotationUtils;
public class FxmlViewLoader implements ViewLoader { public class FxmlViewLoader implements ViewLoader {
private final ViewFactory viewFactory; private final ViewFactory viewFactory;
@ -42,20 +46,41 @@ public class FxmlViewLoader implements ViewLoader {
this.resourceBundle = resourceBundle; this.resourceBundle = resourceBundle;
} }
public View load(Object location) { public View load(Class<?> clazz) {
if (!(location instanceof URL)) if (!View.class.isAssignableFrom(clazz))
throw new IllegalArgumentException("FXML view locations must be of type URL"); throw new IllegalArgumentException("Class must be of generic type Class<? extends View>: " + clazz);
URL url = (URL) location; @SuppressWarnings("unchecked")
Class<? extends View> viewClass = (Class<? extends View>) clazz;
FxmlView fxmlView = AnnotationUtils.getAnnotation(viewClass, FxmlView.class);
try {
String path = fxmlView.convention().newInstance().apply(viewClass);
return load(viewClass.getClassLoader().getResource(path));
} catch (InstantiationException | IllegalAccessException ex) {
throw new ViewfxException(ex, "Failed to load View from class %s", viewClass);
}
}
public View load(URL url) {
try { try {
FXMLLoader loader = new FXMLLoader(url, resourceBundle); FXMLLoader loader = new FXMLLoader(url, resourceBundle);
loader.setControllerFactory(viewFactory); loader.setControllerFactory(viewFactory);
loader.load(); loader.load();
return loader.getController(); return loader.getController();
} catch (IOException ex) { } catch (IOException ex) {
throw new RuntimeException("Failed to load View at location " + url, ex); throw new ViewfxException(ex, "Failed to load View at location %s", url);
} }
}
public View load(Object location) {
if (location instanceof URL)
return load((URL) location);
if (location instanceof Class<?>)
return load((Class) location);
throw new IllegalArgumentException("Argument is not of type URL or Class: " + location);
} }
} }

View file

@ -17,18 +17,21 @@
package io.bitsquare.app.gui; package io.bitsquare.app.gui;
import io.bitsquare.BitsquareException;
import io.bitsquare.app.BitsquareEnvironment; import io.bitsquare.app.BitsquareEnvironment;
import io.bitsquare.gui.FxmlView; import io.bitsquare.gui.main.funds.FundsView;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import viewfx.ViewfxException;
import viewfx.view.support.fxml.FxmlViewLoader; import viewfx.view.support.fxml.FxmlViewLoader;
import viewfx.view.support.guice.GuiceViewFactory; import viewfx.view.support.guice.GuiceViewFactory;
@ -79,13 +82,26 @@ public class ViewLoaderTests {
resourceBundle = BSResources.getResourceBundle(); resourceBundle = BSResources.getResourceBundle();
} }
@Test(expected = BitsquareException.class) @Test(expected = ViewfxException.class)
public void loadingBogusFxmlResourceShouldThrow() throws MalformedURLException { public void loadingBogusFxmlResourceShouldThrow() throws MalformedURLException {
new FxmlViewLoader(viewFactory, resourceBundle).load(FxmlView.BOGUS.getLocation()); URL uri = new File("/tmp/bogus1234").toURI().toURL();
new FxmlViewLoader(viewFactory, resourceBundle).load(uri);
} }
@Test @Test
public void loadingValidFxmlResourceShouldNotThrow() { public void loadingValidFxmlResourceShouldNotThrow() throws MalformedURLException {
new FxmlViewLoader(viewFactory, resourceBundle).load(FxmlView.ACCOUNT.getLocation()); String path = "/Users/cbeams/Desktop/bitsquare/bitsquare/build/resources/main/" +
"io/bitsquare/gui/main/account/AccountView.fxml";
new FxmlViewLoader(viewFactory, resourceBundle).load(new File(path).toURI().toURL());
}
@Test
public void loadingFromValidFxmlViewClassShouldNotThrow() {
new FxmlViewLoader(viewFactory, resourceBundle).load(FundsView.class);
}
@Test(expected = IllegalArgumentException.class)
public void loadingFromNonViewClassShouldThrow() {
new FxmlViewLoader(viewFactory, resourceBundle).load(File.class);
} }
} }