Skip to content

Commit

Permalink
Documentation & renaming a couple of methods for consistency and
Browse files Browse the repository at this point in the history
conciseness.
  • Loading branch information
rx committed Jan 6, 2017
1 parent 30aae7b commit 1250f17
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 59 deletions.
@@ -1,83 +1,164 @@
package com.insightfullogic.honest_profiler.ports.javafx.controller;

import java.util.ResourceBundle;

import com.insightfullogic.honest_profiler.ports.javafx.model.ApplicationContext;

import javafx.scene.Node;
import javafx.scene.control.Tab;

/**
* Superclass for all Controllers in the application. It holds the context which is shared by all controllers.
*/
public abstract class AbstractController
{
private ApplicationContext applicationContext;

/**
* Sets the application context.
*
* @param applicationContext the ApplicationContext of this application
*/
public void setApplicationContext(ApplicationContext applicationContext)
{
this.applicationContext = applicationContext;
}

/**
* Gets the {@link ApplicationContext}. The name has been shortened to unclutter code in subclasses.
*
* @return the {@link ApplicationContext} of this application.
*/
protected ApplicationContext appCtx()
{
return applicationContext;
}

/**
* Look up the String associated with this key in the current {@link ResourceBundle}.
*
* @param key the key in the ResourceBundle
* @return the String associated with the key in the curremt {@link ResourceBundle}
*/
protected final String getText(String key)
{
return applicationContext.textFor(key);
}

/**
* Construct the String based on the pattern associated with this key in the current {@link ResourceBundle}, using
* the provided arguments.
*
* @param key the key in the ResourceBundle
* @param args the arguments needed by the pattern
* @return the String constructed using the pattern and provided arguments
*/
protected final String getText(String key, Object... args)
{
return applicationContext.textFor(key, args);
}

protected final void info(String message)
{
applicationContext.setInfo(message);
}

/**
* Display a message in the InfoBar, by retrieving the message from the current {@link ResourceBundle} using the
* provided key.
*
* @param message the key to the message in the {@link ResourceBundle}
*/
protected final void infoFromBundle(String key)
{
applicationContext.setInfoFromBundle(key);
}

/**
* Display a message in the InfoBar, by retrieving the pattern from the current {@link ResourceBundle} using the
* provided key and formatting it using the provided arguments.
*
* @param message the key to the message pattern in the {@link ResourceBundle}
* @param args the arguments needed by the pattern
*/
protected final void infoFromBundle(String key, Object... args)
{
applicationContext.setInfoFromBundle(key, args);
}

/**
* Clears the InfoBar
*/
protected final void clearInfo()
{
applicationContext.setInfo("");
}

/**
* Associates a message with a given Node. The message is retrieved from the current {@link ResourceBundle} using
* the provided key, and is displayed while the InfoBar whenever the mouse hovers over the Node.
*
* @param node the target Node
* @param key the key to the message in the {@link ResourceBundle}
*/
protected void info(Node node, final String key)
{
node.onMouseEnteredProperty().set(event -> infoFromBundle(key));
node.onMouseExitedProperty().set(event -> clearInfo());
}

/**
* Associates a message with a given Node. The message pattern is retrieved from the current {@link ResourceBundle}
* using the provided key, formatted using the provided arguments, and displayed while the InfoBar whenever the
* mouse hovers over the Node.
*
* @param node the target Node
* @param key the key to the message in the {@link ResourceBundle}
* @param args the arguments needed by the pattern
*/
protected void info(Node node, final String key, Object... args)
{
node.onMouseEnteredProperty().set(event -> infoFromBundle(key, args));
node.onMouseExitedProperty().set(event -> clearInfo());
}

/**
* Associates a message with a Tab Header, as per {@link #info(Node, String)}.
*
* @param tab the target Tab
* @param key the key to the message in the {@link ResourceBundle}
*/
protected void info(Tab tab, final String key)
{
info(tab.getGraphic(), key);
}

/**
* Associates a message with a Tab Header, as per {@link #info(Node, String, Object...)}.
*
* @param tab the target Tab
* @param key the key to the message in the {@link ResourceBundle}
* @param args the arguments needed by the pattern
*/
protected void info(Tab tab, final String key, Object... args)
{
info(tab.getGraphic(), key, args);
}

/**
* This method must be called by subclasses in their FXML initialize(). The idea is to streamline similar tasks
* happening in the initialization method, and encourage decluttering of those methods by extracting similar tasks
* to separate methods.
*/
protected void initialize()
{
initializeInfoText();
initializeHandlers();
}

/**
* Link nodes with "InfoBar" messages. The InfoBar is the info- or statusbar at the bottom of the UI. While hovering
* over various nodes, helpful information should appear in the InfoBar.
*/
protected abstract void initializeInfoText();

/**
* Associate various Handlers and/or Listeners with the nodes managed by the controller.
*/
protected abstract void initializeHandlers();
}
Expand Up @@ -13,6 +13,7 @@
import com.insightfullogic.honest_profiler.core.filters.Filter;
import com.insightfullogic.honest_profiler.core.filters.ProfileFilter;
import com.insightfullogic.honest_profiler.core.filters.StringFilter;
import com.insightfullogic.honest_profiler.core.profiles.Profile;
import com.insightfullogic.honest_profiler.ports.javafx.controller.filter.FilterDialogController;
import com.insightfullogic.honest_profiler.ports.javafx.model.ApplicationContext;
import com.insightfullogic.honest_profiler.ports.javafx.model.filter.FilterSpecification;
Expand All @@ -25,6 +26,10 @@
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;

