Refactor ViewLoader

This commit is contained in:
Chris Beams 2014-11-23 19:58:43 +01:00
parent d120dcad06
commit 318bfc5fb0
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
15 changed files with 62 additions and 68 deletions

View file

@ -40,6 +40,8 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import viewfx.view.View;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.*; import javafx.scene.*;
import javafx.scene.image.*; import javafx.scene.image.*;
@ -94,9 +96,9 @@ 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(ViewLoader.class); ViewLoader viewLoader = injector.getInstance(ViewLoader.class);
ViewLoader.Item loaded = viewLoader.load(Navigation.Item.MAIN.getFxmlUrl(), false); View view = viewLoader.load(Navigation.Item.MAIN.getFxmlUrl(), false);
Scene scene = new Scene((Parent) loaded.view, 1000, 600); Scene scene = new Scene((Parent) view.getRoot(), 1000, 600);
scene.getStylesheets().setAll( scene.getStylesheets().setAll(
"/io/bitsquare/gui/bitsquare.css", "/io/bitsquare/gui/bitsquare.css",
"/io/bitsquare/gui/images.css"); "/io/bitsquare/gui/images.css");

View file

@ -17,11 +17,8 @@
package io.bitsquare.gui; package io.bitsquare.gui;
import io.bitsquare.BitsquareException;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
@ -29,10 +26,10 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.View;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory; import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.*;
import javafx.util.BuilderFactory; import javafx.util.BuilderFactory;
/** /**
@ -41,7 +38,7 @@ import javafx.util.BuilderFactory;
*/ */
public class ViewLoader { public class ViewLoader {
private final Map<URL, Item> cache = new HashMap<>(); private final Map<URL, View> cache = new HashMap<>();
private final BuilderFactory builderFactory = new JavaFXBuilderFactory(); private final BuilderFactory builderFactory = new JavaFXBuilderFactory();
private final GuiceControllerFactory controllerFactory; private final GuiceControllerFactory controllerFactory;
@ -50,35 +47,18 @@ public class ViewLoader {
this.controllerFactory = controllerFactory; this.controllerFactory = controllerFactory;
} }
public Item load(URL url) { public View load(URL url) {
return load(url, true); return load(url, true);
} }
public Item load(URL url, boolean useCaching) { public View load(URL url, boolean useCaching) {
Item item; if (useCaching && cache.containsKey(url))
if (useCaching && cache.containsKey(url)) {
return cache.get(url); return cache.get(url);
}
FXMLLoader loader = new FXMLLoader(url, BSResources.getResourceBundle(), builderFactory, controllerFactory); FXMLLoader loader = new FXMLLoader(url, BSResources.getResourceBundle(), builderFactory, controllerFactory);
try { View view = loader.getController();
item = new Item(loader.load(), loader.getController()); cache.put(url, view);
cache.put(url, item); return view;
return item;
} catch (IOException e) {
throw new BitsquareException(e, "Failed to load view at %s", url);
}
}
public static class Item {
public final Node view;
public final Initializable controller;
Item(Node view, Initializable controller) {
this.view = view;
this.controller = controller;
}
} }
} }

View file

@ -29,6 +29,7 @@ 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.View;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
import javafx.application.Platform; import javafx.application.Platform;
@ -125,8 +126,8 @@ public class MainView extends ActivatableView<StackPane, MainViewModel> {
if (navItems == null || navItems.length != 2 || navItems[0] != Navigation.Item.MAIN) if (navItems == null || navItems.length != 2 || navItems[0] != Navigation.Item.MAIN)
return; return;
ViewLoader.Item loaded = viewLoader.load(navItems[1].getFxmlUrl()); View view = viewLoader.load(navItems[1].getFxmlUrl());
contentContainer.getChildren().setAll(loaded.view); contentContainer.getChildren().setAll(view.getRoot());
navButtons.getToggles().stream() navButtons.getToggles().stream()
.filter(toggle -> toggle instanceof ToggleButton) .filter(toggle -> toggle instanceof ToggleButton)

View file

@ -22,6 +22,7 @@ import io.bitsquare.gui.ViewLoader;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.View;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@ -95,7 +96,7 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
private void loadView(Navigation.Item navigationItem) { private void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
final Tab tab; final Tab tab;
switch (navigationItem) { switch (navigationItem) {
case ACCOUNT_SETTINGS: case ACCOUNT_SETTINGS:
@ -118,7 +119,7 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
// for IRC demo we deactivate the arbitratorSettingsTab // for IRC demo we deactivate the arbitratorSettingsTab
arbitratorSettingsTab.setDisable(true); arbitratorSettingsTab.setDisable(true);
tab.setContent(loaded.view); tab.setContent(view.getRoot());
root.getSelectionModel().select(tab); root.getSelectionModel().select(tab);
} }
} }

