fixed caching tabpane

This commit is contained in:
Manfred Karrer 2014-08-08 18:07:39 +02:00
parent 7d72122a91
commit 83203554e9
7 changed files with 140 additions and 157 deletions

View file

@ -0,0 +1,130 @@
package io.bitsquare.gui.components;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.locale.Localisation;
import io.bitsquare.storage.Persistence;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.Node;
import javafx.scene.control.TabPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* That class caches the already created views in a tab pane.
* So when switching back to an already opened tab it is faster as no fxml loading is needed anymore.
*/
public class CachingTabPane extends TabPane
{
private static final Logger log = LoggerFactory.getLogger(CachingTabPane.class);
private final List<TabInfo> tabInfoList = new ArrayList<>();
private NavigationController navigationController;
private Persistence persistence;
private int selectedTabIndex;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public CachingTabPane()
{
super();
}
public void initialize(NavigationController navigationController, Persistence persistence, String... tabContentFXMLUrls)
{
if (tabContentFXMLUrls.length == 0)
{
throw new IllegalArgumentException("No tabContentFXMLUrls defined");
}
this.navigationController = navigationController;
this.persistence = persistence;
for (String tabContentFXMLUrl : tabContentFXMLUrls) tabInfoList.add(new TabInfo(tabContentFXMLUrl));
getSelectionModel().selectedItemProperty().addListener((observableValue, oldTab, newTab) -> onTabSelectedIndexChanged());
// use parent to read selectedTabIndex
Object indexObject = persistence.read(navigationController, "selectedTabIndex");
selectedTabIndex = (indexObject == null) ? 0 : (int) indexObject;
if (selectedTabIndex == 0) onTabSelectedIndexChanged();
getSelectionModel().select(selectedTabIndex);
}
public void cleanup()
{
if (tabInfoList.get(selectedTabIndex).controller != null)
tabInfoList.get(selectedTabIndex).controller.cleanup();
}
public ChildController navigateToView(String fxmlView)
{
for (int i = 0; i < tabInfoList.size(); i++)
{
if (tabInfoList.get(i).url.equals(fxmlView))
{
getSelectionModel().select(i);
return tabInfoList.get(selectedTabIndex).controller;
}
}
// if not found
throw new IllegalArgumentException("fxmlView not defined in tabContentFXMLUrlMap.");
}
private void onTabSelectedIndexChanged()
{
selectedTabIndex = getSelectionModel().getSelectedIndex();
if (tabInfoList.get(selectedTabIndex).controller != null)
{
// set old one to sleep
((Hibernate) tabInfoList.get(selectedTabIndex).controller).sleep();
}
else
{
// load for the first time
String fxmlView = tabInfoList.get(selectedTabIndex).url;
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
try
{
tabInfoList.get(selectedTabIndex).view = loader.load();
tabInfoList.get(selectedTabIndex).controller = loader.getController();
} catch (IOException e)
{
e.printStackTrace();
}
}
getSelectionModel().getSelectedItem().setContent(tabInfoList.get(selectedTabIndex).view);
tabInfoList.get(selectedTabIndex).controller.setNavigationController(navigationController);
((Hibernate) tabInfoList.get(selectedTabIndex).controller).awake();
// use parent to write selectedTabIndex
persistence.write(navigationController, "selectedTabIndex", selectedTabIndex);
}
public void setSelectedTabIndex(int selectedTabIndex)
{
getSelectionModel().select(selectedTabIndex);
}
}
class TabInfo
{
Node view;
ChildController controller;
final String url;
TabInfo(String url)
{
this.url = url;
}
}

View file