/**
* Superclass for all View Controllers in the application. These controllers provide a particular view on data. The
* class holds the code for the filters and quick filter.
*/
public abstract class AbstractViewController extends AbstractController
{
private Button filterButton;
Expand All @@ -38,6 +43,14 @@ public abstract class AbstractViewController extends AbstractController
private ProfileFilter currentFilter = new ProfileFilter();
private StringFilter quickFilter;

/**
* This method must be called by subclasses in their FXML initialize(). It provides the controller-local UI nodes
* needed by the AbstractViewController.
*
* @param filterButton the button used to trigger filter editing
* @param quickFilterButton the button used to apply the quick filter
* @param quickFilterText the TextField providing the value for the quick filter
*/
protected void initialize(Button filterButton, Button quickFilterButton,
TextField quickFilterText)
{
Expand All @@ -53,6 +66,12 @@ protected void initialize(Button filterButton, Button quickFilterButton,
this.quickFilterText = quickFilterText;
}

/**
* In addition to the normal functionality, the method calls filter initialization, which needs the
* ApplicationContext to be present. If a particular view controller
*
* @param applicationContext the ApplicationContext of this application
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
{
Expand All @@ -66,11 +85,34 @@ public void setApplicationContext(ApplicationContext applicationContext)
initializeFilters(applicationContext);
}

/**
* View Controllers must implement this, and return the {@link FilterType}s which are supported by them.
*
* @return an array containing the {@link FilterType}s supported by the view controller
*/
protected abstract FilterType[] getAllowedFilterTypes();

/**
* Refreshes the view. The view should be updated based on the current state of the {@link Profile} and
* {@link ProfileFilter}.
*/
protected abstract void refresh();

/**
* Returns the current {@link FilterSpecification}.
*
* @return the current {@link FilterSpecification}
*/
protected ObjectProperty<FilterSpecification> getFilterSpecification()
{
return filterSpec;
}

/**
* Returns the currently active {@link ProfileFilter}, constructed from the current filters and the quick filter.
*
* @return the currently active {@link ProfileFilter}
*/
protected ProfileFilter getAdjustedProfileFilter()
{
if (quickFilter == null)
Expand All @@ -84,8 +126,12 @@ protected ProfileFilter getAdjustedProfileFilter()
return new ProfileFilter(filters);
}

// The appCtxt parameter is here to make explicit that the method depends on
// its presence.
/**
* Initializes the filters.
*
* @param applicationContext the {@link ApplicationContext}. The parameter is used to explicitly point out the
* dependency on the presense of the context.
*/
private void initializeFilters(ApplicationContext applicationContext)
{
dialogController = createFilterDialog();
Expand Down Expand Up @@ -131,8 +177,4 @@ private void applyQuickFilter()
input);
refresh();
}

protected abstract FilterType[] getAllowedFilterTypes();

protected abstract void refresh();
}
Expand Up @@ -143,12 +143,12 @@ public void setProfileContexts(ProfileContext baseContext, ProfileContext newCon
configurePercentColumn(
baseSelfTime,
"baseSelfTimeShare",
baseContext(),
baseCtx(),
getText(COLUMN_SELF_PCT));
configurePercentColumn(
newSelfTime,
"newSelfTimeShare",
newContext(),
newCtx(),
getText(COLUMN_SELF_PCT));
configurePercentColumn(
selfTimeDiff,
Expand All @@ -159,12 +159,12 @@ public void setProfileContexts(ProfileContext baseContext, ProfileContext newCon
configurePercentColumn(
baseTotalTime,
"baseTotalTimeShare",
baseContext(),
baseCtx(),
getText(COLUMN_TOTAL_PCT));
configurePercentColumn(
newTotalTime,
"newTotalTimeShare",
newContext(),
newCtx(),
getText(COLUMN_TOTAL_PCT));
configurePercentColumn(
totalTimeDiff,
Expand All @@ -175,9 +175,9 @@ public void setProfileContexts(ProfileContext baseContext, ProfileContext newCon
configureCountColumn(
baseSelfCount,
"baseSelfCount",
baseContext(),
baseCtx(),
getText(COLUMN_SELF_CNT));
configureCountColumn(newSelfCount, "newSelfCount", newContext(), getText(COLUMN_SELF_CNT));
configureCountColumn(newSelfCount, "newSelfCount", newCtx(), getText(COLUMN_SELF_CNT));
configureCountDiffColumn(
selfCountDiff,
data -> new ReadOnlyIntegerWrapper(
Expand All @@ -188,12 +188,12 @@ public void setProfileContexts(ProfileContext baseContext, ProfileContext newCon
configureCountColumn(
baseTotalCount,
"baseTotalCount",
baseContext(),
baseCtx(),
getText(COLUMN_TOTAL_CNT));
configureCountColumn(
newTotalCount,
"newTotalCount",
newContext(),
newCtx(),
getText(COLUMN_TOTAL_CNT));
configureCountDiffColumn(
totalCountDiff,
Expand All @@ -205,12 +205,12 @@ public void setProfileContexts(ProfileContext baseContext, ProfileContext newCon
configureCountColumn(
baseTraceCount,
"baseTraceCount",
baseContext(),
baseCtx(),
getText(COLUMN_PROFILE_CNT));
configureCountColumn(
newTraceCount,
"newTraceCount",
newContext(),
newCtx(),
getText(COLUMN_PROFILE_CNT));
configureCountDiffColumn(
traceCountDiff,
Expand Down

0 comments on commit 1250f17

Please sign in to comment.