View file

@ -23,6 +23,7 @@ import io.bitsquare.gui.main.account.arbitrator.registration.ArbitratorRegistrat
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.View;
import viewfx.view.support.AbstractView; import viewfx.view.support.AbstractView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -47,8 +48,8 @@ class ArbitratorSettingsView extends AbstractView {
} }
private void loadView(Navigation.Item navigationItem) { private void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl(), false); View view = viewLoader.load(navigationItem.getFxmlUrl(), false);
arbitratorRegistrationView = (ArbitratorRegistrationView) loaded.controller; arbitratorRegistrationView = (ArbitratorRegistrationView) view;
final Stage stage = new Stage(); final Stage stage = new Stage();
stage.setTitle("Arbitrator"); stage.setTitle("Arbitrator");
@ -60,7 +61,7 @@ class ArbitratorSettingsView extends AbstractView {
stage.setY(primaryStage.getY() + 50); stage.setY(primaryStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL); stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(primaryStage); stage.initOwner(primaryStage);
Scene scene = new Scene((Parent) loaded.view, 800, 600); Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
stage.setScene(scene); stage.setScene(scene);
stage.show(); stage.show();
} }

View file

@ -32,6 +32,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.view.View;
import viewfx.view.support.ActivatableView; import viewfx.view.support.ActivatableView;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -91,9 +92,9 @@ class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements Arbit
private void loadView(Navigation.Item navigationItem) { private void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
root.getChildren().set(0, loaded.view); root.getChildren().set(0, view.getRoot());
arbitratorProfileView = (ArbitratorProfileView) loaded.controller; arbitratorProfileView = (ArbitratorProfileView) view;
} }
@Override @Override

View file

@ -146,7 +146,7 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
} }
private void loadView(Navigation.Item navigationItem) { private void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl(), false); View view = viewLoader.load(navigationItem.getFxmlUrl(), false);
final Stage stage = new Stage(); final Stage stage = new Stage();
stage.setTitle("Arbitrator selection"); stage.setTitle("Arbitrator selection");
@ -158,7 +158,7 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
stage.setY(primaryStage.getY() + 50); stage.setY(primaryStage.getY() + 50);
stage.initModality(Modality.WINDOW_MODAL); stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(primaryStage); stage.initOwner(primaryStage);
Scene scene = new Scene((Parent) loaded.view, 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 == Navigation.Item.ARBITRATOR_BROWSER) if (navigationItem == Navigation.Item.ARBITRATOR_BROWSER)

View file

@ -109,11 +109,10 @@ class AccountSettingsView extends ActivatableViewAndModel {
} }
private void loadView(Navigation.Item navigationItem) { private void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
content.getChildren().setAll(loaded.view); content.getChildren().setAll(view.getRoot());
View child = (View) loaded.controller; if (view instanceof Wizard.Step)
if (child instanceof Wizard.Step) ((Wizard.Step) view).hideWizardNavigation();
((Wizard.Step) child).hideWizardNavigation();
} }
private void selectMainMenuButton(Navigation.Item item) { private void selectMainMenuButton(Navigation.Item item) {

View file

@ -153,11 +153,10 @@ class AccountSetupWizard extends ActivatableView implements Wizard {
} }
protected void loadView(Navigation.Item navigationItem) { protected void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
content.getChildren().setAll(loaded.view); content.getChildren().setAll(view.getRoot());
View child = (View) loaded.controller; if (view instanceof Wizard.Step)
if (child instanceof Wizard.Step) ((Step) view).setParent(this);
((Step) child).setParent(this);
} }
} }

View file

@ -23,6 +23,7 @@ import io.bitsquare.gui.ViewLoader;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.model.Activatable; import viewfx.model.Activatable;
import viewfx.view.View;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@ -84,7 +85,7 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
if (currentTab != null) if (currentTab != null)
currentTab.setContent(null); currentTab.setContent(null);
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
switch (navigationItem) { switch (navigationItem) {
case WITHDRAWAL: case WITHDRAWAL:
currentTab = withdrawalTab; currentTab = withdrawalTab;
@ -93,7 +94,7 @@ class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
currentTab = transactionsTab; currentTab = transactionsTab;
break; break;
} }
currentTab.setContent(loaded.view); currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab); root.getSelectionModel().select(currentTab);
} }
} }

View file