@ -1,146 +0,0 @@
package io.bitsquare.gui.components;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.locale.Localisation;
import io.bitsquare.storage.Persistence;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javafx.scene.Node;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LazyLoadingTabPane extends TabPane
{
private static final Logger log = LoggerFactory.getLogger(LazyLoadingTabPane.class);
private final Map<Integer, Node> views = new HashMap<>();
private final Map<Integer, ChildController> controllers = new HashMap<>();
private SingleSelectionModel<Tab> selectionModel;
private NavigationController navigationController;
private String[] tabContentFXMLUrls;
private Persistence persistence;
private ChildController childController;
private int selectedTabIndex = -1;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public LazyLoadingTabPane()
{
super();
}
public void initialize(NavigationController navigationController, Persistence persistence, String... tabContentFXMLUrls)
{
if (tabContentFXMLUrls.length == 0)
{
throw new IllegalArgumentException("No tabContentFXMLUrls defined");
}
this.navigationController = navigationController;
this.tabContentFXMLUrls = tabContentFXMLUrls;
this.persistence = persistence;
selectionModel = getSelectionModel();
selectionModel.selectedItemProperty().addListener((observableValue, oldTab, newTab) -> onTabSelectedIndexChanged());
if (selectedTabIndex == -1)
{
Object indexObject = persistence.read(this, "selectedTabIndex");
log.trace("saved index" + indexObject);
if (indexObject != null)
{
selectionModel.select((int) indexObject);
}
}
else
{
selectionModel.select(selectedTabIndex);
}
onTabSelectedIndexChanged();
}
public void cleanup()
{
if (childController != null)
{
childController.cleanup();
}
}
public ChildController navigateToView(String fxmlView)
{
for (int i = 0; i < tabContentFXMLUrls.length; i++)
{
if (tabContentFXMLUrls[i].equals(fxmlView))
{
selectionModel.select(i);
return childController;
}
i++;
}
return null;
}
private void onTabSelectedIndexChanged()
{
int index = selectionModel.getSelectedIndex();
log.trace("onTabSelectedIndexChanged index" + index);
if (index < tabContentFXMLUrls.length && index >= 0)
{
if (childController != null)
{
((Hibernate) childController).sleep();
}
Node view = null;
if (index < views.size())
{
view = views.get(index);
childController = controllers.get(index);
}
if (view == null)
{
String fxmlView = tabContentFXMLUrls[index];
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
try
{
view = loader.load();
log.debug("######## " + view.toString());
views.put(index, view);
childController = loader.getController();
childController.setNavigationController(navigationController);
controllers.put(index, childController);
} catch (IOException e)
{
e.printStackTrace();
}
}
selectionModel.getSelectedItem().setContent(view);
if (childController != null)
{
childController.setNavigationController(navigationController);
((Hibernate) childController).awake();
}
persistence.write(this, "selectedTabIndex", index);
}
}
public void setSelectedTabIndex(int selectedTabIndex)
{
this.selectedTabIndex = selectedTabIndex;
}
}

View file

@ -3,7 +3,7 @@ package io.bitsquare.gui.funds;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.components.LazyLoadingTabPane;
import io.bitsquare.gui.components.CachingTabPane;
import io.bitsquare.storage.Persistence;
import java.net.URL;
import java.util.ResourceBundle;
@ -19,7 +19,7 @@ public class FundsController implements Initializable, ChildController, Navigati
private final Persistence persistence;
@FXML
private LazyLoadingTabPane tabPane;
private CachingTabPane tabPane;
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import io.bitsquare.gui.components.LazyLoadingTabPane?>
<?import io.bitsquare.gui.components.CachingTabPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.AnchorPane?>
<LazyLoadingTabPane xmlns:fx="http://javafx.com/fxml/1" fx:id="tabPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
<CachingTabPane xmlns:fx="http://javafx.com/fxml/1" fx:id="tabPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.funds.FundsController">
<Tab text="Deposit" closable="false"/>
<Tab text="Withdrawal" closable="false"/>
<Tab text="Transactions" closable="false"/>
</LazyLoadingTabPane>
</CachingTabPane>

View file

@ -3,7 +3,7 @@ package io.bitsquare.gui.orders;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.components.LazyLoadingTabPane;
import io.bitsquare.gui.components.CachingTabPane;
import io.bitsquare.storage.Persistence;
import java.net.URL;
import java.util.ResourceBundle;
@ -20,7 +20,7 @@ public class OrdersController implements Initializable, ChildController, Navigat
private static OrdersController INSTANCE;
private final Persistence persistence;
@FXML
private LazyLoadingTabPane tabPane;
private CachingTabPane tabPane;
@Inject
private OrdersController(Persistence persistence)

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import io.bitsquare.gui.components.LazyLoadingTabPane?>
<?import io.bitsquare.gui.components.CachingTabPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.AnchorPane?>
<LazyLoadingTabPane xmlns:fx="http://javafx.com/fxml/1" fx:id="tabPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
<CachingTabPane xmlns:fx="http://javafx.com/fxml/1" fx:id="tabPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.orders.OrdersController">
<Tab text="Open offers" closable="false"/>
<Tab text="Pending trades" closable="false"/>
<Tab text="Closed trades" closable="false"/>
</LazyLoadingTabPane>
</CachingTabPane>

View file

@ -137,7 +137,6 @@ public class Persistence
return read(classInstance.getClass().getName());
}
public Serializable read(Object classInstance, String propertyKey)
{
return read(classInstance.getClass().getName() + "." + propertyKey);