@ -24,6 +24,7 @@ import io.bitsquare.trade.TradeManager;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.model.Activatable; import viewfx.model.Activatable;
import viewfx.view.View;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@ -92,7 +93,7 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
if (currentTab != null) if (currentTab != null)
currentTab.setContent(null); currentTab.setContent(null);
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
switch (navigationItem) { switch (navigationItem) {
case OFFERS: case OFFERS:
currentTab = offersTab; currentTab = offersTab;
@ -104,7 +105,7 @@ class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable> {
currentTab = closedTradesTab; currentTab = closedTradesTab;
break; break;
} }
currentTab.setContent(loaded.view); currentTab.setContent(view.getRoot());
root.getSelectionModel().select(currentTab); root.getSelectionModel().select(currentTab);
} }
} }

View file

@ -24,6 +24,7 @@ import io.bitsquare.settings.Preferences;
import javax.inject.Inject; import javax.inject.Inject;
import viewfx.model.Activatable; import viewfx.model.Activatable;
import viewfx.view.View;
import viewfx.view.support.ActivatableViewAndModel; import viewfx.view.support.ActivatableViewAndModel;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@ -88,7 +89,7 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
} }
private void loadView(Navigation.Item navigationItem) { private void loadView(Navigation.Item navigationItem) {
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl()); View view = viewLoader.load(navigationItem.getFxmlUrl());
final Tab tab; final Tab tab;
switch (navigationItem) { switch (navigationItem) {
case PREFERENCES: case PREFERENCES:
@ -100,7 +101,7 @@ class SettingsView extends ActivatableViewAndModel<TabPane, Activatable> {
default: default:
throw new IllegalArgumentException("navigation item of type " + navigationItem + " is not allowed"); throw new IllegalArgumentException("navigation item of type " + navigationItem + " is not allowed");
} }
tab.setContent(loaded.view); tab.setContent(view.getRoot());
root.getSelectionModel().select(tab); root.getSelectionModel().select(tab);
} }
} }

View file

@ -122,12 +122,12 @@ public class TradeView extends ActivatableView<TabPane, Void> {
TabPane tabPane = root; TabPane tabPane = root;
if (navigationItem == Navigation.Item.OFFER_BOOK && offerBookView == null) { if (navigationItem == Navigation.Item.OFFER_BOOK && 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.
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl(), false); View view = viewLoader.load(navigationItem.getFxmlUrl(), false);
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(loaded.view); tab.setContent(view.getRoot());
tabPane.getTabs().add(tab); tabPane.getTabs().add(tab);
offerBookView = (OfferBookView) loaded.controller; offerBookView = (OfferBookView) view;
offerBookView.setParent(this); offerBookView.setParent(this);
offerBookView.setDirection(direction); offerBookView.setDirection(direction);
@ -137,10 +137,10 @@ public class TradeView extends ActivatableView<TabPane, Void> {
else if (navigationItem == Navigation.Item.CREATE_OFFER && createOfferView == null) { else if (navigationItem == Navigation.Item.CREATE_OFFER && 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
ViewLoader.Item loaded = viewLoader.load(navigationItem.getFxmlUrl(), false); View view = viewLoader.load(navigationItem.getFxmlUrl(), false);
createOfferRoot = loaded.view; createOfferView = (CreateOfferView) view;
createOfferView = (CreateOfferView) loaded.controller;
createOfferView.initWithData(direction, amount, price); createOfferView.initWithData(direction, amount, price);
createOfferRoot = view.getRoot();
final Tab tab = new Tab("Create offer"); final Tab tab = new Tab("Create offer");
createOfferView.configCloseHandlers(tab.closableProperty()); createOfferView.configCloseHandlers(tab.closableProperty());
tab.setContent(createOfferRoot); tab.setContent(createOfferRoot);
@ -152,10 +152,10 @@ public class TradeView extends ActivatableView<TabPane, Void> {
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
ViewLoader.Item loaded = viewLoader.load(Navigation.Item.TAKE_OFFER.getFxmlUrl(), false); View view = viewLoader.load(Navigation.Item.TAKE_OFFER.getFxmlUrl(), false);
takeOfferRoot = loaded.view; takeOfferView = (TakeOfferView) view;
takeOfferView = (TakeOfferView) loaded.controller;
takeOfferView.initWithData(direction, amount, offer); takeOfferView.initWithData(direction, amount, offer);
takeOfferRoot = view.getRoot();
final Tab tab = new Tab("Take offer"); final Tab tab = new Tab("Take offer");
takeOfferView.configCloseHandlers(tab.closableProperty()); takeOfferView.configCloseHandlers(tab.closableProperty());
tab.setContent(takeOfferRoot); tab.setContent(takeOfferRoot);

View file

@ -17,5 +17,8 @@
package viewfx.view; package viewfx.view;
import javafx.scene.*;
public interface View { public interface View {
Node getRoot();
} }

View file

@ -39,4 +39,8 @@ public abstract class AbstractView<R extends Node, M> implements View {
public AbstractView() { public AbstractView() {
this(null); this(null);
} }
public R getRoot() {
return root;
}
} }