From 1fe61565278b30dc5779b67a0855f60fe2a56209 Mon Sep 17 00:00:00 2001 From: Vova Perebykivskyi Date: Thu, 13 Oct 2016 11:49:04 +0300 Subject: [PATCH] Merge ganttzk module with ZK branch. --- ganttzk/pom.xml | 11 +- .../zkoss/ganttz/CommandContextualized.java | 17 +- .../ganttz/CommandOnTaskContextualized.java | 30 +- .../java/org/zkoss/ganttz/DependencyList.java | 161 ++--- .../java/org/zkoss/ganttz/GanttPanel.java | 66 +- .../java/org/zkoss/ganttz/IDatesMapper.java | 2 +- .../main/java/org/zkoss/ganttz/LeftPane.java | 26 +- .../java/org/zkoss/ganttz/LeftTasksTree.java | 648 +++++++++--------- .../org/zkoss/ganttz/LeftTasksTreeRow.java | 120 +--- .../main/java/org/zkoss/ganttz/Planner.java | 355 +++++----- .../java/org/zkoss/ganttz/TabsRegistry.java | 29 +- .../java/org/zkoss/ganttz/TaskComponent.java | 150 ++-- .../zkoss/ganttz/TaskEditFormComposer.java | 34 +- .../main/java/org/zkoss/ganttz/TaskList.java | 66 +- .../main/java/org/zkoss/ganttz/data/Task.java | 23 +- .../org/zkoss/ganttz/data/TaskContainer.java | 35 +- .../ganttz/data/resourceload/LoadLevel.java | 4 + .../data/resourceload/LoadTimeLine.java | 49 +- .../data/resourceload/TimeLineRole.java | 26 +- .../org/zkoss/ganttz/extensions/ICommand.java | 13 +- .../org/zkoss/ganttz/i18n/I18nHelper.java | 15 +- .../resourceload/IFilterChangedListener.java | 2 +- .../IPaginationFilterChangedListener.java | 2 +- .../resourceload/ISeeScheduledOfListener.java | 2 +- .../resourceload/ResourceLoadComponent.java | 145 ++-- .../resourceload/ResourceLoadLeftPane.java | 228 ++++-- .../ganttz/resourceload/ResourceLoadList.java | 58 +- .../resourceload/ResourcesLoadPanel.java | 165 +++-- .../ganttz/servlets/CallbackServlet.java | 3 +- .../timetracker/IConvertibleToColumn.java | 2 +- .../timetracker/OnColumnsRowRenderer.java | 33 +- .../ganttz/timetracker/TimeTrackedTable.java | 12 +- .../TimeTrackedTableWithLeftPane.java | 36 +- .../zkoss/ganttz/timetracker/TimeTracker.java | 44 +- .../timetracker/TimeTrackerComponent.java | 50 +- .../TimeTrackerComponentWithoutColumns.java | 20 +- .../zoom/DetailFiveTimeTrackerState.java | 55 +- .../zoom/DetailFourTimeTrackerState.java | 71 +- .../ganttz/timetracker/zoom/DetailItem.java | 65 +- .../zoom/DetailOneTimeTrackerState.java | 47 +- .../zoom/DetailSixTimeTrackerState.java | 112 --- .../zoom/DetailThreeTimeTrackerState.java | 54 +- .../zoom/DetailTwoTimeTrackerState.java | 40 +- .../zoom/IZoomLevelChangedListener.java | 2 +- .../timetracker/zoom/SeveralModificators.java | 7 +- .../timetracker/zoom/TimeTrackerState.java | 126 ++-- ...meTrackerStateWithSubintervalsFitting.java | 5 +- .../ganttz/timetracker/zoom/ZoomLevel.java | 82 +-- .../zkoss/ganttz/util/ComponentsFinder.java | 34 +- .../ganttz/util/LongOperationFeedback.java | 118 ++-- .../org/zkoss/ganttz/util/MenuBuilder.java | 118 ++-- .../zkoss/ganttz/util/MutableTreeModel.java | 290 +++++--- .../ganttz/util/WeakReferencedListeners.java | 19 +- .../main/resources/metainfo/zk/lang-addon.xml | 42 +- .../web/css/jqplot/jquery.jqplot.min.css | 1 + .../web/ganttz/resourceload/leftPane.zul | 12 +- .../resources/web/ganttz/zul/leftPane.zul | 3 +- .../web/ganttz/zul/leftTasksTree.zul | 18 +- .../web/ganttz/zul/leftTasksTreeRow.zul | 10 +- .../web/ganttz/zul/leftTasksTreeRowLabels.zul | 15 +- .../web/ganttz/zul/plannerLayout.zul | 175 ++--- .../web/ganttz/zul/resourcesLoadLayout.zul | 110 +-- .../resources/web/ganttz/zul/tabSwitcher.zul | 3 +- .../secondlevelwithoutwatermark.zul | 8 +- .../zul/timetracker/timetrackedtable.zul | 23 +- .../ganttz/zul/timetracker/timetracker.zul | 32 +- .../timetracker/timetrackersecondlevel.zul | 23 +- .../main/resources/web/js/common/Common.js | 135 ++-- .../resources/web/js/ganttz/GanttPanel.js | 145 ++-- .../main/resources/web/js/ganttz/Planner.js | 125 ++-- .../resources/web/js/ganttz/TaskComponent.js | 454 ++++++------ .../resources/web/js/ganttz/TimeTracker.js | 16 +- .../web/js/ganttz/advanceAllocations.js | 9 +- .../web/js/ganttz/mold/dependency-list.js | 20 +- .../resourceload/ResourceLoadComponent.js | 14 +- .../ganttz/resourceload/ResourceLoadList.js | 142 ++-- .../mold/resource-load-component.js | 30 +- .../resourceload/mold/resource-load-list.js | 12 +- .../web/js/jqplot/jqplot.barRenderer.min.js | 57 ++ .../jqplot.canvasAxisLabelRenderer.min.js | 57 ++ .../jqplot/jqplot.canvasTextRenderer.min.js | 57 ++ .../jqplot/jqplot.categoryAxisRenderer.min.js | 57 ++ .../web/js/jqplot/jqplot.pieRenderer.min.js | 57 ++ .../web/js/jqplot/jquery.jqplot.min.js | 57 ++ .../resources/web/js/jqplot/jquery.min.js | 4 + .../timetracker/OnColumnsRowRendererTest.java | 39 +- .../ganttz/util/MutableTreeModelTest.java | 44 +- .../business/planner/entities/Task.java | 2 + 88 files changed, 3185 insertions(+), 2750 deletions(-) delete mode 100644 ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java create mode 100644 ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jqplot.barRenderer.min.js create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jqplot.canvasAxisLabelRenderer.min.js create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jqplot.canvasTextRenderer.min.js create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jqplot.categoryAxisRenderer.min.js create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jqplot.pieRenderer.min.js create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jquery.jqplot.min.js create mode 100644 ganttzk/src/main/resources/web/js/jqplot/jquery.min.js diff --git a/ganttzk/pom.xml b/ganttzk/pom.xml index 3ce4f474d..b07aabe21 100644 --- a/ganttzk/pom.xml +++ b/ganttzk/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 @@ -37,6 +37,7 @@ + org.apache.maven.plugins maven-source-plugin @@ -50,6 +51,7 @@ + @@ -89,17 +91,19 @@ org.apache.commons commons-collections4 - + org.zkoss.zk zul + org.zkoss.zk zkplus + org.zkoss.zk zk @@ -123,6 +127,7 @@ easymock test + org.easymock easymockclassextension diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java b/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java index c75db4723..4fac7b3d7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java @@ -24,17 +24,11 @@ package org.zkoss.ganttz; import org.apache.commons.lang3.StringUtils; import org.zkoss.ganttz.extensions.ICommand; import org.zkoss.ganttz.extensions.IContext; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zul.Button; class CommandContextualized { - public static CommandContextualized create(ICommand command, IContext context) { - return new CommandContextualized(command, context); - } - private final ICommand command; private final IContext context; @@ -46,6 +40,10 @@ class CommandContextualized { this.context = context; } + public static CommandContextualized create(ICommand command, IContext context) { + return new CommandContextualized<>(command, context); + } + public void doAction() { command.doAction(context); } @@ -66,12 +64,7 @@ class CommandContextualized { if ( command.isDisabled() ) { result.setDisabled(true); } else { - result.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event event) { - doAction(); - } - }); + result.addEventListener(Events.ON_CLICK, event -> doAction()); } button = result; diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java b/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java index 21ebf9c7c..bb343d3c1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java @@ -29,29 +29,33 @@ import org.zkoss.ganttz.extensions.ICommandOnTask; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.extensions.IContextWithPlannerTask; import org.zkoss.ganttz.util.MenuBuilder.ItemAction; -import org.zkoss.zk.ui.event.Event; public class CommandOnTaskContextualized { - public static CommandOnTaskContextualized create(ICommandOnTask commandOnTask, - IDomainAndBeansMapper mapper, IContext context) { - - return new CommandOnTaskContextualized(commandOnTask, mapper, context); - } - private final ICommandOnTask commandOnTask; private final IContext context; private final IDomainAndBeansMapper mapper; - private CommandOnTaskContextualized(ICommandOnTask commandOnTask, IDomainAndBeansMapper mapper, + private CommandOnTaskContextualized(ICommandOnTask commandOnTask, + IDomainAndBeansMapper mapper, IContext context) { + this.commandOnTask = commandOnTask; this.mapper = mapper; this.context = context; } + public static CommandOnTaskContextualized create(ICommandOnTask commandOnTask, + IDomainAndBeansMapper mapper, + IContext context) { + + return new CommandOnTaskContextualized<>(commandOnTask, mapper, context); + } + + + public void doAction(TaskComponent taskComponent) { doAction( ContextRelativeToOtherComponent.makeRelativeTo(context, taskComponent), @@ -82,12 +86,7 @@ public class CommandOnTaskContextualized { } ItemAction toItemAction() { - return new ItemAction() { - @Override - public void onEvent(TaskComponent choosen, Event event) { - doAction(choosen); - } - }; + return (chosen, event) -> doAction(chosen); } public String getIcon() { @@ -95,8 +94,7 @@ public class CommandOnTaskContextualized { } public boolean accepts(TaskComponent taskComponent) { - T domainObject = domainObjectFor(taskComponent.getTask()); - return commandOnTask.isApplicableTo(domainObject); + return commandOnTask.isApplicableTo(domainObjectFor(taskComponent.getTask())); } public IDomainAndBeansMapper getMapper() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java b/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java index 04ca965e3..7a9bf251e 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java @@ -27,8 +27,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.zkoss.ganttz.data.Dependency; import org.zkoss.ganttz.data.DependencyType; import org.zkoss.ganttz.data.Task; @@ -39,6 +37,7 @@ import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.ganttz.util.MenuBuilder; import org.zkoss.ganttz.util.MenuBuilder.ItemAction; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zul.Menupopup; @@ -51,8 +50,8 @@ import org.zkoss.zul.impl.XulElement; */ public class DependencyList extends XulElement implements AfterCompose { - private final class ChangeTypeAction implements - ItemAction { + private final class ChangeTypeAction implements ItemAction { + private final DependencyType type; private ChangeTypeAction(DependencyType type) { @@ -60,32 +59,28 @@ public class DependencyList extends XulElement implements AfterCompose { } @Override - public void onEvent(final DependencyComponent choosen, Event event) { - boolean canBeAdded = context.changeType(choosen.getDependency(), - type); - if (!canBeAdded) { + public void onEvent(final DependencyComponent chosen, Event event) { + boolean canBeAdded = context.changeType(chosen.getDependency(), type); + + if ( !canBeAdded ) { warnUser(_("The specified dependency is not allowed")); } } private void warnUser(String message) { - try { - Messagebox.show(message, null, Messagebox.OK, - Messagebox.EXCLAMATION, 0, null); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + Messagebox.show(message, null, Messagebox.OK, Messagebox.EXCLAMATION, 0, null); } } - private final class DependencyVisibilityToggler implements - PropertyChangeListener { + private final class DependencyVisibilityToggler implements PropertyChangeListener { + private final Task source; + private final Task destination; + private final DependencyComponent dependencyComponent; - private DependencyVisibilityToggler(Task source, Task destination, - DependencyComponent dependencyComponent) { + private DependencyVisibilityToggler(Task source, Task destination, DependencyComponent dependencyComponent) { this.source = source; this.destination = destination; this.dependencyComponent = dependencyComponent; @@ -93,16 +88,17 @@ public class DependencyList extends XulElement implements AfterCompose { @Override public void propertyChange(PropertyChangeEvent evt) { - if (!evt.getPropertyName().equals("visible")) { + if ( !"visible".equals(evt.getPropertyName()) ) { return; } - if (dependencyMustBeVisible() != isDependencyNowVisible()) { + + if ( dependencyMustBeVisible() != isDependencyNowVisible() ) { toggleDependencyExistence(dependencyMustBeVisible()); } } void toggleDependencyExistence(boolean visible) { - if (visible) { + if ( visible ) { appendChild(dependencyComponent); dependencyComponent.afterCompose(); addContextMenu(dependencyComponent); @@ -120,8 +116,6 @@ public class DependencyList extends XulElement implements AfterCompose { } } - private static final Log LOG = LogFactory.getLog(DependencyList.class); - private transient IZoomLevelChangedListener listener; private final FunctionalityExposedForExtensions context; @@ -135,33 +129,32 @@ public class DependencyList extends XulElement implements AfterCompose { } private List getDependencyComponents() { - List children = getChildren(); - return ComponentsFinder - .findComponentsOfType(DependencyComponent.class, children); + List children = getChildren(); + return ComponentsFinder.findComponentsOfType(DependencyComponent.class, children); } void addDependencyComponent(final DependencyComponent dependencyComponent) { TaskComponent source = dependencyComponent.getSource(); TaskComponent destination = dependencyComponent.getDestination(); - DependencyVisibilityToggler visibilityToggler = new DependencyVisibilityToggler( - source.getTask(), destination.getTask(), dependencyComponent); - source.getTask().addVisibilityPropertiesChangeListener( - visibilityToggler); - destination.getTask().addVisibilityPropertiesChangeListener( - visibilityToggler); + + DependencyVisibilityToggler visibilityToggler = + new DependencyVisibilityToggler(source.getTask(), destination.getTask(), dependencyComponent); + + source.getTask().addVisibilityPropertiesChangeListener(visibilityToggler); + destination.getTask().addVisibilityPropertiesChangeListener(visibilityToggler); dependencyComponent.setVisibilityChangeListener(visibilityToggler); - boolean dependencyMustBeVisible = visibilityToggler - .dependencyMustBeVisible(); + + boolean dependencyMustBeVisible = visibilityToggler.dependencyMustBeVisible(); visibilityToggler.toggleDependencyExistence(dependencyMustBeVisible); - if (dependencyMustBeVisible) { + + if ( dependencyMustBeVisible ) { dependencyComponent.redrawDependency(); } } private void addContextMenu(DependencyComponent dependencyComponent) { - Menupopup contextMenu = dependencyComponent.hasLimitingTasks() ? - getLimitingContextMenu() - : getContextMenu(); + Menupopup contextMenu = dependencyComponent.hasLimitingTasks() ? getLimitingContextMenu() : getContextMenu(); + dependencyComponent.setContext(contextMenu); } @@ -169,8 +162,7 @@ public class DependencyList extends XulElement implements AfterCompose { return (GanttPanel) getParent(); } - public void setDependencyComponents( - List dependencyComponents) { + void setDependencyComponents(List dependencyComponents) { for (DependencyComponent dependencyComponent : dependencyComponents) { addDependencyComponent(dependencyComponent); } @@ -178,11 +170,13 @@ public class DependencyList extends XulElement implements AfterCompose { @Override public void afterCompose() { - if (listener == null) { + if ( listener == null ) { + + /* Do not replace it with lambda */ listener = new IZoomLevelChangedListener() { @Override public void zoomLevelChanged(ZoomLevel detailLevel) { - if (!isInPage()) { + if ( !isInPage() ) { return; } for (DependencyComponent dependencyComponent : getDependencyComponents()) { @@ -190,14 +184,15 @@ public class DependencyList extends XulElement implements AfterCompose { } } }; + getTimeTracker().addZoomListener(listener); } + addContextMenu(); } private boolean isInPage() { - return getParent() != null && getGanttPanel() != null - && getGanttPanel().getParent() != null; + return getParent() != null && getGanttPanel() != null && getGanttPanel().getParent() != null; } private TimeTracker getTimeTracker() { @@ -211,54 +206,39 @@ public class DependencyList extends XulElement implements AfterCompose { } private Menupopup getLimitingContextMenu() { - if (limitingContextMenu == null) { - MenuBuilder contextMenuBuilder = MenuBuilder - .on(getPage(), getDependencyComponents()).item(_("Erase"), + if ( limitingContextMenu == null ) { + + MenuBuilder contextMenuBuilder = + MenuBuilder.on(getPage(), getDependencyComponents()).item( + _("Erase"), "/common/img/ico_borrar.png", - new ItemAction() { - @Override - public void onEvent( - final DependencyComponent choosen, - Event event) { - context - .removeDependency(choosen.getDependency()); - } - }); + (chosen, event) -> context.removeDependency(chosen.getDependency())); + limitingContextMenu = contextMenuBuilder.create(); } + return limitingContextMenu; } private Menupopup getContextMenu() { - if (contextMenu == null) { - MenuBuilder contextMenuBuilder = MenuBuilder - .on(getPage(), getDependencyComponents()).item(_("Erase"), + if ( contextMenu == null ) { + + MenuBuilder contextMenuBuilder = + MenuBuilder.on(getPage(), getDependencyComponents()).item( + _("Erase"), "/common/img/ico_borrar.png", - new ItemAction() { - @Override - public void onEvent( - final DependencyComponent choosen, - Event event) { - context - .removeDependency(choosen.getDependency()); - } - }); + ((chosen, event) -> context.removeDependency(chosen.getDependency()))); - contextMenuBuilder.item(_("Set End-Start"), null, - new ChangeTypeAction( - DependencyType.END_START)); + contextMenuBuilder.item(_("Set End-Start"), null, new ChangeTypeAction(DependencyType.END_START)); - contextMenuBuilder.item(_("Set Start-Start"), null, - new ChangeTypeAction( - DependencyType.START_START)); + contextMenuBuilder.item(_("Set Start-Start"), null, new ChangeTypeAction(DependencyType.START_START)); - contextMenuBuilder.item(_("Set End-End"), null, - new ChangeTypeAction( - DependencyType.END_END)); + contextMenuBuilder.item(_("Set End-End"), null, new ChangeTypeAction(DependencyType.END_END)); contextMenu = contextMenuBuilder.create(); } + return contextMenu; } @@ -266,48 +246,45 @@ public class DependencyList extends XulElement implements AfterCompose { return getGanttPanel().getTimeTrackerComponent(); } - public void redrawDependencies() { + void redrawDependencies() { redrawDependencyComponents(getDependencyComponents()); } - public void redrawDependencyComponents( - List dependencyComponents) { + private void redrawDependencyComponents(List dependencyComponents) { for (DependencyComponent dependencyComponent : dependencyComponents) { dependencyComponent.redrawDependency(); } } - public void taskRemoved(Task task) { - for (DependencyComponent dependencyComponent : DependencyList.this - .getDependencyComponents()) { - if (dependencyComponent.contains(task)) { + void taskRemoved(Task task) { + for (DependencyComponent dependencyComponent : DependencyList.this.getDependencyComponents()) { + if ( dependencyComponent.contains(task) ) { removeDependencyComponent(dependencyComponent); } } } public void remove(Dependency dependency) { - for (DependencyComponent dependencyComponent : DependencyList.this - .getDependencyComponents()) { - if (dependencyComponent.hasSameSourceAndDestination(dependency)) { + for (DependencyComponent dependencyComponent : DependencyList.this.getDependencyComponents()) { + if ( dependencyComponent.hasSameSourceAndDestination(dependency) ) { removeDependencyComponent(dependencyComponent); } } } private void removeDependencyComponent(DependencyComponent dependencyComponent) { - //remove the visibility listener attached to the tasks + // Remove the visibility listener attached to the tasks TaskComponent source = dependencyComponent.getSource(); TaskComponent destination = dependencyComponent.getDestination(); - PropertyChangeListener listener = - dependencyComponent.getVisibilityChangeListener(); + PropertyChangeListener listener = dependencyComponent.getVisibilityChangeListener(); + source.getTask().removeVisibilityPropertiesChangeListener(listener); destination.getTask().removeVisibilityPropertiesChangeListener(listener); - //remove other change listeners + // Remove other change listeners dependencyComponent.removeChangeListeners(); - //remove the dependency itself + // Remove the dependency itself this.removeChild(dependencyComponent); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java b/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java index 335dfe229..d554443c5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java @@ -60,56 +60,60 @@ public class GanttPanel extends XulElement implements AfterCompose { CommandOnTaskContextualized doubleClickCommand, IDisabilityConfiguration disabilityConfiguration, FilterAndParentExpandedPredicates predicate) { + this.planner = planner; - FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner - .getContext(); + FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner.getContext(); + if (planner.isShowingCriticalPath()) { context.showCriticalPath(); } + this.diagramGraph = context.getDiagramGraph(); - timeTrackerComponent = timeTrackerForGanttPanel(context - .getTimeTracker()); + timeTrackerComponent = timeTrackerForGanttPanel(context.getTimeTracker()); + appendChild(timeTrackerComponent); dependencyList = new DependencyList(context); - tasksLists = TaskList.createFor(context, doubleClickCommand, - commandsOnTasksContextualized, disabilityConfiguration, - predicate); + + tasksLists = TaskList.createFor( + context, doubleClickCommand, commandsOnTasksContextualized, disabilityConfiguration, predicate); + appendChild(tasksLists); appendChild(dependencyList); } - private TimeTrackerComponent timeTrackerForGanttPanel( - TimeTracker timeTracker) { + private TimeTrackerComponent timeTrackerForGanttPanel(TimeTracker timeTracker) { return new TimeTrackerComponent(timeTracker) { @Override protected void scrollHorizontalPercentage(int daysDisplacement) { - response("scroll_horizontal", new AuInvoke(GanttPanel.this, - "scroll_horizontal", "" + daysDisplacement)); + + response( + "scroll_horizontal", + new AuInvoke(GanttPanel.this, "scroll_horizontal", Integer.toString(daysDisplacement))); + moveCurrentPositionScroll(); } // FIXME: this is quite awful, it should be simple @Override protected void moveCurrentPositionScroll() { - // get the previous data. + // Get the previous data. LocalDate previousStart = getPreviousStart(); - // get the current data - int diffDays = getTimeTrackerComponent().getDiffDays( - previousStart); + // Get the current data + int diffDays = getTimeTrackerComponent().getDiffDays(previousStart); double pixelPerDay = getTimeTrackerComponent().getPixelPerDay(); - response("move_scroll", new AuInvoke(GanttPanel.this, - "move_scroll", "" + diffDays, "" + pixelPerDay)); + response("move_scroll", new AuInvoke(GanttPanel.this, "move_scroll", + Integer.toString(diffDays), + Double.toString(pixelPerDay))); } protected void updateCurrentDayScroll() { - double previousPixelPerDay = getTimeTracker().getMapper() - .getPixelsPerDay() - .doubleValue(); + double previousPixelPerDay = getTimeTracker().getMapper().getPixelsPerDay().doubleValue(); - response("update_day_scroll", new AuInvoke(GanttPanel.this, - "update_day_scroll", "" + previousPixelPerDay)); + response( + "update_day_scroll", + new AuInvoke(GanttPanel.this, "update_day_scroll", Double.toString(previousPixelPerDay))); } @@ -119,14 +123,16 @@ public class GanttPanel extends XulElement implements AfterCompose { @Override public void afterCompose() { tasksLists.afterCompose(); - dependencyList.setDependencyComponents(tasksLists - .asDependencyComponents(diagramGraph.getVisibleDependencies())); + + dependencyList.setDependencyComponents( + tasksLists.asDependencyComponents(diagramGraph.getVisibleDependencies())); + timeTrackerComponent.afterCompose(); dependencyList.afterCompose(); savePreviousData(); + if (planner.isExpandAll()) { - FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner - .getContext(); + FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner.getContext(); context.expandAll(); } @@ -141,6 +147,7 @@ public class GanttPanel extends XulElement implements AfterCompose { for (Task task : this.tasksLists.getAllTasks()) { task.updateTooltipText(); } + for (TaskComponent taskComponent : this.tasksLists.getTaskComponents()) { taskComponent.invalidate(); } @@ -195,12 +202,7 @@ public class GanttPanel extends XulElement implements AfterCompose { private void registerZoomLevelChangedListener() { if (zoomLevelChangedListener == null) { - zoomLevelChangedListener = new IZoomLevelChangedListener() { - @Override - public void zoomLevelChanged(ZoomLevel detailLevel) { - adjustZoomColumnsHeight(); - } - }; + zoomLevelChangedListener = detailLevel -> adjustZoomColumnsHeight(); getTimeTracker().addZoomListener(zoomLevelChangedListener); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java b/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java index a9a7473ec..051116aa1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java @@ -28,7 +28,7 @@ import org.zkoss.ganttz.util.Interval; public interface IDatesMapper { - final long MILISECONDS_PER_HOUR = 3600000; + long MILISECONDS_PER_HOUR = 3600000; int toPixels(LocalDate date); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java b/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java index e2ed9375a..3acf7f6d4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java @@ -31,14 +31,13 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; /** - * LeftPane of the planner. Responsible of showing global commands and the - * leftTasksTree
+ * LeftPane of the planner. Responsible of showing global commands and the leftTasksTree + *
+ * * @author Óscar González Fernández */ public class LeftPane extends HtmlMacroComponent { - private final List topLevelTasks; - private LeftTasksTree leftTasksTree; private final IDisabilityConfiguration disabilityConfiguration; @@ -47,16 +46,14 @@ public class LeftPane extends HtmlMacroComponent { private Planner planner; - public void setGoingDownInLastArrowCommand( - CommandContextualized goingDownInLastArrowCommand) { - this.leftTasksTree - .setGoingDownInLastArrowCommand(goingDownInLastArrowCommand); + public void setGoingDownInLastArrowCommand(CommandContextualized goingDownInLastArrowCommand) { + this.leftTasksTree.setGoingDownInLastArrowCommand(goingDownInLastArrowCommand); } public LeftPane(IDisabilityConfiguration disabilityConfiguration, - Planner planner, - FilterAndParentExpandedPredicates predicate) { - this.topLevelTasks = planner.getDiagramGraph().getTopLevelTasks(); + Planner planner, + FilterAndParentExpandedPredicates predicate) { + this.disabilityConfiguration = disabilityConfiguration; this.predicate = predicate; this.planner = planner; @@ -65,15 +62,14 @@ public class LeftPane extends HtmlMacroComponent { @Override public void afterCompose() { super.afterCompose(); - leftTasksTree = new LeftTasksTree(disabilityConfiguration, planner, - predicate); + + leftTasksTree = new LeftTasksTree(disabilityConfiguration, planner, predicate); getContainer().appendChild(leftTasksTree); leftTasksTree.afterCompose(); } private Component getContainer() { - Component container = getFellow("listdetails_container"); - return container; + return getFellow("listdetails_container"); } public void taskRemoved(Task task) { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java index 142c75903..4b1989c1a 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java @@ -23,39 +23,32 @@ package org.zkoss.ganttz; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.zkoss.ganttz.LeftTasksTreeRow.ILeftTasksTreeNavigator; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.Position; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.data.TaskContainer; import org.zkoss.ganttz.data.TaskContainer.IExpandListener; -import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.ganttz.util.MutableTreeModel; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zul.Tree; -import org.zkoss.zul.TreeModel; -import org.zkoss.zul.Treecell; import org.zkoss.zul.Treeitem; import org.zkoss.zul.TreeitemRenderer; /** - * Tree element to display tasks structure in the planning Gantt
+ * Tree element to display tasks structure in the planning Gantt. + *
* * @author Óscar González Fernández * @author Manuel Rego Casasnovas @@ -63,258 +56,8 @@ import org.zkoss.zul.TreeitemRenderer; */ public class LeftTasksTree extends HtmlMacroComponent { - private final class TaskBeanRenderer implements TreeitemRenderer { - private Map expandListeners = new HashMap(); - - public void render(final Treeitem item, Object data) throws Exception { - Task task = (Task) data; - item.setOpen(isOpened(task)); - - if ( task instanceof TaskContainer ) { - - final TaskContainer container = (TaskContainer) task; - - IExpandListener expandListener = new IExpandListener() { - - @Override - public void expandStateChanged(boolean isNowExpanded) { - item.setOpen(isNowExpanded); - } - }; - - expandListeners.put(container, expandListener); - container.addExpandListener(expandListener); - - } - LeftTasksTreeRow leftTasksTreeRow = LeftTasksTreeRow - .create(disabilityConfiguration, task, new TreeNavigator(tasksTreeModel, task), planner); - - if ( task.isContainer() ) { - expandWhenOpened((TaskContainer) task, item); - } - Component row; - if ( disabilityConfiguration.isTreeEditable() ) { - row = Executions.getCurrent().createComponents( - "~./ganttz/zul/leftTasksTreeRow.zul", item, null); - } else { - row = Executions.getCurrent().createComponents( - "~./ganttz/zul/leftTasksTreeRowLabels.zul", item, null); - } - leftTasksTreeRow.doAfterCompose(row); - detailsForBeans.put(task, leftTasksTreeRow); - deferredFiller.isBeingRendered(task, item); - } - - private void expandWhenOpened(final TaskContainer taskBean, Treeitem item) { - item.addEventListener("onOpen", new EventListener() { - @Override - public void onEvent(Event event) { - OpenEvent openEvent = (OpenEvent) event; - taskBean.setExpanded(openEvent.isOpen()); - } - }); - } - - } - - public boolean isOpened(Task task) { - return task.isLeaf() || task.isExpanded(); - } - - private static final class DetailsForBeans { - - private Map map = new HashMap(); - - private Set focusRequested = new HashSet(); - - public void put(Task task, LeftTasksTreeRow leftTasksTreeRow) { - map.put(task, leftTasksTreeRow); - if (focusRequested.contains(task)) { - focusRequested.remove(task); - leftTasksTreeRow.receiveFocus(); - } - } - - public void requestFocusFor(Task task) { - focusRequested.add(task); - } - - public LeftTasksTreeRow get(Task taskbean) { - return map.get(taskbean); - } - - } - private DetailsForBeans detailsForBeans = new DetailsForBeans(); - private final class TreeNavigator implements ILeftTasksTreeNavigator { - private final int[] pathToNode; - private final Task task; - - private TreeNavigator(TreeModel treemodel, Task task) { - this.task = task; - this.pathToNode = tasksTreeModel.getPath(tasksTreeModel.getRoot(), - task); - } - - @Override - public LeftTasksTreeRow getAboveRow() { - Task parent = getParent(pathToNode); - int lastPosition = pathToNode[pathToNode.length - 1]; - if (lastPosition != 0) { - return getChild(parent, lastPosition - 1); - } else if (tasksTreeModel.getRoot() != parent) { - return getDetailFor(parent); - } - return null; - } - - private LeftTasksTreeRow getChild(Task parent, int position) { - Task child = tasksTreeModel.getChild(parent, position); - return getDetailFor(child); - } - - private LeftTasksTreeRow getDetailFor(Task child) { - return detailsForBeans.get(child); - } - - @Override - public LeftTasksTreeRow getBelowRow() { - if (isExpanded() && hasChildren()) { - return getChild(task, 0); - } - for (ChildAndParent childAndParent : group(task, tasksTreeModel - .getParents(task))) { - if (childAndParent.childIsNotLast()) { - return getDetailFor(childAndParent.getNextToChild()); - } - } - // it's the last one, it has none below - return null; - } - - public List group(Task origin, List parents) { - ArrayList result = new ArrayList(); - Task child = origin; - Task parent; - ListIterator listIterator = parents.listIterator(); - while (listIterator.hasNext()) { - parent = listIterator.next(); - result.add(new ChildAndParent(child, parent)); - child = parent; - } - return result; - } - - private class ChildAndParent { - private final Task parent; - - private final Task child; - - private Integer positionOfChildCached; - - private ChildAndParent(Task child, Task parent) { - this.parent = parent; - this.child = child; - } - - public Task getNextToChild() { - return tasksTreeModel - .getChild(parent, getPositionOfChild() + 1); - } - - public boolean childIsNotLast() { - return getPositionOfChild() < numberOfChildrenForParent() - 1; - } - - private int numberOfChildrenForParent() { - return tasksTreeModel.getChildCount(parent); - } - - private int getPositionOfChild() { - if (positionOfChildCached != null) { - return positionOfChildCached; - } - int[] path = tasksTreeModel.getPath(parent, child); - return positionOfChildCached = path[path.length - 1]; - } - } - - private boolean hasChildren() { - return task.isContainer() && task.getTasks().size() > 0; - } - - private boolean isExpanded() { - return task.isContainer() && task.isExpanded(); - } - - private Task getParent(int[] path) { - Task current = tasksTreeModel.getRoot(); - for (int i = 0; i < path.length - 1; i++) { - current = tasksTreeModel.getChild(current, path[i]); - } - return current; - } - - } - - /** - * This class is a workaround for an issue with zk {@link Tree}. Once the - * tree is created, adding a node with children is troublesome. Only the top - * element is added to the tree, although the element has children. The Tree - * discards the adding event for the children because the parent says it's - * not loaded. This is the condition that is not satisfied:
- * if(parent != null && - (!(parent instanceof Treeitem) || ((Treeitem)parent).isLoaded())){
- * This problem is present in zk 3.6.1 at least. - * @author Óscar González Fernández - * @see Tree#onTreeDataChange - */ - private class DeferredFiller { - - private Set pendingToAddChildren = new HashSet(); - - public void addParentOfPendingToAdd(Task parent) { - pendingToAddChildren.add(parent); - } - - public void isBeingRendered(final Task parent, final Treeitem item) { - if (!pendingToAddChildren.contains(parent)) { - return; - } - markLoaded(item); - fillModel(parent, 0, parent.getTasks(), false); - pendingToAddChildren.remove(parent); - } - - private void markLoaded(Treeitem item) { - try { - Method method = getSetLoadedMethod(); - method.invoke(item, true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private Method setLoadedMethod = null; - - private Method getSetLoadedMethod() { - if (setLoadedMethod != null) { - return setLoadedMethod; - } - try { - Method method = Treeitem.class.getDeclaredMethod("setLoaded", - Boolean.TYPE); - method.setAccessible(true); - return setLoadedMethod = method; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private static Log LOG = LogFactory.getLog(LeftTasksTree.class); - private final DeferredFiller deferredFiller = new DeferredFiller(); private final List tasks; @@ -329,67 +72,376 @@ public class LeftTasksTree extends HtmlMacroComponent { private FilterAndParentExpandedPredicates predicate; - private final List visibleTasks = new ArrayList(); + private final List visibleTasks = new ArrayList<>(); private Planner planner; public LeftTasksTree(IDisabilityConfiguration disabilityConfiguration, - Planner planner, - FilterAndParentExpandedPredicates predicate) { + Planner planner, + FilterAndParentExpandedPredicates predicate) { + this.disabilityConfiguration = disabilityConfiguration; this.tasks = planner.getTaskList().getAllTasks(); this.predicate = predicate; this.planner = planner; } + @Override + public void afterCompose() { + setClass("listdetails"); + super.afterCompose(); + tasksTree = (Tree) getFellow("tasksTree"); + tasksTreeModel = MutableTreeModel.create(Task.class); + fillModel(tasks, true); + tasksTree.setModel(tasksTreeModel); + tasksTree.setItemRenderer(getTaskBeanRenderer()); + + /* Force call overridden render() */ + try { + if ( !tasks.isEmpty() ) { + getTaskBeanRenderer().render(new Treeitem(""), tasks.get(0), 0); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private final class TaskBeanRenderer implements TreeitemRenderer { + @Override + public void render(final Treeitem treeitem, Task o, int i) throws Exception { + Task task = o; + treeitem.setOpen(isOpened(task)); + + if ( task instanceof TaskContainer ) { + + final TaskContainer container = (TaskContainer) task; + + IExpandListener expandListener = new IExpandListener() { + @Override + public void expandStateChanged(boolean isNowExpanded) { + treeitem.setOpen(isNowExpanded); + } + }; + + container.addExpandListener(expandListener); + + } + + LeftTasksTreeRow leftTasksTreeRow = + LeftTasksTreeRow.create(disabilityConfiguration, task, new TreeNavigator(task), planner); + + if ( task.isContainer() ) { + expandWhenOpened((TaskContainer) task, treeitem); + } + + /* Clear existing Treerows */ + if ( !treeitem.getChildren().isEmpty() ) { + treeitem.getChildren().clear(); + } + + Component row = disabilityConfiguration.isTreeEditable() + ? Executions + .getCurrent() + .createComponents("~./ganttz/zul/leftTasksTreeRow.zul", treeitem, null) + : Executions + .getCurrent() + .createComponents("~./ganttz/zul/leftTasksTreeRowLabels.zul", treeitem, null); + + leftTasksTreeRow.doAfterCompose(row); + detailsForBeans.put(task, leftTasksTreeRow); + deferredFiller.isBeingRendered(task, treeitem); + } + + private void expandWhenOpened(final TaskContainer taskBean, Treeitem item) { + item.addEventListener("onOpen", event -> { + OpenEvent openEvent = (OpenEvent) event; + taskBean.setExpanded(openEvent.isOpen()); + }); + } + } + + private TaskBeanRenderer getTaskBeanRenderer() { + return new TaskBeanRenderer(); + } + + public boolean isOpened(Task task) { + return task.isLeaf() || task.isExpanded(); + } + + private static final class DetailsForBeans { + + private Map map = new HashMap<>(); + + private Set focusRequested = new HashSet<>(); + + public void put(Task task, LeftTasksTreeRow leftTasksTreeRow) { + map.put(task, leftTasksTreeRow); + + if ( focusRequested.contains(task) ) { + focusRequested.remove(task); + leftTasksTreeRow.receiveFocus(); + } + } + + public void requestFocusFor(Task task) { + focusRequested.add(task); + } + + public LeftTasksTreeRow get(Task taskbean) { + return map.get(taskbean); + } + + } + + private final class TreeNavigator implements ILeftTasksTreeNavigator { + + private final int[] pathToNode; + + private final Task task; + + private TreeNavigator(Task task) { + this.task = task; + this.pathToNode = tasksTreeModel.getPath(tasksTreeModel.getRoot(), task); + } + + @Override + public LeftTasksTreeRow getAboveRow() { + Task parent = getParent(pathToNode); + int lastPosition = pathToNode[pathToNode.length - 1]; + + if ( lastPosition != 0 ) { + return getChild(parent, lastPosition - 1); + } else if ( tasksTreeModel.getRoot() != parent ) { + return getDetailFor(parent); + } + + return null; + } + + private LeftTasksTreeRow getChild(Task parent, int position) { + return getDetailFor(tasksTreeModel.getChild(parent, position)); + } + + private LeftTasksTreeRow getDetailFor(Task child) { + return detailsForBeans.get(child); + } + + @Override + public LeftTasksTreeRow getBelowRow() { + if ( isExpanded() && hasChildren() ) { + return getChild(task, 0); + } + + for (ChildAndParent childAndParent : group(task, tasksTreeModel.getParents(task))) { + if ( childAndParent.childIsNotLast() ) { + return getDetailFor(childAndParent.getNextToChild()); + } + } + + // It's the last one, it has none below + return null; + } + + public List group(Task origin, List parents) { + ArrayList result = new ArrayList<>(); + Task child = origin; + + for (Task parent : parents) { + result.add(new ChildAndParent(child, parent)); + child = parent; + } + + return result; + } + + private class ChildAndParent { + + private final Task parent; + + private final Task child; + + private Integer positionOfChildCached; + + private ChildAndParent(Task child, Task parent) { + this.parent = parent; + this.child = child; + } + + public Task getNextToChild() { + return tasksTreeModel.getChild(parent, getPositionOfChild() + 1); + } + + public boolean childIsNotLast() { + return getPositionOfChild() < numberOfChildrenForParent() - 1; + } + + private int numberOfChildrenForParent() { + return tasksTreeModel.getChildCount(parent); + } + + private int getPositionOfChild() { + if ( positionOfChildCached != null ) { + return positionOfChildCached; + } + + int[] path = tasksTreeModel.getPath(parent, child); + + positionOfChildCached = path[path.length - 1]; + + return positionOfChildCached; + } + } + + private boolean hasChildren() { + return task.isContainer() && !task.getTasks().isEmpty(); + } + + private boolean isExpanded() { + return task.isContainer() && task.isExpanded(); + } + + private Task getParent(int[] path) { + Task current = tasksTreeModel.getRoot(); + + for (int i = 0; i < path.length - 1; i++) { + current = tasksTreeModel.getChild(current, path[i]); + } + + return current; + } + + } + + /** + * This class is a workaround for an issue with zk {@link Tree}. + * Once the tree is created, adding a node with children is troublesome. + * Only the top element is added to the tree, although the element has children. + * The Tree discards the adding event for the children because the parent says it's not loaded. + * + * This is the condition that is not satisfied: + *
+ * + * if( parent != null && (!(parent instanceof Treeitem) || ((Treeitem) parent).isLoaded()) ) { + * // ... + * } + * + *
+ * + * This problem is present in zk 3.6.1 at least. + * + * @author Óscar González Fernández + * @see Tree#onTreeDataChange + */ + private class DeferredFiller { + + private Set pendingToAddChildren = new HashSet<>(); + + private Method setLoadedMethod = null; + + public void addParentOfPendingToAdd(Task parent) { + pendingToAddChildren.add(parent); + } + + public void isBeingRendered(final Task parent, final Treeitem item) { + if ( !pendingToAddChildren.contains(parent) ) { + return; + } + + markLoaded(item); + fillModel(parent, 0, parent.getTasks(), false); + pendingToAddChildren.remove(parent); + } + + private void markLoaded(Treeitem item) { + try { + Method method = getSetLoadedMethod(); + method.invoke(item, true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Method getSetLoadedMethod() { + if ( setLoadedMethod != null ) { + return setLoadedMethod; + } + + try { + Method method = Treeitem.class.getDeclaredMethod("setLoaded", Boolean.TYPE); + method.setAccessible(true); + setLoadedMethod = method; + + return setLoadedMethod; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + private void fillModel(Collection tasks, boolean firstTime) { fillModel(this.tasksTreeModel.getRoot(), 0, tasks, firstTime); } - private void fillModel(Task parent, Integer insertionPosition, - Collection children, final boolean firstTime) { - if (predicate.isFilterContainers()) { + private void fillModel(Task parent, + Integer insertionPosition, + Collection children, + final boolean firstTime) { + + if ( predicate.isFilterContainers() ) { parent = this.tasksTreeModel.getRoot(); } - if (firstTime) { + if ( firstTime ) { + for (Task node : children) { - if (predicate.accpetsFilterPredicateAndContainers(node)) { - if (!visibleTasks.contains(node)) { + + if ( predicate.accpetsFilterPredicateAndContainers(node) ) { + + if ( !visibleTasks.contains(node) ) { this.tasksTreeModel.add(parent, node); visibleTasks.add(node); } + } else { - if (visibleTasks.contains(node)) { + + if ( visibleTasks.contains(node) ) { this.tasksTreeModel.remove(node); visibleTasks.remove(node); } } - if (node.isContainer()) { + if ( node.isContainer() ) { fillModel(node, 0, node.getTasks(), firstTime); } } } else { + for (Task node : children) { - if (node.isContainer()) { - if (predicate.accpetsFilterPredicateAndContainers(node)) { - if (!visibleTasks.contains(node)) { + + if ( node.isContainer() ) { + + if ( predicate.accpetsFilterPredicateAndContainers(node) ) { + + if ( !visibleTasks.contains(node) ) { this.deferredFiller.addParentOfPendingToAdd(node); } } } } - // the node must be added after, so the multistepTreeFiller is - // ready + + // The node must be added after, so the multistepTreeFiller is ready for (Task node : children) { - if (predicate.accpetsFilterPredicateAndContainers(node)) { - if (!visibleTasks.contains(node)) { - this.tasksTreeModel.add(parent, insertionPosition, - Arrays.asList(node)); + + if ( predicate.accpetsFilterPredicateAndContainers(node) ) { + + if ( !visibleTasks.contains(node) ) { + this.tasksTreeModel.add(parent, insertionPosition, Collections.singletonList(node)); visibleTasks.add(node); } + } else { if (visibleTasks.contains(node)) { this.tasksTreeModel.remove(node); @@ -411,7 +463,7 @@ public class LeftTasksTree extends HtmlMacroComponent { private void removeTaskAndAllChildren(List visibleTasks, Task task) { visibleTasks.remove(task); - if (task.isContainer()) { + if ( task.isContainer() ) { for (Task node : task.getTasks()) { removeTaskAndAllChildren(visibleTasks, node); } @@ -422,38 +474,25 @@ public class LeftTasksTree extends HtmlMacroComponent { tasksTreeModel.remove(taskRemoved); } - @Override - public void afterCompose() { - setClass("listdetails"); - super.afterCompose(); - tasksTree = (Tree) getFellow("tasksTree"); - tasksTreeModel = MutableTreeModel.create(Task.class); - fillModel(tasks, true); - tasksTree.setModel(tasksTreeModel); - tasksTree.setTreeitemRenderer(new TaskBeanRenderer()); - } - void addTask(Position position, Task task) { - if (position.isAppendToTop()) { - fillModel(Arrays.asList(task), false); + if ( position.isAppendToTop() ) { + fillModel(Collections.singletonList(task), false); detailsForBeans.requestFocusFor(task); } else { - List toAdd = Arrays.asList(task); - fillModel(position.getParent(), position.getInsertionPosition(), - toAdd, false); + List toAdd = Collections.singletonList(task); + fillModel(position.getParent(), position.getInsertionPosition(), toAdd, false); } } public void addTasks(Position position, Collection newTasks) { Task root = tasksTreeModel.getRoot(); - if (position.isAppendToTop()) { + + if ( position.isAppendToTop() ) { fillModel(root, tasksTreeModel.getChildCount(root), newTasks, false); - } else if (position.isAtTop()) { - fillModel(root, - position.getInsertionPosition(), newTasks, false); + } else if ( position.isAtTop() ) { + fillModel(root, position.getInsertionPosition(), newTasks, false); } else { - fillModel(position.getParent(), position.getInsertionPosition(), - newTasks, false); + fillModel(position.getParent(), position.getInsertionPosition(), newTasks, false); } } @@ -461,8 +500,7 @@ public class LeftTasksTree extends HtmlMacroComponent { return goingDownInLastArrowCommand; } - public void setGoingDownInLastArrowCommand( - CommandContextualized goingDownInLastArrowCommand) { + public void setGoingDownInLastArrowCommand(CommandContextualized goingDownInLastArrowCommand) { this.goingDownInLastArrowCommand = goingDownInLastArrowCommand; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java index ba6d9475e..cef49182f 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java @@ -39,16 +39,12 @@ import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.GanttDate; -import org.zkoss.ganttz.data.ITaskFundamentalProperties.IModifications; -import org.zkoss.ganttz.data.ITaskFundamentalProperties.IUpdatablePosition; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.util.Locales; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.WrongValueException; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zk.ui.util.GenericForwardComposer; @@ -56,10 +52,10 @@ import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; import org.zkoss.zul.Textbox; import org.zkoss.zul.Treecell; -import org.zkoss.zul.api.Div; -import org.zkoss.zul.api.Hlayout; -import org.zkoss.zul.api.Label; -import org.zkoss.zul.api.Treerow; +import org.zkoss.zul.Div; +import org.zkoss.zul.Hlayout; +import org.zkoss.zul.Label; +import org.zkoss.zul.Treerow; import static org.zkoss.ganttz.i18n.I18nHelper._; @@ -74,6 +70,7 @@ import static org.zkoss.ganttz.i18n.I18nHelper._; public class LeftTasksTreeRow extends GenericForwardComposer { public interface ILeftTasksTreeNavigator { + LeftTasksTreeRow getBelowRow(); LeftTasksTreeRow getAboveRow(); @@ -287,7 +284,11 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private enum Navigation { - LEFT, UP, RIGHT, DOWN; + LEFT, + UP, + RIGHT, + DOWN; + public static Navigation getIntentFrom(KeyEvent keyEvent) { return values()[keyEvent.getKeyCode() - 37]; } @@ -332,15 +333,15 @@ public class LeftTasksTreeRow extends GenericForwardComposer { int position = textBoxes.indexOf(textbox); switch (navigation) { case UP: - focusGoUp(position); - break; + focusGoUp(position); + break; case DOWN: - focusGoDown(position); - break; + focusGoDown(position); + break; default: - throw new RuntimeException("case not covered: " + navigation); + throw new RuntimeException("case not covered: " + navigation); } } @@ -394,7 +395,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void findComponents(Treerow row) { - List rowChildren = row.getChildren(); + List rowChildren = row.getChildren(); List treeCells = ComponentsFinder.findComponentsOfType(Treecell.class, rowChildren); assert treeCells.size() == 4; @@ -405,7 +406,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private static Textbox findTextBoxOfCell(Treecell treecell) { - List children = treecell.getChildren(); + List children = treecell.getChildren(); return ComponentsFinder.findComponentsOfType(Textbox.class, children).get(0); } @@ -418,54 +419,26 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void registerKeyboardListener(final Textbox textBox) { - textBox.addEventListener("onCtrlKey", new EventListener() { - - @Override - public void onEvent(Event event) { - userWantsToMove(textBox, (KeyEvent) event); - } - }); + textBox.addEventListener("onCtrlKey", event -> userWantsToMove(textBox, (KeyEvent) event)); } private void registerOnChange(final Component component) { - component.addEventListener("onChange", new EventListener() { - - @Override - public void onEvent(Event event) { - updateBean(component); - } - }); + component.addEventListener("onChange", event -> updateBean(component)); } private void registerOnChangeDatebox(final Datebox datebox, final Textbox textbox) { - datebox.addEventListener("onChange", new EventListener() { - - @Override - public void onEvent(Event event) { - textbox.setValue(dateFormat.format(datebox.getValue())); - updateBean(textbox); - } + datebox.addEventListener("onChange", event -> { + textbox.setValue(dateFormat.format(datebox.getValue())); + updateBean(textbox); }); } private void registerOnEnterListener(final Textbox textBox) { - textBox.addEventListener("onOK", new EventListener() { - - @Override - public void onEvent(Event event) { - userWantsDateBox(textBox); - } - }); + textBox.addEventListener("onOK", event -> userWantsDateBox(textBox)); } private void registerOnEnterOpenDateBox(final Datebox datebox) { - datebox.addEventListener("onOK", new EventListener() { - - @Override - public void onEvent(Event event) { - datebox.setOpen(true); - } - }); + datebox.addEventListener("onOK", event -> datebox.setOpen(true)); } private void findComponentsForStartDateCell(Treecell treecell) { @@ -485,7 +458,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void findComponentsForStatusCell(Treecell treecell) { - List children = treecell.getChildren(); + List children = treecell.getChildren(); Hlayout hlayout = ComponentsFinder.findComponentsOfType(Hlayout.class, children).get(0); @@ -496,13 +469,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void registerBlurListener(final Datebox datebox) { - datebox.addEventListener("onBlur", new EventListener() { - - @Override - public void onEvent(Event event) { - dateBoxHasLostFocus(datebox); - } - }); + datebox.addEventListener("onBlur", event -> dateBoxHasLostFocus(datebox)); } public void updateBean(Component updatedComponent) { @@ -518,13 +485,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { try { final Date begin = dateFormat.parse(getStartDateTextBox().getValue()); - task.doPositionModifications(new IModifications() { - - @Override - public void doIt(IUpdatablePosition position) { - position.moveTo(GanttDate.createFrom(begin)); - } - }); + task.doPositionModifications(position -> position.moveTo(GanttDate.createFrom(begin))); } catch (ParseException e) { // Do nothing as textbox is rested in the next sentence } @@ -562,12 +523,8 @@ public class LeftTasksTreeRow extends GenericForwardComposer { nameLabel.setTooltiptext(task.getName()); nameLabel.setSclass("clickable-rows"); - nameLabel.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event arg0) throws Exception { - Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode()); - } - }); + nameLabel.addEventListener(Events.ON_CLICK, + arg0 -> Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode())); startDateLabel.setValue(asString(task.getBeginDate().toDayRoundedDate())); endDateLabel.setValue(asString(task.getEndDate().toDayRoundedDate())); @@ -627,17 +584,17 @@ public class LeftTasksTreeRow extends GenericForwardComposer { switch (status) { case MARGIN_EXCEEDED: - cssClass = "status-red"; - break; + cssClass = "status-red"; + break; case WITHIN_MARGIN: - cssClass = "status-orange"; - break; + cssClass = "status-orange"; + break; case AS_PLANNED: default: - cssClass = "status-green"; + cssClass = "status-green"; } return cssClass; @@ -645,12 +602,9 @@ public class LeftTasksTreeRow extends GenericForwardComposer { private void onProjectStatusClick(Component statucComp) { if ( !disabilityConfiguration.isTreeEditable() ) { - statucComp.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event arg0) throws Exception { - Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode()); - } - }); + statucComp.addEventListener( + Events.ON_CLICK, + arg0 -> Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode())); } } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java index 9f0a702a5..771cbe4f4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java @@ -23,16 +23,15 @@ package org.zkoss.ganttz; import static org.zkoss.ganttz.i18n.I18nHelper._; - +import java.util.ArrayList; +import java.util.Collections; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.List; -import java.util.Collection; -import java.util.Collections; -import java.util.ArrayList; import org.apache.commons.logging.Log; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; @@ -56,7 +55,6 @@ import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; import org.zkoss.ganttz.util.ProfilingLogFactory; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.au.AuRequest; import org.zkoss.zk.au.AuService; import org.zkoss.zk.mesg.MZk; @@ -64,8 +62,6 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; import org.zkoss.zk.ui.UiException; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Button; @@ -74,57 +70,17 @@ import org.zkoss.zul.Listbox; import org.zkoss.zul.Listitem; import org.zkoss.zul.SimpleListModel; import org.zkoss.zul.South; -import org.zkoss.zul.api.Combobox; +import org.zkoss.zul.Combobox; public class Planner extends HtmlMacroComponent { private static final Log PROFILING_LOG = ProfilingLogFactory.getLog(Planner.class); - public static boolean guessContainersExpandedByDefaultGivenPrintParameters(Map printParameters) { - return guessContainersExpandedByDefault(convertToURLParameters(printParameters)); - } + private static int PIXELS_PER_TASK_LEVEL = 21; - private static Map convertToURLParameters(Map printParameters) { - Map result = new HashMap<>(); - for (Entry each : printParameters.entrySet()) { - result.put(each.getKey(), new String[] { each.getValue() }); - } + private static int PIXELS_PER_CHARACTER = 5; - return result; - } - - public static boolean guessContainersExpandedByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("expanded"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - public static boolean guessShowAdvancesByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("advances"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - public static boolean guessShowReportedHoursByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("reportedHours"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - public static boolean guessShowMoneyCostBarByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("moneyCostBar"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - private static Set toLowercaseSet(String[] values) { - Set result = new HashSet<>(); - for (String each : values) { - result.add(each.toLowerCase()); - } - - return result; - } + private String EXPAND_ALL_BUTTON = "expandAll"; private GanttZKDiagramGraph diagramGraph; @@ -134,6 +90,8 @@ public class Planner extends HtmlMacroComponent { private List> contextualizedGlobalCommands; + private CommandContextualized goingDownInLastArrowCommand; + private List> commandsOnTasksContextualized; private CommandOnTaskContextualized doubleClickCommand; @@ -165,16 +123,102 @@ public class Planner extends HtmlMacroComponent { private WeakReferencedListeners chartVisibilityListeners = WeakReferencedListeners.create(); - public Planner() { + private IGraphChangeListener showCriticalPathOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showCriticalPath(); + } + }; + + private IGraphChangeListener showAdvanceOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showAdvances(); + } + }; + + private IGraphChangeListener showReportedHoursOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showReportedHours(); + } + }; + + private IGraphChangeListener showMoneyCostBarOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showMoneyCostBar(); + } + }; + + private boolean containersExpandedByDefault = false; + + private boolean shownAdvanceByDefault = false; + + private boolean shownReportedHoursByDefault = false; + + private boolean shownMoneyCostBarByDefault = false; + + private FilterAndParentExpandedPredicates predicate; + + private boolean visibleChart; + + public Planner() {} + + public static boolean guessContainersExpandedByDefaultGivenPrintParameters(Map printParameters) { + return guessContainersExpandedByDefault(convertToURLParameters(printParameters)); + } + + private static Map convertToURLParameters(Map printParameters) { + Map result = new HashMap<>(); + for (Entry each : printParameters.entrySet()) { + result.put(each.getKey(), new String[] { each.getValue() }); + } + + return result; + } + + public static boolean guessContainersExpandedByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("expanded"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + public static boolean guessShowAdvancesByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("advances"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + public static boolean guessShowReportedHoursByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("reportedHours"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + public static boolean guessShowMoneyCostBarByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("moneyCostBar"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + private static Set toLowercaseSet(String[] values) { + Set result = new HashSet<>(); + for (String each : values) { + result.add(each.toLowerCase()); + } + + return result; } TaskList getTaskList() { - if ( ganttPanel == null ) { - return null; - } - List children = ganttPanel.getChildren(); - - return ComponentsFinder.findComponentsOfType(TaskList.class, children).get(0); + return ganttPanel == null + ? null + : ComponentsFinder.findComponentsOfType(TaskList.class, ganttPanel.getChildren()).get(0); } public int getTaskNumber() { @@ -186,20 +230,19 @@ public class Planner extends HtmlMacroComponent { } private int calculateMinimumWidthForTaskNameColumn(boolean expand, List tasks) { + IDomainAndBeansMapper mapper = getContext().getMapper(); int widest = 0; - for(Task task : tasks) { + for (Task task : tasks) { int numberOfAncestors = mapper.findPositionFor(task).getAncestors().size(); int numberOfCharacters = task.getName().length(); - int PIXELS_PER_TASK_LEVEL = 21; - int PIXELS_PER_CHARACTER = 5; widest = Math.max( widest, numberOfCharacters * PIXELS_PER_CHARACTER + numberOfAncestors * PIXELS_PER_TASK_LEVEL); - if( expand && !task.isLeaf() ) { + if ( expand && !task.isLeaf() ) { widest = Math.max(widest, calculateMinimumWidthForTaskNameColumn(expand, task.getTasks())); } } @@ -220,7 +263,7 @@ public class Planner extends HtmlMacroComponent { return null; } - List children = ganttPanel.getChildren(); + List children = ganttPanel.getChildren(); List found = ComponentsFinder.findComponentsOfType(DependencyList.class, children); if ( found.isEmpty() ) { @@ -232,6 +275,7 @@ public class Planner extends HtmlMacroComponent { public void addTasks(Position position, Collection newTasks) { TaskList taskList = getTaskList(); + if ( taskList != null && leftPane != null ) { taskList.addTasks(position, newTasks); leftPane.addTasks(position, newTasks); @@ -244,6 +288,7 @@ public class Planner extends HtmlMacroComponent { void addDependencies(Collection dependencies) { DependencyList dependencyList = getDependencyList(); + if ( dependencyList == null ) { return; } @@ -253,21 +298,23 @@ public class Planner extends HtmlMacroComponent { } } - public ListModel getZoomLevels() { + public ListModel getZoomLevels() { ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE, ZoomLevel.DETAIL_TWO, ZoomLevel.DETAIL_THREE, ZoomLevel.DETAIL_FOUR, - ZoomLevel.DETAIL_FIVE }; + ZoomLevel.DETAIL_FIVE + }; - return new SimpleListModel(selectableZoomlevels); + return new SimpleListModel<>(selectableZoomlevels); } public void setZoomLevel(final ZoomLevel zoomLevel, int scrollLeft) { if ( ganttPanel == null ) { return; } + this.zoomLevel = zoomLevel; ganttPanel.setZoomLevel(zoomLevel, scrollLeft); } @@ -294,6 +341,7 @@ public class Planner extends HtmlMacroComponent { if ( ganttPanel == null ) { return; } + LongOperationFeedback.execute(ganttPanel, new ILongOperation() { @Override public String getName() { @@ -328,18 +376,22 @@ public class Planner extends HtmlMacroComponent { new FunctionalityExposedForExtensions<>(this, configuration, diagramGraph); addGraphChangeListenersFromConfiguration(configuration); + this.contextualizedGlobalCommands = contextualize(newContext, configuration.getGlobalCommands()); + this.commandsOnTasksContextualized = contextualize(newContext, configuration.getCommandsOnTasks()); - CommandContextualized goingDownInLastArrowCommand = - contextualize(newContext, configuration.getGoingDownInLastArrowCommand()); + goingDownInLastArrowCommand = contextualize(newContext, configuration.getGoingDownInLastArrowCommand()); doubleClickCommand = contextualize(newContext, configuration.getDoubleClickCommand()); + this.context = newContext; this.disabilityConfiguration = configuration; + resettingPreviousComponentsToNull(); long timeAddingData = System.currentTimeMillis(); newContext.add(configuration.getData()); + PROFILING_LOG.debug("It took to add data: " + (System.currentTimeMillis() - timeAddingData) + " ms"); long timeSetupingAndAddingComponents = System.currentTimeMillis(); setupComponents(); @@ -356,6 +408,7 @@ public class Planner extends HtmlMacroComponent { timetrackerheader.afterCompose(); Component chartComponent = configuration.getChartComponent(); + if ( chartComponent != null ) { setAt("insertionPointChart", chartComponent); } @@ -366,11 +419,11 @@ public class Planner extends HtmlMacroComponent { } if ( !configuration.isExpandAllEnabled() ) { - Button expandAllButton = (Button) getFellow("expandAll"); + Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); expandAllButton.setVisible(false); } - if ( !configuration.isFlattenTreeEnabled() ) { + if (!configuration.isFlattenTreeEnabled()) { Button flattenTree = (Button) getFellow("flattenTree"); flattenTree.setVisible(false); } @@ -390,22 +443,26 @@ public class Planner extends HtmlMacroComponent { this.visibleChart = configuration.isExpandPlanningViewCharts(); ((South) getFellow("graphics")).setOpen(this.visibleChart); - PROFILING_LOG.debug( - "It took doing the setup of components and adding them: " + - (System.currentTimeMillis() - timeSetupingAndAddingComponents) + " ms"); + if (!visibleChart) { + ((South) getFellow("graphics")).setTitle(_("Graphics are disabled")); + } - setAuService(new AuService(){ + PROFILING_LOG.debug("it took doing the setup of components and adding them: " + + (System.currentTimeMillis() - timeSetupingAndAddingComponents) + " ms"); + + setAuService(new AuService() { public boolean service(AuRequest request, boolean everError){ String command = request.getCommand(); int zoomindex; int scrollLeft; - if ( command.equals("onZoomLevelChange") ){ + if ( "onZoomLevelChange".equals(command) ) { zoomindex= (Integer) retrieveData(request, "zoomindex"); scrollLeft = (Integer) retrieveData(request, "scrollLeft"); - setZoomLevel((ZoomLevel)((Listbox)getFellow("listZoomLevels")) - .getModel().getElementAt(zoomindex), scrollLeft); + setZoomLevel( + (ZoomLevel)((Listbox) getFellow("listZoomLevels")).getModel().getElementAt(zoomindex), + scrollLeft); return true; } @@ -413,7 +470,7 @@ public class Planner extends HtmlMacroComponent { return false; } - private Object retrieveData(AuRequest request, String key){ + private Object retrieveData(AuRequest request, String key) { Object value = request.getData().get(key); if ( value == null ) throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA, new Object[] { key, this }); @@ -434,9 +491,8 @@ public class Planner extends HtmlMacroComponent { insertionPoint.appendChild(component); } - private List> contextualize( - FunctionalityExposedForExtensions context, List> commands) { - + private List> contextualize(FunctionalityExposedForExtensions context, + List> commands) { List> result = new ArrayList<>(); for (ICommandOnTask c : commands) { result.add(contextualize(context, c)); @@ -445,18 +501,14 @@ public class Planner extends HtmlMacroComponent { return result; } - private CommandOnTaskContextualized contextualize( - FunctionalityExposedForExtensions context, ICommandOnTask commandOnTask) { + private CommandOnTaskContextualized contextualize(FunctionalityExposedForExtensions context, + ICommandOnTask commandOnTask) { return CommandOnTaskContextualized.create(commandOnTask, context.getMapper(), context); } private CommandContextualized contextualize(IContext context, ICommand command) { - if (command == null) { - return null; - } - - return CommandContextualized.create(command, context); + return command == null ? null : CommandContextualized.create(command, context); } private List> contextualize( @@ -510,6 +562,7 @@ public class Planner extends HtmlMacroComponent { // Comparison through icon as name is internationalized if ( c.getCommand().isPlannerCommand() ) { + // FIXME Avoid hard-coding the number of planner commands // At this moment we have 2 planner commands: reassign and adapt planning if ( plannerToolbar.getChildren().size() < 2 ) { @@ -535,10 +588,7 @@ public class Planner extends HtmlMacroComponent { taskList.remove(task); getDependencyList().taskRemoved(task); leftPane.taskRemoved(task); - - // forcing smart update - setHeight(getHeight()); - + setHeight(getHeight());// forcing smart update ganttPanel.adjustZoomColumnsHeight(); getDependencyList().redrawDependencies(); } @@ -549,14 +599,10 @@ public class Planner extends HtmlMacroComponent { listZoomLevels = (Listbox) getFellow("listZoomLevels"); Component westContainer = getFellow("taskdetailsContainer"); - westContainer.addEventListener(Events.ON_SIZE, new EventListener() { - @Override - public void onEvent(Event event) { - Clients.evalJavaScript("ganttz.TaskList.getInstance().legendResize();"); - } - - }); + westContainer.addEventListener( + Events.ON_SIZE, + event -> Clients.evalJavaScript("ganttz.TaskList.getInstance().legendResize();")); } @@ -564,60 +610,14 @@ public class Planner extends HtmlMacroComponent { return ganttPanel.getTimeTracker(); } - private IGraphChangeListener showCriticalPathOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showCriticalPath(); - } - }; - - private IGraphChangeListener showAdvanceOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showAdvances(); - } - }; - - private IGraphChangeListener showReportedHoursOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showReportedHours(); - } - }; - - private IGraphChangeListener showMoneyCostBarOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showMoneyCostBar(); - } - }; - - private boolean containersExpandedByDefault = false; - - private boolean shownAdvanceByDefault = false; - - private boolean shownReportedHoursByDefault = false; - - private boolean shownMoneyCostBarByDefault = false; - - private FilterAndParentExpandedPredicates predicate; - - private boolean visibleChart; - public void showCriticalPath() { Button showCriticalPathButton = (Button) getFellow("showCriticalPath"); - if ( disabilityConfiguration.isCriticalPathEnabled() ) { if ( isShowingCriticalPath ) { context.hideCriticalPath(); diagramGraph.removePostGraphChangeListener(showCriticalPathOnChange); showCriticalPathButton.setSclass("planner-command"); showCriticalPathButton.setTooltiptext(_("Show critical path")); - } else { context.showCriticalPath(); diagramGraph.addPostGraphChangeListener(showCriticalPathOnChange); @@ -638,10 +638,9 @@ public class Planner extends HtmlMacroComponent { public void showAdvances() { Button showAdvancesButton = (Button) getFellow("showAdvances"); if ( disabilityConfiguration.isAdvancesEnabled() ) { - Combobox progressTypesCombo = (Combobox) getFellow("cbProgressTypes"); - if ( isShowingAdvances ) { + if ( isShowingAdvances ) { context.hideAdvances(); diagramGraph.removePostGraphChangeListener(showAdvanceOnChange); showAdvancesButton.setSclass("planner-command"); @@ -650,40 +649,39 @@ public class Planner extends HtmlMacroComponent { if ( progressTypesCombo.getItemCount() > 0 ) { progressTypesCombo.setSelectedIndex(0); } - } else { context.showAdvances(); diagramGraph.addPostGraphChangeListener(showAdvanceOnChange); showAdvancesButton.setSclass("planner-command clicked"); showAdvancesButton.setTooltiptext(_("Hide progress")); } + isShowingAdvances = !isShowingAdvances; } } public void showReportedHours() { Button showReportedHoursButton = (Button) getFellow("showReportedHours"); - if ( disabilityConfiguration.isReportedHoursEnabled() ) { + if ( isShowingReportedHours ) { context.hideReportedHours(); diagramGraph.removePostGraphChangeListener(showReportedHoursOnChange); showReportedHoursButton.setSclass("planner-command"); showReportedHoursButton.setTooltiptext(_("Show reported hours")); - } else { context.showReportedHours(); diagramGraph.addPostGraphChangeListener(showReportedHoursOnChange); showReportedHoursButton.setSclass("planner-command clicked"); showReportedHoursButton.setTooltiptext(_("Hide reported hours")); } + isShowingReportedHours = !isShowingReportedHours; } } public void showMoneyCostBar() { Button showMoneyCostBarButton = (Button) getFellow("showMoneyCostBar"); - if ( disabilityConfiguration.isMoneyCostBarEnabled() ) { if ( isShowingMoneyCostBar ) { context.hideMoneyCostBar(); @@ -696,6 +694,7 @@ public class Planner extends HtmlMacroComponent { showMoneyCostBarButton.setSclass("planner-command clicked"); showMoneyCostBarButton.setTooltiptext(_("Hide money cost bar")); } + isShowingMoneyCostBar = !isShowingMoneyCostBar; } } @@ -709,6 +708,7 @@ public class Planner extends HtmlMacroComponent { Clients.evalJavaScript("ganttz.TaskList.getInstance().showAllTaskLabels()"); showAllLabelsButton.setSclass("planner-command show-labels clicked"); } + isShowingLabels = !isShowingLabels; } @@ -721,6 +721,7 @@ public class Planner extends HtmlMacroComponent { Clients.evalJavaScript("ganttz.TaskList.getInstance().showResourceTooltips()"); showAllLabelsButton.setSclass("planner-command show-resources clicked"); } + isShowingResources = !isShowingResources; } @@ -731,11 +732,9 @@ public class Planner extends HtmlMacroComponent { } public ZoomLevel getZoomLevel() { - if ( ganttPanel == null ) { - return zoomLevel != null ? zoomLevel : ZoomLevel.DETAIL_ONE; - } - - return ganttPanel.getTimeTracker().getDetailLevel(); + return ganttPanel == null + ? zoomLevel != null ? zoomLevel : ZoomLevel.DETAIL_ONE + : ganttPanel.getTimeTracker().getDetailLevel(); } public void setInitialZoomLevel(final ZoomLevel zoomLevel) { @@ -755,7 +754,7 @@ public class Planner extends HtmlMacroComponent { } public boolean showAdvancesRightNow() { - return (areShownAdvancesByDefault() || isShowingAdvances); + return areShownAdvancesByDefault() || isShowingAdvances; } public void setAreShownAdvancesByDefault(boolean shownAdvanceByDefault) { @@ -772,7 +771,7 @@ public class Planner extends HtmlMacroComponent { } public boolean showReportedHoursRightNow() { - return (areShownReportedHoursByDefault() || isShowingReportedHours); + return areShownReportedHoursByDefault() || isShowingReportedHours; } public void setAreShownMoneyCostBarByDefault(boolean shownMoneyCostBarByDefault) { @@ -784,13 +783,13 @@ public class Planner extends HtmlMacroComponent { } public boolean showMoneyCostBarRightNow() { - return (areShownMoneyCostBarByDefault() || isShowingMoneyCostBar); + return areShownMoneyCostBarByDefault() || isShowingMoneyCostBar; } public void expandAll() { - Button expandAllButton = (Button) getFellow("expandAll"); - + Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); if ( disabilityConfiguration.isExpandAllEnabled() ) { + if ( isExpandAll ) { context.collapseAll(); expandAllButton.setSclass("planner-command"); @@ -799,25 +798,26 @@ public class Planner extends HtmlMacroComponent { expandAllButton.setSclass("planner-command clicked"); } } + isExpandAll = !isExpandAll; } public void expandAllAlways() { - Button expandAllButton = (Button) getFellow("expandAll"); + Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); if ( disabilityConfiguration.isExpandAllEnabled() ) { - context.expandAll(); - expandAllButton.setSclass("planner-command clicked"); + context.expandAll(); + expandAllButton.setSclass("planner-command clicked"); } } public void updateSelectedZoomLevel() { ganttPanel.getTimeTracker().setZoomLevel(zoomLevel); - Listitem selectedItem = (Listitem) listZoomLevels.getItems().get(zoomLevel.ordinal()); + Listitem selectedItem = listZoomLevels.getItems().get(zoomLevel.ordinal()); listZoomLevels.setSelectedItem(selectedItem); listZoomLevels.invalidate(); } - public IContext getContext() { + public IContext getContext() { return context; } @@ -838,17 +838,18 @@ public class Planner extends HtmlMacroComponent { public void flattenTree() { Button flattenTreeButton = (Button) getFellow("flattenTree"); - if ( disabilityConfiguration.isFlattenTreeEnabled() ) { - if ( isFlattenTree ) { + if (isFlattenTree) { predicate.setFilterContainers(false); flattenTreeButton.setSclass("planner-command"); } else { predicate.setFilterContainers(true); flattenTreeButton.setSclass("planner-command clicked"); } + setTaskListPredicate(predicate); } + isFlattenTree = !isFlattenTree; Clients.evalJavaScript("ganttz.Planner.getInstance().adjustScrollableDimensions()"); } @@ -859,12 +860,7 @@ public class Planner extends HtmlMacroComponent { public void changeChartVisibility(boolean visible) { visibleChart = visible; - chartVisibilityListeners.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IChartVisibilityChangedListener listener) { - listener.chartVisibilityChanged(visibleChart); - } - }); + chartVisibilityListeners.fireEvent(listener -> listener.chartVisibilityChanged(visibleChart)); } public boolean isVisibleChart() { @@ -914,8 +910,9 @@ public class Planner extends HtmlMacroComponent { return null; } + @Override public String getWidgetClass(){ - return getDefinition().getDefaultWidgetClass(); + return getDefinition().getDefaultWidgetClass(this); } public List getCriticalPath() { @@ -926,17 +923,19 @@ public class Planner extends HtmlMacroComponent { TaskList taskList = getTaskList(); if ( taskList != null ) { taskList.updateCompletion(progressType); - // FIXME Bug #1270 + for (TaskComponent each : taskList.getTaskComponents()) { each.invalidate(); } } } - public TaskComponent getTaskComponentRelatedTo(org.zkoss.ganttz.data.Task task) { + public TaskComponent getTaskComponentRelatedTo(Task task) { TaskList taskList = getTaskList(); if ( taskList != null ) { + for (TaskComponent each : taskList.getTaskComponents()) { + if ( each.getTask().equals(task) ) { return each; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java b/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java index e9b98b2ef..1c1699a22 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java @@ -29,16 +29,14 @@ import java.util.Map; import org.zkoss.ganttz.extensions.ITab; import org.zkoss.ganttz.util.IMenuItemsRegister; import org.zkoss.zk.ui.Component; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; public class TabsRegistry { - private List tabs = new ArrayList(); + private List tabs = new ArrayList<>(); private final Component parent; - private Map fromTabToMenuKey = new HashMap(); + private Map fromTabToMenuKey = new HashMap<>(); private IMenuItemsRegister menu; @@ -52,14 +50,10 @@ public class TabsRegistry { } public interface IBeforeShowAction { - public void doAction(); + void doAction(); } - private static final IBeforeShowAction DO_NOTHING = new IBeforeShowAction() { - @Override - public void doAction() { - } - }; + private static final IBeforeShowAction DO_NOTHING = () -> {}; public void show(ITab tab) { show(tab, DO_NOTHING); @@ -101,23 +95,10 @@ public class TabsRegistry { } } - public void showFirst() { - if (!tabs.isEmpty()) { - show(tabs.get(0)); - } - } - public void registerAtMenu(IMenuItemsRegister menu) { this.menu = menu; for (final ITab t : tabs) { - Object key = menu.addMenuItem(t.getName(), t.getCssClass(), - new EventListener() { - - @Override - public void onEvent(Event event) { - show(t); - } - }); + Object key = menu.addMenuItem(t.getName(), t.getCssClass(), event -> show(t)); fromTabToMenuKey.put(t, key); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java index 07cab2efd..9a721613b 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java @@ -21,6 +21,7 @@ package org.zkoss.ganttz; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.util.Date; @@ -34,6 +35,8 @@ import org.joda.time.Duration; import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.GanttDate; +import org.zkoss.ganttz.data.ITaskFundamentalProperties.IModifications; +import org.zkoss.ganttz.data.ITaskFundamentalProperties.IUpdatablePosition; import org.zkoss.ganttz.data.Milestone; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.data.Task.IReloadResourcesTextRequested; @@ -62,9 +65,12 @@ import org.zkoss.zul.Div; public class TaskComponent extends Div implements AfterCompose { private static final int HEIGHT_PER_TASK = 10; + private static final int CONSOLIDATED_MARK_HALF_WIDTH = 3; + private static final int HALF_DEADLINE_MARK = 3; + private String FUNCTION_RESIZE = "resizeCompletion2Advance"; protected final IDisabilityConfiguration disabilityConfiguration; @@ -76,6 +82,18 @@ public class TaskComponent extends Div implements AfterCompose { private PropertyChangeListener showingMoneyCostBarPropertyListener; + private IReloadResourcesTextRequested reloadResourcesTextRequested; + + private String _color; + + private boolean isTopLevel; + + private final Task task; + + private transient PropertyChangeListener propertiesListener; + + private String progressType; + public static TaskComponent asTaskComponent(Task task, IDisabilityConfiguration disabilityConfiguration, boolean isTopLevel) { @@ -99,8 +117,6 @@ public class TaskComponent extends Div implements AfterCompose { return asTaskComponent(task, disabilityConfiguration, true); } - private IReloadResourcesTextRequested reloadResourcesTextRequested; - public TaskComponent(Task task, IDisabilityConfiguration disabilityConfiguration) { setHeight(HEIGHT_PER_TASK + "px"); setContext("idContextMenuTaskAssignment"); @@ -108,9 +124,7 @@ public class TaskComponent extends Div implements AfterCompose { setClass(calculateCSSClass()); setId(UUID.randomUUID().toString()); this.disabilityConfiguration = disabilityConfiguration; - - IConstraintViolationListener taskViolationListener = - Constraint.onlyOnZKExecution(new IConstraintViolationListener() { + IConstraintViolationListener taskViolationListener = Constraint.onlyOnZKExecution(new IConstraintViolationListener() { @Override public void constraintViolated(Constraint constraint, GanttDate value) { @@ -124,32 +138,38 @@ public class TaskComponent extends Div implements AfterCompose { }); this.task.addConstraintViolationListener(taskViolationListener, Mode.RECEIVE_PENDING); - reloadResourcesTextRequested = () -> { - if ( canShowResourcesText() ) { - smartUpdate("resourcesText", getResourcesText()); + + reloadResourcesTextRequested = new IReloadResourcesTextRequested() { + @Override + public void reloadResourcesTextRequested() { + if ( canShowResourcesText() ) { + smartUpdate("resourcesText", getResourcesText()); + } + + String cssClass = calculateCSSClass(); + + response("setClass", new AuInvoke(TaskComponent.this, "setClass", cssClass)); + + // FIXME: Refactor to another listener + updateDeadline(); + invalidate(); } - String cssClass = calculateCSSClass(); - - response("setClass", new AuInvoke(TaskComponent.this, "setClass", cssClass)); - - // FIXME: Refactor to another listener - updateDeadline(); - invalidate(); }; this.task.addReloadListener(reloadResourcesTextRequested); - setAuService(new AuService(){ + setAuService(new AuService() { - public boolean service(AuRequest request, boolean everError){ + public boolean service(AuRequest request, boolean everError) { String command = request.getCommand(); final TaskComponent ta; if ( command.equals("onUpdatePosition") ){ ta = retrieveTaskComponent(request); - ta.doUpdatePosition(toInteger(retrieveData(request, "left"))); + ta.doUpdatePosition(toInteger(retrieveData(request, "left")) + ); Events.postEvent(new Event(getId(), ta, request.getData())); @@ -181,7 +201,7 @@ public class TaskComponent extends Div implements AfterCompose { return ((Number) valueFromRequestData).intValue(); } - private TaskComponent retrieveTaskComponent(AuRequest request){ + private TaskComponent retrieveTaskComponent(AuRequest request) { final TaskComponent ta = (TaskComponent) request.getComponent(); if ( ta == null ) { @@ -191,7 +211,7 @@ public class TaskComponent extends Div implements AfterCompose { return ta; } - private Object retrieveData(AuRequest request, String key){ + private Object retrieveData(AuRequest request, String key) { Object value = request.getData().get(key); if ( value == null ) throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA, new Object[] { key, this }); @@ -240,15 +260,25 @@ public class TaskComponent extends Div implements AfterCompose { public final void afterCompose() { updateProperties(); if ( propertiesListener == null ) { - propertiesListener = evt -> updateProperties(); + + propertiesListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateProperties(); + } + }; } this.task.addFundamentalPropertiesChangeListener(propertiesListener); if ( showingAdvancePropertyListener == null ) { - showingAdvancePropertyListener = evt -> { - if ( isInPage() && !(task instanceof Milestone) ) { - updateCompletionAdvance(); + + showingAdvancePropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( isInPage() && !(task instanceof Milestone) ) { + updateCompletionAdvance(); + } } }; } @@ -256,9 +286,13 @@ public class TaskComponent extends Div implements AfterCompose { this.task.addAdvancesPropertyChangeListener(showingAdvancePropertyListener); if ( showingReportedHoursPropertyListener == null ) { - showingReportedHoursPropertyListener = evt -> { - if ( isInPage() && !(task instanceof Milestone) ) { - updateCompletionReportedHours(); + + showingReportedHoursPropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( isInPage() && !(task instanceof Milestone) ) { + updateCompletionReportedHours(); + } } }; } @@ -266,9 +300,13 @@ public class TaskComponent extends Div implements AfterCompose { this.task.addReportedHoursPropertyChangeListener(showingReportedHoursPropertyListener); if ( showingMoneyCostBarPropertyListener == null ) { - showingMoneyCostBarPropertyListener = evt -> { - if ( isInPage() && !(task instanceof Milestone) ) { - updateCompletionMoneyCostBar(); + + showingMoneyCostBarPropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( isInPage() && !(task instanceof Milestone) ) { + updateCompletionMoneyCostBar(); + } } }; } @@ -276,7 +314,14 @@ public class TaskComponent extends Div implements AfterCompose { this.task.addMoneyCostBarPropertyChangeListener(showingMoneyCostBarPropertyListener); if ( criticalPathPropertyListener == null ) { - criticalPathPropertyListener = evt -> updateClass(); + + criticalPathPropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateClass(); + } + + }; } this.task.addCriticalPathPropertyChangeListener(criticalPathPropertyListener); @@ -291,15 +336,6 @@ public class TaskComponent extends Div implements AfterCompose { return true; } - private String _color; - - private boolean isTopLevel; - - private final Task task; - private transient PropertyChangeListener propertiesListener; - - private String progressType; - public TaskRow getRow() { if ( getParent() == null ) { throw new IllegalStateException( @@ -337,9 +373,16 @@ public class TaskComponent extends Div implements AfterCompose { void doUpdatePosition(int leftX) { GanttDate startBeforeMoving = this.task.getBeginDate(); final LocalDate newPosition = getMapper().toDate(leftX); - this.task.doPositionModifications(position -> position.moveTo(GanttDate.createFrom(newPosition))); + + this.task.doPositionModifications(new IModifications() { + @Override + public void doIt(IUpdatablePosition position) { + position.moveTo(GanttDate.createFrom(newPosition)); + } + }); boolean remainsInOriginalPosition = this.task.getBeginDate().equals(startBeforeMoving); + if ( remainsInOriginalPosition ) { updateProperties(); } @@ -372,20 +415,18 @@ public class TaskComponent extends Div implements AfterCompose { } } - /* - * We override the method of renderProperties to put the color property as part - * of the style - */ + /* We override the method of renderProperties to put the color property as part of the style */ protected void renderProperties(ContentRenderer renderer) throws IOException{ + if ( getColor() != null ) setStyle("background-color : " + getColor()); setWidgetAttribute("movingTasksEnabled", ((Boolean)isMovingTasksEnabled()).toString()); setWidgetAttribute("resizingTasksEnabled", ((Boolean)isResizingTasksEnabled()).toString()); - /* We can't use setStyle because of restrictions - * involved with UiVisualizer#getResponses and the - * smartUpdate method (when the request is asynchronous) */ + /* We can't use setStyle because of restrictions involved with UiVisualizer#getResponses and the + * smartUpdate method (when the request is asynchronous) + */ render(renderer, "style", "position : absolute"); render(renderer, "_labelsText", getLabelsText()); @@ -395,10 +436,7 @@ public class TaskComponent extends Div implements AfterCompose { super.renderProperties(renderer); } - /* - * We send a response to the client to create the arrow we are going to use - * to create the dependency - */ + /* We send a response to the client to create the arrow we are going to use to create the dependency */ public void addDependency() { response("depkey", new AuInvoke(this, "addDependency")); @@ -540,9 +578,9 @@ public class TaskComponent extends Div implements AfterCompose { if ( task.isShowingAdvances() ) { int startPixels = this.task.getBeginDate().toPixels(getMapper()); String widthAdvancePercentage = pixelsFromStartUntil(startPixels, this.task.getAdvanceBarEndDate()) + "px"; - response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage)); + response(null, new AuInvoke(this, FUNCTION_RESIZE, widthAdvancePercentage)); } else { - response(null, new AuInvoke(this, "resizeCompletion2Advance", "0px")); + response(null, new AuInvoke(this, FUNCTION_RESIZE, "0px")); } } @@ -553,9 +591,9 @@ public class TaskComponent extends Div implements AfterCompose { String widthAdvancePercentage = pixelsFromStartUntil(startPixels, this.task.getAdvanceBarEndDate(progressType)) + "px"; - response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage)); + response(null, new AuInvoke(this, FUNCTION_RESIZE, widthAdvancePercentage)); } else { - response(null, new AuInvoke(this, "resizeCompletion2Advance", "0px")); + response(null, new AuInvoke(this, FUNCTION_RESIZE, "0px")); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java index 6e74d1f86..a63c1f24f 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java @@ -33,11 +33,7 @@ import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zul.Datebox; import org.zkoss.zul.Textbox; -public class TaskEditFormComposer extends GenericForwardComposer { - - public TaskEditFormComposer() { - - } +public class TaskEditFormComposer extends GenericForwardComposer { private Task currentTask; @@ -53,19 +49,22 @@ public class TaskEditFormComposer extends GenericForwardComposer { private Textbox notes; + public TaskEditFormComposer() { + + } + @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); } - public void init(Component openRelativeTo, Task task) { + public void init(Task task) { this.currentTask = task; this.taskDTO = toDTO(task); updateComponentValuesForTask(taskDTO); } - private void updateComponentValuesForTask( - TaskDTO taskDTO) { + private void updateComponentValuesForTask(TaskDTO taskDTO) { name.setValue(taskDTO.name); startDateBox.setValue(taskDTO.beginDate); endDateBox.setValue(taskDTO.endDate); @@ -96,10 +95,15 @@ public class TaskEditFormComposer extends GenericForwardComposer { * @author Manuel Rego Casasnovas */ public static class TaskDTO { + public String name; + public Date beginDate; + public Date endDate; + public Date deadlineDate; + public String notes; } @@ -122,18 +126,12 @@ public class TaskEditFormComposer extends GenericForwardComposer { return localDate.toDateTimeAtStartOfDay().toDate(); } - private void copyFromDTO(final TaskDTO taskDTO, Task currentTask, - boolean copyDates) { + private void copyFromDTO(final TaskDTO taskDTO, Task currentTask, boolean copyDates) { currentTask.setName(taskDTO.name); if (copyDates) { - currentTask.doPositionModifications(new IModifications() { - - @Override - public void doIt(IUpdatablePosition position) { - position.setBeginDate(GanttDate - .createFrom(taskDTO.beginDate)); - position.resizeTo(GanttDate.createFrom(taskDTO.endDate)); - } + currentTask.doPositionModifications(position -> { + position.setBeginDate(GanttDate.createFrom(taskDTO.beginDate)); + position.resizeTo(GanttDate.createFrom(taskDTO.endDate)); }); } currentTask.setNotes(taskDTO.notes); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java index d01c04d48..4afe88529 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java @@ -23,15 +23,7 @@ package org.zkoss.ganttz; import static org.zkoss.ganttz.i18n.I18nHelper._; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; +import java.util.*; import org.apache.commons.lang3.math.Fraction; import org.joda.time.LocalDate; @@ -48,15 +40,13 @@ import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.Interval; import org.zkoss.ganttz.util.MenuBuilder; -import org.zkoss.ganttz.util.MenuBuilder.ItemAction; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zul.Menupopup; import org.zkoss.zul.impl.XulElement; /** - * Component to show the list of task in the planner + * Component to show the list of task in the planner. + * * @author Javier Moran Rua */ public class TaskList extends XulElement implements AfterCompose { @@ -79,6 +69,10 @@ public class TaskList extends XulElement implements AfterCompose { private Map taskComponentByTask; + private Map autoRemovedListers = new WeakHashMap<>(); + + private Map contextMenus = new HashMap<>(); + public TaskList( FunctionalityExposedForExtensions context, CommandOnTaskContextualized doubleClickCommand, @@ -114,15 +108,13 @@ public class TaskList extends XulElement implements AfterCompose { IDisabilityConfiguration disabilityConfiguration, FilterAndParentExpandedPredicates predicate) { - TaskList result = new TaskList( + return new TaskList( context, doubleClickCommand, context.getDiagramGraph().getTopLevelTasks(), commandsOnTasksContextualized, disabilityConfiguration, predicate); - - return result; } public List asDependencyComponents(Collection dependencies) { @@ -137,11 +129,11 @@ public class TaskList extends XulElement implements AfterCompose { } public DependencyComponent asDependencyComponent(Dependency dependency) { - return asDependencyComponents(Arrays.asList(dependency)).get(0); + return asDependencyComponents(Collections.singletonList(dependency)).get(0); } - private synchronized void addTaskComponent(TaskRow beforeThis, final TaskComponent taskComponent, - boolean relocate) { + private synchronized void addTaskComponent( + TaskRow beforeThis, final TaskComponent taskComponent, boolean relocate) { insertBefore(taskComponent.getRow(), beforeThis); addContextMenu(taskComponent); @@ -163,7 +155,7 @@ public class TaskList extends XulElement implements AfterCompose { currentTotalTasks.addAll(insertionPosition, newTasks); } - // if the position is children of some already existent task when + // If the position is children of some already existent task when // reloading it will be added if the predicate tells so reload(true); } @@ -182,13 +174,7 @@ public class TaskList extends XulElement implements AfterCompose { if ( doubleClickCommand == null ) { return; } - taskComponent.addEventListener("onDoubleClick", new EventListener() { - - @Override - public void onEvent(Event event) { - doubleClickCommand.doAction(taskComponent); - } - }); + taskComponent.addEventListener("onDoubleClick", event -> doubleClickCommand.doAction(taskComponent)); } private void addContextMenu(final TaskComponent taskComponent) { @@ -262,20 +248,12 @@ public class TaskList extends XulElement implements AfterCompose { return result; } - private Map autoRemovedListers = new WeakHashMap<>(); - private void addExpandListenerTo(TaskContainer container) { if ( autoRemovedListers.containsKey(container) ) { return; } - IExpandListener expandListener = new IExpandListener() { - - @Override - public void expandStateChanged(boolean isNowExpanded) { - reload(true); - } - }; + IExpandListener expandListener = (isNowExpanded -> reload(true)); container.addExpandListener(expandListener); autoRemovedListers.put(container, expandListener); @@ -283,6 +261,7 @@ public class TaskList extends XulElement implements AfterCompose { private void registerZoomLevelChangedListener() { if ( zoomLevelChangedListener == null ) { + /* Do not replace it with lambda */ zoomLevelChangedListener = new IZoomLevelChangedListener() { @Override public void zoomLevelChanged(ZoomLevel detailLevel) { @@ -301,25 +280,20 @@ public class TaskList extends XulElement implements AfterCompose { return interval.getStart().plusDays(daysInto); } - private Map contextMenus = new HashMap<>(); - private Menupopup getContextMenuFor(TaskComponent taskComponent) { if ( contextMenus.get(taskComponent) == null ) { MenuBuilder menuBuilder = MenuBuilder.on(getPage(), getTaskComponents()); if ( disabilityConfiguration.isAddingDependenciesEnabled() ) { - menuBuilder.item(_("Add Dependency"), "/common/img/ico_dependency.png", - new ItemAction() { - @Override - public void onEvent(TaskComponent choosen, Event event) { - choosen.addDependency(); - } - }); + + menuBuilder.item( + _("Add Dependency"), "/common/img/ico_dependency.png", + (chosen, event) -> chosen.addDependency()); } for (CommandOnTaskContextualized command : commandsOnTasksContextualized) { if ( command.accepts(taskComponent) ) { - menuBuilder.item(command.getName(), command.getIcon(), command.toItemAction()); + menuBuilder.item(command.getName(), command.getIcon(), command.toItemAction()); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java index 302f54146..086156365 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java @@ -126,14 +126,7 @@ public abstract class Task implements ITaskFundamentalProperties { @Override public void doPositionModifications(final IModifications modifications) { - fundamentalProperties.doPositionModifications(new IModifications() { - - @Override - public void doIt(IUpdatablePosition p) { - modifications.doIt(position); - - } - }); + fundamentalProperties.doPositionModifications(p -> modifications.doIt(position)); } private final IUpdatablePosition position = new IUpdatablePosition() { @@ -174,12 +167,7 @@ public abstract class Task implements ITaskFundamentalProperties { private IUpdatablePosition getFundamentalPropertiesPosition() { final IUpdatablePosition[] result = new IUpdatablePosition[1]; - fundamentalProperties.doPositionModifications(new IModifications() { - @Override - public void doIt(IUpdatablePosition position) { - result[0] = position; - } - }); + fundamentalProperties.doPositionModifications(position1 -> result[0] = position1); return result[0]; } @@ -342,12 +330,7 @@ public abstract class Task implements ITaskFundamentalProperties { return; } - doPositionModifications(new IModifications() { - @Override - public void doIt(IUpdatablePosition position) { - position.resizeTo(GanttDate.createFrom(date)); - } - }); + doPositionModifications(position1 -> position1.resizeTo(GanttDate.createFrom(date))); } public void removed() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java index e26aa6f6c..1001312c3 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java @@ -37,18 +37,18 @@ import org.zkoss.zk.ui.util.Clients; */ public class TaskContainer extends Task { - public TaskContainer(ITaskFundamentalProperties fundamentalProperties, - boolean expanded) { + public TaskContainer(ITaskFundamentalProperties fundamentalProperties, boolean expanded) { super(fundamentalProperties); this.expanded = expanded; } public interface IExpandListener { - public void expandStateChanged(boolean isNowExpanded); + void expandStateChanged(boolean isNowExpanded); } private static List removeNulls(Collection elements) { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); + for (T e : elements) { if (e != null) { result.add(e); @@ -57,22 +57,19 @@ public class TaskContainer extends Task { return result; } - private static > T getSmallest( - Collection elements) { + private static > T getSmallest(Collection elements) { return Collections.min(removeNulls(elements)); } - private static > T getBiggest( - Collection elements) { + private static > T getBiggest(Collection elements) { return Collections.max(removeNulls(elements)); } - private List tasks = new ArrayList(); + private List tasks = new ArrayList<>(); private boolean expanded = false; - private WeakReferencedListeners expandListeners = WeakReferencedListeners - .create(); + private WeakReferencedListeners expandListeners = WeakReferencedListeners.create(); public void addExpandListener(IExpandListener expandListener) { expandListeners.addListener(expandListener); @@ -89,17 +86,20 @@ public class TaskContainer extends Task { } private List getEndDates() { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); + for (Task task : tasks) { result.add(task.getEndDate()); } + return result; } public GanttDate getBiggestDateFromChildren() { - if (tasks.isEmpty()) { + if ( tasks.isEmpty() ) { return getEndDate(); } + return getBiggest(getEndDates()); } @@ -111,9 +111,11 @@ public class TaskContainer extends Task { @Override public void setVisible(boolean visible) { super.setVisible(visible); - if (!this.expanded) { + + if ( !this.expanded ) { return; } + for (Task task : tasks) { task.setVisible(true); } @@ -133,6 +135,7 @@ public class TaskContainer extends Task { } }); } + refreshTooltips(); } @@ -171,10 +174,12 @@ public class TaskContainer extends Task { @Override public List getAllTaskLeafs() { - List result = new ArrayList(); + List result = new ArrayList<>(); + for (Task task : tasks) { result.addAll(task.getAllTaskLeafs()); } + return result; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java index ad8f575e6..b719c8e51 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java @@ -23,6 +23,9 @@ package org.zkoss.ganttz.data.resourceload; import org.apache.commons.lang3.Validate; +/** + * Represents level of load of some {@link Resource}. + */ public class LoadLevel { public enum Category { @@ -56,6 +59,7 @@ public class LoadLevel { }; protected abstract boolean contains(int percentage); + public static Category categoryFor(int percentage) { for (Category category : values()) { if ( category.contains(percentage) ) { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java index 2b89e0dfa..b826534b5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java @@ -37,30 +37,17 @@ public class LoadTimeLine { @SuppressWarnings("unchecked") private static final Comparator nullSafeComparator = new NullComparator<>(false); - public static Comparator byStartAndEndDate() { - return new Comparator() { - @Override - public int compare(LoadTimeLine o1, LoadTimeLine o2) { - int result = nullSafeComparator.compare(o1.getStartPeriod(), o2.getStartPeriod()); - - if ( result == 0 ) { - return nullSafeComparator.compare(o1.getEndPeriod(), o2.getEndPeriod()); - } - - return result; - - } - }; - } - private final String conceptName; + private final List loadPeriods; private final TimeLineRole timeLineRole; + private final String type; private final List children; + public LoadTimeLine(String conceptName, List loadPeriods, TimeLineRole role) { @@ -101,6 +88,22 @@ public class LoadTimeLine { } + public static Comparator byStartAndEndDate() { + return new Comparator() { + @Override + public int compare(LoadTimeLine o1, LoadTimeLine o2) { + int result = nullSafeComparator.compare(o1.getStartPeriod(), o2.getStartPeriod()); + + if ( result == 0 ) { + return nullSafeComparator.compare(o1.getEndPeriod(), o2.getEndPeriod()); + } + + return result; + + } + }; + } + public List getLoadPeriods() { return loadPeriods; } @@ -122,11 +125,7 @@ public class LoadTimeLine { } public GanttDate getStartPeriod() { - if ( isEmpty() ) { - return null; - } - - return getFirst().getStart(); + return isEmpty() ? null : getFirst().getStart(); } public boolean isEmpty() { @@ -134,11 +133,7 @@ public class LoadTimeLine { } public GanttDate getEndPeriod() { - if ( isEmpty() ) { - return null; - } - - return getLast().getEnd(); + return isEmpty() ? null : getLast().getEnd(); } public String getType() { @@ -192,7 +187,7 @@ public class LoadTimeLine { } public boolean hasChildren() { - return (!children.isEmpty()); + return !children.isEmpty(); } public List getChildren() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java index 54f9b2f61..7f72a7622 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java @@ -21,8 +21,6 @@ package org.zkoss.ganttz.data.resourceload; -import org.zkoss.ganttz.i18n.I18nHelper; - /** * @author Susana Montes Pedreira */ @@ -39,7 +37,7 @@ public class TimeLineRole { } public boolean isVisibleScheduled() { - return type != null ? type.isVisibleScheduled() : false; + return type != null && type.isVisibleScheduled(); } public T getEntity() { @@ -55,7 +53,10 @@ public class TimeLineRole { */ public enum TimeLineRoleEnum { - NONE(_("None")), WORKER(_("Worker")), ORDER(_("Project")), TASK(_("Task")) { + NONE(_("None")), + WORKER(_("Worker")), + ORDER(_("Project")), + TASK(_("Task")) { @Override public boolean isVisibleScheduled() { return true; @@ -63,19 +64,19 @@ public class TimeLineRole { }, CRITERION(_("Criterion")); + private String name; + + TimeLineRoleEnum(String name) { + this.name = name; + } + /** - * Forces to mark the string as needing translation + * Forces to mark the string as needing translation. */ private static String _(String string) { return string; } - private String name; - - private TimeLineRoleEnum(String name) { - this.name = name; - } - public static TimeLineRoleEnum create(String name) { TimeLineRoleEnum requiredTimeLineRole = TimeLineRoleEnum.NONE; if (name != null) { @@ -88,8 +89,9 @@ public class TimeLineRole { return requiredTimeLineRole; } + @Override public String toString() { - return I18nHelper._(this.name); + return _(this.name); } public boolean isVisibleScheduled() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java b/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java index 186ad8412..2e0dcefea 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java @@ -23,25 +23,24 @@ package org.zkoss.ganttz.extensions; /** - * An action that can be applied to the planner and it's wanted to be available - * to the user
+ * An action that can be applied to the planner and it's wanted to be available to the user
* * @author Óscar González Fernández * @author Manuel Rego Casasnovas */ public interface ICommand { - public String getName(); + String getName(); - public void doAction(IContext context); + void doAction(IContext context); - public String getImage(); + String getImage(); boolean isDisabled(); /** - * Describes if a command is for the planner toolbar. Otherwise it'll be - * inserted in the common toolbar. + * Describes if a command is for the planner toolbar. + * Otherwise it will be inserted in the common toolbar. */ boolean isPlannerCommand(); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java b/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java index 2bbed8892..bfa327554 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java @@ -34,7 +34,7 @@ public class I18nHelper { private static HashMap localesCache = new HashMap<>(); public static I18n getI18n() { - if ( localesCache.keySet().contains(Locales.getCurrent()) ) { + if (localesCache.keySet().contains(Locales.getCurrent())) { return localesCache.get(Locales.getCurrent()); } @@ -48,7 +48,15 @@ public class I18nHelper { return i18n; } - // TODO refactor symbol _ + + + //TODO It should be changed since JDK9. + /** + * Use of '_' as an identifier might not be supported in releases after Java SE 8. + * + * @param str + * @return Text depends on locale + */ public static String _(String str) { return getI18n().tr(str); } @@ -65,8 +73,7 @@ public class I18nHelper { return getI18n().tr(text, o1, o2, o3); } - public static String _(String text, Object o1, Object o2, Object o3, - Object o4) { + public static String _(String text, Object o1, Object o2, Object o3, Object o4) { return getI18n().tr(text, o1, o2, o3, o4); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java index 47207786a..b7e675bd7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java @@ -23,6 +23,6 @@ package org.zkoss.ganttz.resourceload; public interface IFilterChangedListener { - public void filterChanged(boolean filter); + void filterChanged(boolean filter); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java index 8006de012..b0bee8ea1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java @@ -23,6 +23,6 @@ package org.zkoss.ganttz.resourceload; public interface IPaginationFilterChangedListener { - public void filterChanged(int initialPosition); + void filterChanged(int initialPosition); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java index 990951456..d943327c7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java @@ -25,6 +25,6 @@ import org.zkoss.ganttz.data.resourceload.LoadTimeLine; public interface ISeeScheduledOfListener { - public void seeScheduleOf(LoadTimeLine taskLine); + void seeScheduleOf(LoadTimeLine taskLine); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java index f084d21a2..81d9e5c07 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java @@ -36,11 +36,7 @@ import org.zkoss.ganttz.timetracker.TimeTracker; import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.MenuBuilder; -import org.zkoss.ganttz.util.MenuBuilder.ItemAction; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.sys.ContentRenderer; import org.zkoss.zul.Div; import org.zkoss.zul.Menupopup; @@ -48,38 +44,54 @@ import org.zkoss.zul.impl.XulElement; /** * This class wraps ResourceLoad data inside an specific HTML Div component. + * * @author Lorenzo Tilve Álvaro + * @author Vova Perebykivskyi */ public class ResourceLoadComponent extends XulElement { - public static ResourceLoadComponent create(TimeTracker timeTracker, - LoadTimeLine loadLine) { - return new ResourceLoadComponent(timeTracker, loadLine); - } - private final LoadTimeLine loadLine; - private final TimeTracker timeTracker; - private transient IZoomLevelChangedListener zoomChangedListener; - private WeakReferencedListeners scheduleListeners = WeakReferencedListeners - .create(); - private ResourceLoadComponent(final TimeTracker timeTracker, - final LoadTimeLine loadLine) { + private final TimeTracker timeTracker; + + private transient IZoomLevelChangedListener zoomChangedListener; + + private WeakReferencedListeners scheduleListeners = WeakReferencedListeners.create(); + + private Map contextMenus = new HashMap<>(); + + private ResourceLoadComponent(final TimeTracker timeTracker, final LoadTimeLine loadLine) { this.loadLine = loadLine; this.timeTracker = timeTracker; createChildren(loadLine, timeTracker.getMapper()); + + /* Do not replace it with lambda */ zoomChangedListener = new IZoomLevelChangedListener() { + /** + * In general it is working like, on every zoomChanged : + * 1. Remove all LoadLines ( divs ). + * 2. Create new ones ( for selected zoom mode ). + * 3. Redraw insertionPointRightPanel component ( Div ). + */ @Override public void zoomLevelChanged(ZoomLevel detailLevel) { getChildren().clear(); createChildren(loadLine, timeTracker.getMapper()); + if ( !getFellows().isEmpty() ) { + getFellow("insertionPointRightPanel").invalidate(); + } invalidate(); } }; + this.timeTracker.addZoomListener(zoomChangedListener); } + public static ResourceLoadComponent create(TimeTracker timeTracker, LoadTimeLine loadLine) { + return new ResourceLoadComponent(timeTracker, loadLine); + } + private void createChildren(final LoadTimeLine loadLine, IDatesMapper mapper) { List
divs = createDivsForPeriods(mapper, loadLine.getLoadPeriods()); for (Div div : divs) { @@ -95,71 +107,50 @@ public class ResourceLoadComponent extends XulElement { } private void addDoubleClickAction(final Div div, final LoadTimeLine loadLine) { - div.addEventListener("onDoubleClick", new EventListener() { - @Override - public void onEvent(Event event) { - schedule(loadLine); - } - }); + div.addEventListener("onDoubleClick", event -> schedule(loadLine)); } - private void addContextMenu(final List
divs, final Div div, - final LoadTimeLine loadLine) { + private void addContextMenu(final List
divs, final Div div, final LoadTimeLine loadLine) { /* * This EventListener could be replaced with * div.setContext(getContextMenuFor(divs, div, loadLine)) but - * on this case this is not valid as we'll got an exception. + * in this case this is not valid as we'll got an exception. + * * As this component (ResourceLoadComponent) hasn't be added to * a page yet, its getPage() method will return null and a - * non-null page is required by MenuBuilder or a NullPointerException - * will be raised. - * */ - div.addEventListener("onRightClick", new EventListener() { - @Override - public void onEvent(Event event) { - try { - getContextMenuFor(divs, div, loadLine).open(div); - } catch (Exception e) { - e.printStackTrace(); - } + * non-null page is required by MenuBuilder or a NullPointerException will be raised. + */ + + div.addEventListener("onRightClick", event -> { + try { + getContextMenuFor(divs, div, loadLine).open(div); + } catch (Exception e) { + e.printStackTrace(); } }); } public void schedule(final LoadTimeLine taskLine) { - - scheduleListeners - .fireEvent(new IListenerNotification() { - @Override - public void doNotify(ISeeScheduledOfListener listener) { - listener.seeScheduleOf(taskLine); - } - }); + scheduleListeners.fireEvent(listener -> listener.seeScheduleOf(taskLine)); } - public void addSeeScheduledOfListener( - ISeeScheduledOfListener seeScheduledOfListener) { + public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) { scheduleListeners.addListener(seeScheduledOfListener); } - private Map contextMenus = new HashMap(); - - private Menupopup getContextMenuFor(final List
divs, final Div div, - final LoadTimeLine loadLine) { + private Menupopup getContextMenuFor(final List
divs, final Div div, final LoadTimeLine loadLine) { if (contextMenus.get(div) == null) { MenuBuilder
menuBuilder = MenuBuilder.on(getPage(), divs); - menuBuilder.item(_("See resource allocation"), - "/common/img/ico_allocation.png", new ItemAction
() { - @Override - public void onEvent(Div choosen, Event event) { - schedule(loadLine); - } - }); + menuBuilder.item( + _("See resource allocation"), + "/common/img/ico_allocation.png", + (chosen, event) -> schedule(loadLine)); Menupopup result = menuBuilder.createWithoutSettingContext(); contextMenus.put(div, result); + return result; } @@ -174,52 +165,56 @@ public class ResourceLoadComponent extends XulElement { return loadLine.getType(); } + LoadTimeLine getLoadLine() { + return loadLine; + } - private static List
createDivsForPeriods(IDatesMapper datesMapper, - List loadPeriods) { - List
result = new ArrayList
(); + private static List
createDivsForPeriods(IDatesMapper datesMapper, List loadPeriods) { + List
result = new ArrayList<>(); for (LoadPeriod loadPeriod : loadPeriods) { result.add(createDivForPeriod(datesMapper, loadPeriod)); } return result; } - private static Div createDivForPeriod(IDatesMapper datesMapper, - LoadPeriod loadPeriod) { + private static Div createDivForPeriod(IDatesMapper datesMapper, LoadPeriod loadPeriod) { Div result = new Div(); - result.setClass(String.format("taskassignmentinterval %s", loadPeriod - .getLoadLevel().getCategory())); + result.setClass(String.format("taskassignmentinterval %s", loadPeriod.getLoadLevel().getCategory())); + + String load = _("Load: {0}%", loadPeriod.getLoadLevel().getPercentage()) + ", "; - String load = _("Load: {0}%", loadPeriod.getLoadLevel().getPercentage()) - + ", "; if (loadPeriod.getLoadLevel().getPercentage() == Integer.MAX_VALUE) { load = ""; } - result.setTooltiptext(load - + _("available effort: {0}, assigned effort: {1}", - loadPeriod.getAvailableEffort(), - loadPeriod.getAssignedEffort())); + + result.setTooltiptext( + load + + _("available effort: {0}, assigned effort: {1}", + loadPeriod.getAvailableEffort(), + loadPeriod.getAssignedEffort())); result.setLeft(forCSS(getStartPixels(datesMapper, loadPeriod))); result.setWidth(forCSS(getWidthPixels(datesMapper, loadPeriod))); + return result; } - private static int getWidthPixels(IDatesMapper datesMapper, - LoadPeriod loadPeriod) { - return Math.max(loadPeriod.getEnd().toPixels(datesMapper) - - getStartPixels(datesMapper, loadPeriod), 0); + private static int getWidthPixels(IDatesMapper datesMapper, LoadPeriod loadPeriod) { + return Math.max(loadPeriod.getEnd().toPixels(datesMapper) - getStartPixels(datesMapper, loadPeriod), 0); } private static String forCSS(int pixels) { return String.format("%dpx", pixels); } - private static int getStartPixels(IDatesMapper datesMapper, - LoadPeriod loadPeriod) { + private static int getStartPixels(IDatesMapper datesMapper, LoadPeriod loadPeriod) { return loadPeriod.getStart().toPixels(datesMapper); } + /** + * It is drawing chart on right pane for each ResourceLoad row. + */ + @Override protected void renderProperties(ContentRenderer renderer) throws IOException{ render(renderer, "_resourceLoadName", getResourceLoadName()); render(renderer, "_resourceLoadType", getResourceLoadType()); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java index 0b5b321a8..77fa98c20 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java @@ -24,65 +24,106 @@ package org.zkoss.ganttz.resourceload; import static org.zkoss.ganttz.i18n.I18nHelper._; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import java.util.HashSet; import org.zkoss.ganttz.data.resourceload.LoadTimeLine; import org.zkoss.ganttz.util.MutableTreeModel; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.OpenEvent; -import org.zkoss.zul.Button; -import org.zkoss.zul.Div; -import org.zkoss.zul.Label; -import org.zkoss.zul.Popup; import org.zkoss.zul.Treecell; -import org.zkoss.zul.Treechildren; import org.zkoss.zul.Treeitem; import org.zkoss.zul.TreeitemRenderer; import org.zkoss.zul.Treerow; -import org.zkoss.zul.api.Tree; +import org.zkoss.zul.Button; +import org.zkoss.zul.Div; +import org.zkoss.zul.Label; +import org.zkoss.zul.Tree; +import org.zkoss.zul.Treechildren; +/** + * Works with left pane of Resource Load page. Also works with right pane ( a little bit ). + * + * @author Óscar González Fernández + * @author Manuel Rego Casasnovas + * @author Susana Montes Pedreira + * @author Lorenzo Tilve + * @author Jacobo Aragunde Pérez + * @author Vova Perebykivskyi + */ public class ResourceLoadLeftPane extends HtmlMacroComponent { private MutableTreeModel modelForTree; + private final ResourceLoadList resourceLoadList; - private WeakReferencedListeners scheduleListeners = WeakReferencedListeners - .create(); + private WeakReferencedListeners scheduleListeners = WeakReferencedListeners.create(); - public ResourceLoadLeftPane( -MutableTreeModel modelForTree, - ResourceLoadList resourceLoadList) { + /** + * {@link ResourceLoadLeftPane#onOpenEventQueue}, {@link OnOpenEvent} and proceedOnOpenEventQueue() + * were created because of problem: + * after migration from ZK5 to ZK8 onOpen event had been calling before render(). + * It produced a problem. + * On onOpen event we are calculating closest items to treeItem. + * render() was not called so, treeItem row had no value. + * It made calculatedClosedItems(treeItem).isEmpty() to return true, even if it is not! + * + * http://forum.zkoss.org/question/101294/event-before-render-treeitem/ + */ + private OnOpenEvent onOpenEventQueue = null; + + /** + * Made to know if {@link LoadTimeLine} was rendered. + */ + private HashSet renderedLines; + + + public ResourceLoadLeftPane(MutableTreeModel modelForTree, ResourceLoadList resourceLoadList) { this.resourceLoadList = resourceLoadList; this.modelForTree = modelForTree; + this.renderedLines = new HashSet<>(); } - @Override public void afterCompose() { super.afterCompose(); + getContainerTree().setModel(modelForTree); - getContainerTree().setTreeitemRenderer(getRendererForTree()); + getContainerTree().setItemRenderer(getRendererForTree()); + + /* Force call overridden render() */ + try { + if ( !this.resourceLoadList.getChildren().isEmpty() ) { + getRendererForTree().render( + new Treeitem(""), + ((ResourceLoadComponent) this.resourceLoadList.getFirstChild()).getLoadLine(), + 0); + } + } catch (Exception e) { + e.printStackTrace(); + } } private TreeitemRenderer getRendererForTree() { return new TreeitemRenderer() { @Override - public void render(Treeitem item, Object data) - { - LoadTimeLine line = (LoadTimeLine) data; - item.setOpen(false); - item.setValue(line); + public void render(Treeitem treeitem, Object o, int index) throws Exception { + LoadTimeLine line = (LoadTimeLine) o; + treeitem.setOpen(false); + treeitem.setValue(line); Treerow row = new Treerow(); Treecell cell = new Treecell(); Component component = createComponent(line); - item.appendChild(row); + + /* Clear existing Treerows */ + if ( !treeitem.getChildren().isEmpty() ) { + treeitem.getChildren().clear(); + } + + treeitem.appendChild(row); row.appendChild(cell); appendOperations(cell, line); @@ -90,70 +131,86 @@ MutableTreeModel modelForTree, cell.appendChild(component); collapse(line); - addExpandedListener(item, line); + addExpandedListener(treeitem, line); row.setSclass("resourceload-leftpanel-row"); + + if ( onOpenEventQueue != null ) { + processOnOpenEventQueue(); + } + + renderedLines.add(line); } - private void appendOperations(final Treecell cell, - final LoadTimeLine line) { - if (line.getRole().isVisibleScheduled()) { + private void processOnOpenEventQueue() { + if ( onOpenEventQueue.event.isOpen() ) { + List closed = calculatedClosedItems(onOpenEventQueue.treeitem); + expand(onOpenEventQueue.line, closed); + } else { + collapse(onOpenEventQueue.line); + } + + /* + * When queue processed, clean object, to make it kind of "unique" or "one time only". + */ + onOpenEventQueue = null; + } + + private void appendOperations(final Treecell cell, final LoadTimeLine line) { + if ( line.getRole().isVisibleScheduled() ) { appendButtonPlan(cell, line); } } - private void appendButtonPlan(final Treecell cell, - final LoadTimeLine taskLine) { + private void appendButtonPlan(final Treecell cell, final LoadTimeLine taskLine) { Button buttonPlan = new Button(); buttonPlan.setSclass("icono"); buttonPlan.setImage("/common/img/ico_planificador1.png"); buttonPlan.setHoverImage("/common/img/ico_planificador.png"); buttonPlan.setTooltiptext(_("See scheduling")); - buttonPlan.addEventListener("onClick", new EventListener() { - @Override - public void onEvent(Event event) { - schedule(taskLine); - } - }); + buttonPlan.addEventListener("onClick", event -> schedule(taskLine)); + cell.appendChild(buttonPlan); } + /** + * Do not replace it with lambda. + */ public void schedule(final LoadTimeLine taskLine) { - - scheduleListeners - .fireEvent(new IListenerNotification() { + scheduleListeners.fireEvent( + new WeakReferencedListeners.IListenerNotification() { @Override - public void doNotify( - ISeeScheduledOfListener listener) { + public void doNotify(ISeeScheduledOfListener listener) { listener.seeScheduleOf(taskLine); } }); } - private void addExpandedListener(final Treeitem item, - final LoadTimeLine line) { - item.addEventListener("onOpen", new EventListener() { - @Override - public void onEvent(Event event) { - OpenEvent openEvent = (OpenEvent) event; - if (openEvent.isOpen()) { - List closed = calculatedClosedItems(item); - expand(line, closed); - } else { - collapse(line); + private void addExpandedListener(final Treeitem item, final LoadTimeLine line) { + item.addEventListener("onOpen", event -> { + OpenEvent openEvent = (OpenEvent) event; + + if ( openEvent.isOpen() ) { + + onOpenEventQueue = new OnOpenEvent(item, line, openEvent); + + /* If line was rendered than we need to call expand manually */ + if ( renderedLines.contains(line) ) { + processOnOpenEventQueue(); } + + } else { + collapse(line); } }); } private Component createComponent(LoadTimeLine line) { - return isTopLevel(line) ? createFirstLevel(line) - : createSecondLevel(line); + return isTopLevel(line) ? createFirstLevel(line) : createSecondLevel(line); } private boolean isTopLevel(LoadTimeLine line) { - int[] path = modelForTree.getPath(modelForTree.getRoot(), line); - return path.length == 0; + return modelForTree.getPath(modelForTree.getRoot(), line).length == 0; } }; } @@ -167,40 +224,45 @@ MutableTreeModel modelForTree, } private List calculatedClosedItems(Treeitem item) { - List result = new ArrayList(); + List result = new ArrayList<>(); Treechildren treeChildren = item.getTreechildren(); - if (treeChildren != null) { - List myTreeItems = (List) treeChildren - .getChildren(); - Iterator iterator = myTreeItems.iterator(); - while (iterator.hasNext()) { - Treeitem child = (Treeitem) iterator.next(); - if (!child.isOpen()) { + + if ( treeChildren != null ) { + + List myTreeItems = treeChildren.getChildren(); + for (Treeitem child : myTreeItems) { + + if ( !child.isOpen() ) { result.addAll(getLineChildrenBy(child)); } else { result.addAll(calculatedClosedItems(child)); } } } + return result; } private List getLineChildrenBy(Treeitem item) { - List result = new ArrayList(); + List result = new ArrayList<>(); LoadTimeLine line = getLineByTreeitem(item); - if (line != null) { + + if ( line != null ) { result.addAll(line.getAllChildren()); } + return result; } private LoadTimeLine getLineByTreeitem(Treeitem child) { - LoadTimeLine line = null; + LoadTimeLine line; + try { - line = (LoadTimeLine) child.getValue(); + line = child.getValue(); } catch (Exception e) { return null; } + return line; } @@ -211,12 +273,14 @@ MutableTreeModel modelForTree, private Component createFirstLevel(LoadTimeLine main) { Div result = createLabelWithName(main); result.setSclass("firstlevel"); + return result; } private Component createSecondLevel(LoadTimeLine loadTimeLine) { Div result = createLabelWithName(loadTimeLine); result.setSclass("secondlevel"); + return result; } @@ -224,20 +288,32 @@ MutableTreeModel modelForTree, Div result = new Div(); Label label = new Label(); final String conceptName = main.getConceptName(); + label.setValue(conceptName); result.appendChild(label); + return result; } - private static Popup createPopup(Div parent, String originalValue) { - Popup result = new Popup(); - result.appendChild(new Label(originalValue)); - parent.appendChild(result); - return result; - } - - public void addSeeScheduledOfListener( - ISeeScheduledOfListener seeScheduledOfListener) { + public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) { scheduleListeners.addListener(seeScheduledOfListener); } + + /** + * Info about onOpenEvent. + */ + private class OnOpenEvent { + + private LoadTimeLine line; + + private Treeitem treeitem; + + private OpenEvent event; + + OnOpenEvent(Treeitem treeitem, LoadTimeLine line, OpenEvent event) { + this.line = line; + this.treeitem = treeitem; + this.event = event; + } + } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java index 8418da53f..9d1cc4bc3 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java @@ -40,27 +40,26 @@ import org.zkoss.zul.impl.XulElement; /** * Component to include a list of ResourceLoads inside the ResourcesLoadPanel. + * * @author Lorenzo Tilve Álvaro + * @author Vova Perebykivskyi */ public class ResourceLoadList extends XulElement { - private final IZoomLevelChangedListener zoomListener; + private Map fromTimeLineToComponent = new HashMap<>(); - private Map fromTimeLineToComponent = new HashMap(); - - public ResourceLoadList(TimeTracker timeTracker, - MutableTreeModel timelinesTree) { - zoomListener = adjustTimeTrackerSizeListener(); + public ResourceLoadList(TimeTracker timeTracker, MutableTreeModel timelinesTree) { + IZoomLevelChangedListener zoomListener = adjustTimeTrackerSizeListener(); timeTracker.addZoomListener(zoomListener); LoadTimeLine current = timelinesTree.getRoot(); - List toInsert = new ArrayList(); + List toInsert = new ArrayList<>(); fill(timelinesTree, current, toInsert); insertAsComponents(timeTracker, toInsert); } - private void fill(MutableTreeModel timelinesTree, - LoadTimeLine current, List result) { + private void fill(MutableTreeModel timelinesTree, LoadTimeLine current, List result) { final int length = timelinesTree.getChildCount(current); + for (int i = 0; i < length; i++) { LoadTimeLine child = timelinesTree.getChild(current, i); result.add(child); @@ -70,41 +69,48 @@ public class ResourceLoadList extends XulElement { private IZoomLevelChangedListener adjustTimeTrackerSizeListener() { return new IZoomLevelChangedListener() { - @Override public void zoomLevelChanged(ZoomLevel detailLevel) { - response(null, new AuInvoke(ResourceLoadList.this, - "adjustTimeTrackerSize")); - response(null, new AuInvoke(ResourceLoadList.this, - "adjustResourceLoadRows")); + response(null, new AuInvoke(ResourceLoadList.this, "adjustTimeTrackerSize")); + response(null, new AuInvoke(ResourceLoadList.this, "adjustResourceLoadRows")); } }; } - private void insertAsComponents(TimeTracker timetracker, - List children) { + private void insertAsComponents(TimeTracker timetracker, List children) { for (LoadTimeLine loadTimeLine : children) { - ResourceLoadComponent component = ResourceLoadComponent.create( - timetracker, loadTimeLine); + ResourceLoadComponent component = ResourceLoadComponent.create(timetracker, loadTimeLine); appendChild(component); fromTimeLineToComponent.put(loadTimeLine, component); } } + /** + * On Resources Load page it will collapse inherited resources. + * + * @param line + */ public void collapse(LoadTimeLine line) { for (LoadTimeLine l : line.getAllChildren()) { getComponentFor(l).detach(); } + /* In ZK8, after detaching component, component will be still visible, so we need to redraw it */ + this.invalidate(); + Clients.evalJavaScript(getWidgetClass() + ".getInstance().recalculateTimeTrackerHeight();"); } private ResourceLoadComponent getComponentFor(LoadTimeLine l) { - ResourceLoadComponent resourceLoadComponent = fromTimeLineToComponent - .get(l); - return resourceLoadComponent; + return fromTimeLineToComponent.get(l); } + /** + * On Resources Load page it will expand inherited resources. + * + * @param line + * @param closed + */ public void expand(LoadTimeLine line, List closed) { ResourceLoadComponent parentComponent = getComponentFor(line); Component nextSibling = parentComponent.getNextSibling(); @@ -118,19 +124,21 @@ public class ResourceLoadList extends XulElement { nextSibling = child; } + /* In ZK8, after detaching component, component will be still visible, so we need to redraw it */ + this.invalidate(); + Clients.evalJavaScript(getWidgetClass() + ".getInstance().recalculateTimeTrackerHeight();"); } private List getChildrenReverseOrderFor(LoadTimeLine line) { List childrenOf = line.getAllChildren(); Collections.reverse(childrenOf); + return childrenOf; } - public void addSeeScheduledOfListener( - ISeeScheduledOfListener seeScheduledOfListener) { - for (Entry entry : fromTimeLineToComponent - .entrySet()) { + public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) { + for (Entry entry : fromTimeLineToComponent.entrySet()) { entry.getValue().addSeeScheduledOfListener(seeScheduledOfListener); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java index 0244acc6a..971c4b10f 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java @@ -38,25 +38,24 @@ import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; import org.zkoss.ganttz.util.MutableTreeModel; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.au.out.AuInvoke; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zul.Button; import org.zkoss.zul.Comboitem; import org.zkoss.zul.ListModel; import org.zkoss.zul.Separator; import org.zkoss.zul.SimpleListModel; -import org.zkoss.zul.api.Combobox; -import org.zkoss.zul.api.Listbox; -import org.zkoss.zul.api.South; +import org.zkoss.zul.Combobox; +import org.zkoss.zul.Listbox; +import org.zkoss.zul.South; +import org.zkoss.zul.Div; public class ResourcesLoadPanel extends HtmlMacroComponent { public interface IToolbarCommand { + void doAction(); String getLabel(); @@ -84,17 +83,24 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private WeakReferencedListeners zoomListeners = WeakReferencedListeners.create(); - private Listbox listZoomLevels; - private final String FILTER_RESOURCES = _("Resources"); + private final String FILTER_CRITERIA = _("Generic allocation criteria"); + + private final String FILTER_BY_NAME_COMBO_COMPONENT = "filterByNameCombo"; + private String feedBackMessage; + private Boolean filterbyResources; private boolean refreshNameFilter = true; + private int filterByNamePosition = 0; + private int numberOfGroupsByName = 10; + private int lastSelectedName = 0; + private final PaginationType paginationType; private WeakReferencedListeners nameFilterListener = @@ -113,12 +119,14 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private Component secondOptionalFilter; - public ResourcesLoadPanel( - List groups, - TimeTracker timeTracker, - Component componentOnWhichGiveFeedback, - boolean expandResourceLoadViewCharts, - PaginationType paginationType) { + private Combobox filterByNameCombo; + + + public ResourcesLoadPanel(List groups, + TimeTracker timeTracker, + Component componentOnWhichGiveFeedback, + boolean expandResourceLoadViewCharts, + PaginationType paginationType) { this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback; this.expandResourceLoadViewCharts = expandResourceLoadViewCharts; @@ -141,10 +149,8 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { return timeTracker; } - public ListModel getFilters() { - String[] filters = new String[] { FILTER_RESOURCES, FILTER_CRITERIA }; - - return new SimpleListModel(filters); + public ListModel getFilters() { + return new SimpleListModel<>(new String[] { FILTER_RESOURCES, FILTER_CRITERIA }); } public void setFilter(String filterby) { @@ -184,19 +190,14 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } private void applyFilter() { - zoomListeners.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IFilterChangedListener listener) { - listener.filterChanged(getFilter()); - } - }); + zoomListeners.fireEvent(listener -> listener.filterChanged(getFilter())); } public void addFilterListener(IFilterChangedListener listener) { zoomListeners.addListener(listener); } - public ListModel getZoomLevels() { + public ListModel getZoomLevels() { ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE, ZoomLevel.DETAIL_TWO, @@ -204,7 +205,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { ZoomLevel.DETAIL_FOUR, ZoomLevel.DETAIL_FIVE }; - return new SimpleListModel(selectableZoomlevels); + return new SimpleListModel<>(selectableZoomlevels); } public void setZoomLevel(final ZoomLevel zoomLevel) { @@ -213,6 +214,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { timeTracker.setZoomLevel(zoomLevel); } + public void zoomIncrease() { savePreviousData(); getTimeTrackerComponent().updateDayScroll(); @@ -265,12 +267,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private Button asButton(final IToolbarCommand c) { Button result = new Button(); - result.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event event) { - c.doAction(); - } - }); + result.addEventListener(Events.ON_CLICK, event -> c.doAction()); if ( !StringUtils.isEmpty(c.getImage()) ) { result.setImage(c.getImage()); @@ -290,13 +287,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } private Component getToolbar() { - Component toolbar = getFellow("toolbar"); - - return toolbar; + return getFellow("toolbar"); } private MutableTreeModel createModelForTree() { MutableTreeModel result = MutableTreeModel.create(LoadTimeLine.class); + for (LoadTimeLine loadTimeLine : this.getGroupsToShow()) { result.addToRoot(loadTimeLine); result = addNodes(result, loadTimeLine); @@ -322,20 +318,21 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { return new TimeTrackerComponent(timeTracker) { @Override protected void scrollHorizontalPercentage(int daysDisplacement) { - response("", new AuInvoke(resourceLoadList, "scroll_horizontal", daysDisplacement + "")); + response("", new AuInvoke(resourceLoadList, "scroll_horizontal", Integer.toString(daysDisplacement))); moveCurrentPositionScroll(); } @Override protected void moveCurrentPositionScroll() { - // get the previous data. + // Get the previous data LocalDate previousStart = getPreviousStart(); - // get the current data + // Get the current data int diffDays = getTimeTrackerComponent().getDiffDays(previousStart); double pixelPerDay = getTimeTrackerComponent().getPixelPerDay(); - response("move_scroll", new AuInvoke(resourceLoadList, "move_scroll", "" + diffDays, "" + pixelPerDay)); + response("move_scroll", new AuInvoke( + resourceLoadList, "move_scroll", Integer.toString(diffDays), Double.toString(pixelPerDay))); } protected void updateCurrentDayScroll() { @@ -343,7 +340,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { response( "update_day_scroll", - new AuInvoke(resourceLoadList, "update_day_scroll", "" + previousPixelPerDay)); + new AuInvoke(resourceLoadList, "update_day_scroll", Double.toString(previousPixelPerDay))); } }; @@ -356,8 +353,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { getFellow("insertionPointLeftPanel").appendChild(leftPane); leftPane.afterCompose(); - getFellow("insertionPointRightPanel").appendChild(timeTrackerComponent); - getFellow("insertionPointRightPanel").appendChild(resourceLoadList); + Div insertionPointRightPanel = (Div) getFellow("insertionPointRightPanel"); + insertionPointRightPanel.appendChild(timeTrackerComponent); + insertionPointRightPanel.appendChild(resourceLoadList); + TimeTrackerComponent timeTrackerHeader = createTimeTrackerHeader(); getFellow("insertionPointTimetracker").appendChild(timeTrackerHeader); @@ -374,21 +373,30 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { timeTrackerHeader.afterCompose(); timeTrackerComponent.afterCompose(); - listZoomLevels = (Listbox) getFellow("listZoomLevels"); + Listbox listZoomLevels = (Listbox) getFellow("listZoomLevels"); listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal()); + filterByNameCombo = (Combobox) getFellow(FILTER_BY_NAME_COMBO_COMPONENT); + filterByNameCombo.setWidth("85px"); + if ( paginationType == PaginationType.INTERNAL_PAGINATION && refreshNameFilter ) { setupNameFilter(); } else if ( paginationType == PaginationType.NONE ) { - getFellow("filterByNameCombo").setVisible(false); + getFellow(FILTER_BY_NAME_COMBO_COMPONENT).setVisible(false); getFellow("filterByNameLabel").setVisible(false); } getFellow("insertionPointChart").appendChild(loadChart); + this.visibleChart = expandResourceLoadViewCharts; this.visibleChart = expandResourceLoadViewCharts; ((South) getFellow("graphics")).setOpen(this.visibleChart); + + if (!visibleChart) { + ((South) getFellow("graphics")).setTitle(_("Graphics are disabled")); + } + savePreviousData(); } @@ -417,18 +425,14 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private TimeTrackerComponent createTimeTrackerHeader() { return new TimeTrackerComponent(timeTracker) { - - @Override - protected void scrollHorizontalPercentage(int pixelsDisplacement) { - } + @Override + protected void scrollHorizontalPercentage(int pixelsDisplacement) {} @Override - protected void moveCurrentPositionScroll() { - } + protected void moveCurrentPositionScroll() {} @Override - protected void updateCurrentDayScroll() { - } + protected void updateCurrentDayScroll() {} }; } @@ -438,7 +442,6 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } private void setupNameFilter() { - Combobox filterByNameCombo = (Combobox) getFellow("filterByNameCombo"); filterByNameCombo.getChildren().clear(); int size = groups.size(); @@ -469,7 +472,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { Comboitem lastItem = new Comboitem(); lastItem.setLabel(_("All")); lastItem.setDescription(_("Show all elements")); - lastItem.setValue(new Integer(-1)); + lastItem.setValue(-1); filterByNameCombo.appendChild(lastItem); filterByNameCombo.setSelectedIndex(0); @@ -477,26 +480,28 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } /** - * Returns only the LoadTimeLine objects that have to be show - * according to the name filter. - * @return + * @return only the LoadTimeLine objects that have to be show according to the name filter. */ private List getGroupsToShow() { if ( paginationType != PaginationType.INTERNAL_PAGINATION || filterByNamePosition == -1 ) { return groups; } - boolean condition = (filterByNamePosition + numberOfGroupsByName < groups.size()); + boolean condition = filterByNamePosition + numberOfGroupsByName < groups.size(); int endPosition = condition ? filterByNamePosition + numberOfGroupsByName : groups.size(); return groups.subList(filterByNamePosition, endPosition); } + /** + * Should be public! + * Used in resourcesLoadLayout.zul + */ public void onSelectFilterByName(Combobox comboByName) { - if ( comboByName.getSelectedItemApi() == null ) { + if ( comboByName.getSelectedItem() == null ) { resetComboByName(comboByName); } else { - Integer filterByNamePosition = (Integer) comboByName.getSelectedItemApi().getValue(); + Integer filterByNamePosition = comboByName.getSelectedItem().getValue(); if ( paginationType != PaginationType.NONE ) { this.filterByNamePosition = filterByNamePosition; @@ -523,7 +528,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { public void doAction() { if ( paginationType == PaginationType.INTERNAL_PAGINATION ) { - //if the pagination is internal, we are in charge of repainting the graph + // If the pagination is internal, we are in charge of repainting the graph treeModel = createModelForTree(); timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker); @@ -531,12 +536,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList); } - nameFilterListener.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IPaginationFilterChangedListener listener) { - listener.filterChanged(filterByNamePosition); - } - }); + nameFilterListener.fireEvent(listener -> listener.filterChanged(filterByNamePosition)); afterCompose(); } @@ -549,9 +549,9 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } public void setInternalPaginationDisabled(boolean disabled) { - Combobox combo = ((Combobox) getFellow("filterByNameCombo")); + Combobox combo = (Combobox) getFellow(FILTER_BY_NAME_COMBO_COMPONENT); if ( combo != null && combo.isDisabled() != disabled ) { - filterByNamePosition = disabled? -1 : (Integer) combo.getSelectedItemApi().getValue(); + filterByNamePosition = disabled? -1 : (Integer) combo.getSelectedItem().getValue(); combo.setDisabled(disabled); } } @@ -560,15 +560,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { nameFilterListener.addListener(iFilterChangedListener); } + /** + * It should be public! + */ public void changeChartVisibility(boolean visible) { visibleChart = visible; - - chartVisibilityListeners.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IChartVisibilityChangedListener listener) { - listener.chartVisibilityChanged(visibleChart); - } - }); + chartVisibilityListeners.fireEvent(listener -> listener.chartVisibilityChanged(visibleChart)); } public boolean isVisibleChart() { @@ -588,11 +585,9 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } public Combobox getPaginationFilterCombobox() { - if ( paginationType == PaginationType.EXTERNAL_PAGINATION ) { - return (Combobox) getFellow("filterByNameCombo"); - } - - return null; + return paginationType == PaginationType.EXTERNAL_PAGINATION + ? (Combobox) getFellow(FILTER_BY_NAME_COMBO_COMPONENT) + : null; } public enum PaginationType { @@ -600,14 +595,16 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { * Sets the widget to take care of the pagination of all the LoadTimeLine objects received. */ INTERNAL_PAGINATION, + /** * The widget will only show the combo box but its content has to be configured externally. - * The pagination has to be managed externally too: the widget will show all the LoadTimeLine - * objects received. + * The pagination has to be managed externally too: the widget will show all the LoadTimeLine objects received. */ EXTERNAL_PAGINATION, + /** - * Disables pagination. Shows all the LoadTimeLine objects received. + * Disables pagination. + * Shows all the LoadTimeLine objects received. */ NONE } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java b/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java index 80786f69c..d70276bad 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java @@ -34,11 +34,12 @@ import java.util.concurrent.TimeUnit; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.Validate; -import org.zkoss.web.servlet.http.HttpServlet; + /** * Servlet that allows to register custom responses. It must be declared at diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java index 9a65d8f95..e21b5ce75 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java @@ -21,7 +21,7 @@ package org.zkoss.ganttz.timetracker; -import org.zkoss.zul.api.Column; +import org.zkoss.zul.Column; public interface IConvertibleToColumn { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java index 83bd4be11..af7c1d396 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java @@ -34,15 +34,20 @@ import org.zkoss.zul.RowRenderer; public class OnColumnsRowRenderer implements RowRenderer { + private final List columns; + + private final ICellForDetailItemRenderer cellRenderer; + + private Class type; + public static OnColumnsRowRenderer create(ICellForDetailItemRenderer cellRenderer, Collection columns) { return create(inferGenericType(cellRenderer), cellRenderer, columns); } - public static OnColumnsRowRenderer create(Class type, - ICellForDetailItemRenderer cellRenderer, - Collection columns) { + public static OnColumnsRowRenderer create( + Class type, ICellForDetailItemRenderer cellRenderer, Collection columns) { return new OnColumnsRowRenderer<>(type, cellRenderer, columns); } @@ -95,19 +100,12 @@ public class OnColumnsRowRenderer implements RowRenderer { private static void informCannotBeInferred(ICellForDetailItemRenderer renderer) { throw new IllegalArgumentException( - "the generic type cannot be inferred " + - "if actual type parameters are not declared " + - "or implements the raw interface: " + - renderer.getClass().getName()); + "the generic type cannot be inferred if actual type parameters are not declared " + + "or implements the raw interface: " + renderer.getClass().getName()); } - private final List columns; - private final ICellForDetailItemRenderer cellRenderer; - private Class type; + private OnColumnsRowRenderer(Class type, ICellForDetailItemRenderer cellRenderer, Collection columns) { - private OnColumnsRowRenderer(Class type, - ICellForDetailItemRenderer cellRenderer, - Collection columns) { Validate.notNull(type); Validate.notNull(columns); Validate.notNull(cellRenderer); @@ -119,15 +117,16 @@ public class OnColumnsRowRenderer implements RowRenderer { } @Override - public void render(Row row, Object data) { - if ( !type.isInstance(data) ) { - throw new IllegalArgumentException(data + " is not instance of " + type); + public void render(Row row, Object o, int index) throws Exception { + if ( !type.isInstance(o) ) { + throw new IllegalArgumentException(o + " is not instance of " + type); } for (C item : columns) { - Component child = cellRenderer.cellFor(item, type.cast(data)); + Component child = cellRenderer.cellFor(item, type.cast(o)); child.setParent(row); } } + } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java index ecd6a88a4..bf1d646b2 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java @@ -41,8 +41,9 @@ public class TimeTrackedTable extends HtmlMacroComponent { private transient IZoomLevelChangedListener zoomListener; public TimeTrackedTable(Callable> dataSource, - ICellForDetailItemRenderer cellRenderer, - TimeTracker timeTracker) { + ICellForDetailItemRenderer cellRenderer, + TimeTracker timeTracker) { + this.data = dataSource; this.cellRenderer = cellRenderer; this.timeTracker = timeTracker; @@ -56,8 +57,8 @@ public class TimeTrackedTable extends HtmlMacroComponent { this.timeTracker.addZoomListener(zoomListener); } - public ListModel getTableModel() { - return new ListModelList(getData()); + public ListModel getTableModel() { + return new ListModelList<>(getData()); } private List getData() { @@ -69,8 +70,7 @@ public class TimeTrackedTable extends HtmlMacroComponent { } public RowRenderer getRowRenderer() { - return OnColumnsRowRenderer.create(cellRenderer, timeTracker - .getDetailsSecondLevel()); + return OnColumnsRowRenderer.create(cellRenderer, timeTracker.getDetailsSecondLevel()); } public Collection getDetailsSecondLevel() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java index 73d5ef594..4941c3390 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java @@ -33,7 +33,7 @@ import org.zkoss.zul.Columns; import org.zkoss.zul.Grid; import org.zkoss.zul.ListModel; import org.zkoss.zul.ListModelList; -import org.zkoss.zul.api.Column; +import org.zkoss.zul.Column; public class TimeTrackedTableWithLeftPane { @@ -48,10 +48,13 @@ public class TimeTrackedTableWithLeftPane { ICellForDetailItemRenderer leftPaneCellRenderer, ICellForDetailItemRenderer cellRendererForTimeTracker, TimeTracker timeTracker) { + this.dataSource = dataSource; - timeTrackedTable = new TimeTrackedTable( + + timeTrackedTable = new TimeTrackedTable<>( dataForTimeTracker(dataSource), cellRendererForTimeTracker, timeTracker); + timeTrackedTable.setSclass("inner-timetracked-table"); leftPane = new Grid(); zoomLevelListener = new IZoomLevelChangedListener() { @@ -60,28 +63,32 @@ public class TimeTrackedTableWithLeftPane { loadModelForLeftPane(); } }; + timeTracker.addZoomListener(zoomLevelListener); + leftPane.appendChild(createColumns(leftPaneColumns)); - leftPane.setRowRenderer(OnColumnsRowRenderer.create( - leftPaneCellRenderer, leftPaneColumns)); + leftPane.setRowRenderer(OnColumnsRowRenderer.create(leftPaneCellRenderer, leftPaneColumns)); + loadModelForLeftPane(); } - private static Columns createColumns( - Collection convertibleToColumns) { + private static Columns createColumns(Collection convertibleToColumns) { Columns result = new Columns(); + for (Column column : toColumns(convertibleToColumns)) { result.appendChild(column); } + return result; } - private static List toColumns( - Collection convertibleToColumns) { - List columns = new ArrayList(); + private static List toColumns(Collection convertibleToColumns) { + List columns = new ArrayList<>(); + for (IConvertibleToColumn c : convertibleToColumns) { columns.add(c.toColumn()); } + return columns; } @@ -89,12 +96,13 @@ public class TimeTrackedTableWithLeftPane { leftPane.setModel(createModelForLeftPane()); } - private ListModel createModelForLeftPane() { - return new ListModelList(retrieveLeftPaneList()); + private ListModel createModelForLeftPane() { + return new ListModelList<>(retrieveLeftPaneList()); } private List retrieveLeftPaneList() { PairOfLists pair = loadPairOfListsFromCallable(); + return pair.getFirst(); } @@ -106,8 +114,7 @@ public class TimeTrackedTableWithLeftPane { } } - private Callable> dataForTimeTracker( - final Callable> dataSource) { + private Callable> dataForTimeTracker(final Callable> dataSource) { return new Callable>() { @Override @@ -120,10 +127,11 @@ public class TimeTrackedTableWithLeftPane { private boolean afterComposeCalled = false; public TimeTrackedTable getTimeTrackedTable() { - if (!afterComposeCalled) { + if ( !afterComposeCalled ) { timeTrackedTable.afterCompose(); afterComposeCalled = true; } + return timeTrackedTable; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java index e0a5d74a5..a167c4135 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java @@ -23,8 +23,6 @@ package org.zkoss.ganttz.timetracker; import static org.zkoss.ganttz.i18n.I18nHelper._; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.Date; @@ -43,7 +41,6 @@ import org.zkoss.ganttz.util.Interval; import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.WeakReferencedListeners; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.ui.Component; public class TimeTracker { @@ -82,9 +79,7 @@ public class TimeTracker { private IDetailItemFilter filter = null; - public IDetailItemFilter getFilter() { - return filter; - } + private Interval realIntervalCached; public TimeTracker(Interval interval, ZoomLevel zoomLevel, Component parent) { this(interval, zoomLevel, SeveralModificators.empty(), SeveralModificators.empty(), parent); @@ -122,6 +117,10 @@ public class TimeTracker { detailLevel = zoomLevel; } + public IDetailItemFilter getFilter() { + return filter; + } + public void setFilter(IDetailItemFilter filter) { this.filter = filter; datesMapper = null; @@ -144,11 +143,7 @@ public class TimeTracker { } private Collection filterFirstLevel(Collection firstLevelDetails) { - if ( filter == null ) { - return firstLevelDetails; - } - - return filter.selectsFirstLevel(firstLevelDetails); + return filter == null ? firstLevelDetails : filter.selectsFirstLevel(firstLevelDetails); } public Collection getDetailsSecondLevel() { @@ -160,15 +155,9 @@ public class TimeTracker { } private Collection filterSecondLevel(Collection secondLevelDetails) { - if ( filter == null ) { - return secondLevelDetails; - } - - return filter.selectsSecondLevel(secondLevelDetails); + return filter == null ? secondLevelDetails : filter.selectsSecondLevel(secondLevelDetails); } - private Interval realIntervalCached; - public Interval getRealInterval() { if ( realIntervalCached == null ) { realIntervalCached = getTimeTrackerState().getRealIntervalFor(interval); @@ -182,7 +171,8 @@ public class TimeTracker { } private void fireZoomChanged() { - zoomListeners.fireEvent(new IListenerNotification() { + /* Do not replace it with lambda */ + zoomListeners.fireEvent(new WeakReferencedListeners.IListenerNotification() { @Override public void doNotify(IZoomLevelChangedListener listener) { listener.zoomLevelChanged(detailLevel); @@ -257,13 +247,7 @@ public class TimeTracker { } public void trackPosition(final Task task) { - task.addFundamentalPropertiesChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - updateIntervalIfNeeded(task); - } - }); - + task.addFundamentalPropertiesChangeListener(evt -> updateIntervalIfNeeded(task)); updateIntervalIfNeeded(task); } @@ -319,16 +303,14 @@ public class TimeTracker { } private LocalDate endPlusOneMonth(Task task) { - Date taskEnd = max(task.getEndDate().toDayRoundedDate(), task.getDeadline()); - - return new LocalDate(taskEnd).plusMonths(1); + return new LocalDate(max(task.getEndDate().toDayRoundedDate(), task.getDeadline())).plusMonths(1); } private LocalDate startMinusTwoWeeks(Task task) { - // the deadline could be before the start + // The deadline could be before the start Date start = min(task.getBeginDate().toDayRoundedDate(), task.getDeadline()); - // the last consolidated value could be before the start + // The last consolidated value could be before the start if ( task.getConsolidatedline() != null ) { start = min(start, task.getConsolidatedline().toDayRoundedDate()); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java index b27141c43..9ae3d822d 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java @@ -25,7 +25,6 @@ import java.util.Collection; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.zkoss.ganttz.IDatesMapper; import org.zkoss.ganttz.timetracker.zoom.DetailItem; import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; @@ -35,36 +34,35 @@ import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; /** + * Works with time header of some pages. + * * @author Javier Moran Rua */ public abstract class TimeTrackerComponent extends HtmlMacroComponent { private final TimeTracker timeTracker; - private IZoomLevelChangedListener zoomListener; + private final String secondLevelZul; + private String timeTrackerElementId; + private int scrollLeft; public TimeTrackerComponent(TimeTracker timeTracker) { - this(timeTracker, - "~./ganttz/zul/timetracker/timetrackersecondlevel.zul", - "timetracker"); + this(timeTracker, "~./ganttz/zul/timetracker/timetrackersecondlevel.zul", "timetracker"); } - protected TimeTrackerComponent(TimeTracker timeTracker, - String secondLevelZul, String timetrackerId) { + TimeTrackerComponent(TimeTracker timeTracker, String secondLevelZul, String timetrackerId) { this.secondLevelZul = secondLevelZul; this.timeTracker = timeTracker; - zoomListener = new IZoomLevelChangedListener() { - @Override - public void zoomLevelChanged(ZoomLevel detailLevel) { - if (isInPage()) { - recreate(); - changeDetailLevel(getDaysFor(scrollLeft)); - } + IZoomLevelChangedListener zoomListener = detailLevel -> { + if ( isInPage() ) { + recreate(); + changeDetailLevel(getDaysFor(scrollLeft)); } }; + this.timeTracker.addZoomListener(zoomListener); timeTrackerElementId = timetrackerId; } @@ -81,22 +79,24 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent { return timeTrackerElementId; } - /* - * fsanjurjo: I'm temporary changing the name of this method - * (from afterCompose to compose) to get it called after calling recreate(). - * To understand why, please read this: http://www.zkoss.org/forum/listComment/14905 - * Also renamed the call to its parent. - * */ + /** + * fsanjurjo: + * I'm temporary changing the name of this method (from afterCompose to compose) + * to get it called after calling recreate(). + * + * To understand why, please read this: http://www.zkoss.org/forum/listComment/14905 + * Also renamed the call to its parent. + */ @Override public void compose() { super.compose(); + Component fellow = getFellow("firstleveldetails"); addSecondLevels(fellow.getParent()); } private void addSecondLevels(Component parent) { - Executions.getCurrent().createComponents(secondLevelZul, parent, - getAttributes()); + Executions.getCurrent().createComponents(secondLevelZul, parent, getAttributes()); } public ZoomLevel getZoomLevel() { @@ -146,9 +146,9 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent { } public int getDiffDays(LocalDate previousStart) { - // get the current data - IDatesMapper mapper = getTimeTracker().getMapper(); + // Get the current data LocalDate start = getTimeTracker().getRealInterval().getStart(); + return Days.daysBetween(start, previousStart).getDays(); } @@ -166,7 +166,7 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent { } public String getWidgetClass(){ - return getDefinition().getDefaultWidgetClass(); + return getDefinition().getDefaultWidgetClass(this); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java index 4f91c480a..fc581afd5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java @@ -21,16 +21,14 @@ package org.zkoss.ganttz.timetracker; /** - * A {@link TimeTrackerComponent} that doesn't show columns as watermark + * A {@link TimeTrackerComponent} that doesn't show columns as watermark. + * * @author Óscar González Fernández */ public class TimeTrackerComponentWithoutColumns extends TimeTrackerComponent { - public TimeTrackerComponentWithoutColumns(TimeTracker timeTracker, - String timeTrackerId) { - super(timeTracker, - "~./ganttz/zul/timetracker/secondlevelwithoutwatermark.zul", - timeTrackerId); + public TimeTrackerComponentWithoutColumns(TimeTracker timeTracker, String timeTrackerId) { + super(timeTracker, "~./ganttz/zul/timetracker/secondlevelwithoutwatermark.zul", timeTrackerId); } @Override @@ -38,14 +36,8 @@ public class TimeTrackerComponentWithoutColumns extends TimeTrackerComponent { } @Override - protected void moveCurrentPositionScroll() { - // TODO Auto-generated method stub - - } + protected void moveCurrentPositionScroll() {} @Override - protected void updateCurrentDayScroll() { - // TODO Auto-generated method stub - - } + protected void updateCurrentDayScroll() {} } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java index 4d8f65299..e09c4541c 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java @@ -21,57 +21,51 @@ package org.zkoss.ganttz.timetracker.zoom; -import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.ReadablePeriod; /** - * Zoom level for weeks in the first level and days in the second level + * Zoom level for weeks in the first level and days in the second level. + * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro */ -public class DetailFiveTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailFiveTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { private static final int NUMBER_OF_DAYS_MINIMUM = 50; - public static final int FIRST_LEVEL_SIZE = 210; - public static final int SECOND_LEVEL_SIZE = 30; - DetailFiveTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + private static final int FIRST_LEVEL_SIZE = 210; + + private static final int SECOND_LEVEL_SIZE = 30; + + DetailFiveTimeTrackerState( + IDetailItemModificator firstLevelModificator, IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); } + @Override public final double daysPerPixel() { - return ((double) 1 / SECOND_LEVEL_SIZE); + return (double) 1 / SECOND_LEVEL_SIZE; } @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_SIZE, dateTime - .getWeekOfWeekyear() - + dateTime.toString(", MMM YYYY"), dateTime, dateTime - .plusDays(7)); - } - }; + return dateTime -> new DetailItem( + FIRST_LEVEL_SIZE, + dateTime.getWeekOfWeekyear() + dateTime.toString(", MMM YYYY"), + dateTime, + dateTime.plusDays(7)); } @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_SIZE, dateTime - .getDayOfMonth() - + "", dateTime, dateTime.plusDays(1)); - } - }; + return dateTime -> new DetailItem( + SECOND_LEVEL_SIZE, + Integer.toString(dateTime.getDayOfMonth()), + dateTime, + dateTime.plusDays(1)); } @Override @@ -87,11 +81,12 @@ public class DetailFiveTimeTrackerState extends @Override protected LocalDate round(LocalDate date, boolean down) { int dayOfWeek = date.getDayOfWeek(); + if (dayOfWeek == 1) { return date; } - return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1) - .plusWeeks(1); + + return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1).plusWeeks(1); } @Override diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java index a68abe444..8dc667cde 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java @@ -31,7 +31,8 @@ import org.joda.time.LocalDate; import org.joda.time.Months; /** - * Zoom level for months and years and weeks in the second level + * Zoom level for months and years and weeks in the second level. + * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro */ @@ -39,53 +40,39 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { private static final int NUMBER_OF_WEEKS_MINIMUM = 40; - DetailFourTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + private static final int SECOND_LEVEL_SIZE = 56; + + DetailFourTimeTrackerState( + IDetailItemModificator firstLevelModificator, IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); } - private static final int SECOND_LEVEL_SIZE = 56; - public final double pixelPerDay() { - return (SECOND_LEVEL_SIZE / (double) 7); + return SECOND_LEVEL_SIZE / (double) 7; } public final double daysPerPixel() { - return ((double) 7 / SECOND_LEVEL_SIZE); + return (double) 7 / SECOND_LEVEL_SIZE; } - - private IDetailItemCreator firstLevelCreator; - @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - firstLevelCreator = new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(getSizeMonth(dateTime), dateTime - .toString("MMMM,YYYY"), dateTime, dateTime - .plusMonths(1)); - } - }; - return firstLevelCreator; + return dateTime -> new DetailItem( + getSizeMonth(dateTime), dateTime.toString("MMMM,YYYY"), dateTime, dateTime.plusMonths(1)); } @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { + return dateTime -> { + int daysUntilFirstDayNextWeek = getDaysUntilFirstDayNextWeek(dateTime.toLocalDate()); + int sizeWeek = BigDecimal.valueOf(pixelPerDay() * daysUntilFirstDayNextWeek).intValue(); - @Override - public DetailItem create(DateTime dateTime) { - int daysUntilFirstDayNextWeek = getDaysUntilFirstDayNextWeek(dateTime - .toLocalDate()); - int sizeWeek = new BigDecimal(pixelPerDay() - * daysUntilFirstDayNextWeek).intValue(); - - return new DetailItem(sizeWeek, dateTime.getWeekOfWeekyear() - + "", dateTime, - dateTime.plusDays(daysUntilFirstDayNextWeek)); - } + return new DetailItem( + sizeWeek, + Integer.toString(dateTime.getWeekOfWeekyear()), + dateTime, + dateTime.plusDays(daysUntilFirstDayNextWeek)); }; } @@ -94,8 +81,8 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { if (date.getDayOfMonth() == 1) { return date; } - return down ? date.withDayOfMonth(1) : date.plusMonths(1) - .withDayOfMonth(1); + + return down ? date.withDayOfMonth(1) : date.plusMonths(1).withDayOfMonth(1); } @Override @@ -114,17 +101,18 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { } private int getSizeMonth(DateTime dateTime) { - Calendar cal = new GregorianCalendar(dateTime.getYear(), dateTime - .getMonthOfYear() - 1, dateTime.getDayOfMonth()); + Calendar cal = + new GregorianCalendar(dateTime.getYear(), dateTime.getMonthOfYear() - 1, dateTime.getDayOfMonth()); + // Get the number of days in that month int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH); - return new BigDecimal(pixelPerDay() * days).intValue(); + + return BigDecimal.valueOf(pixelPerDay() * days).intValue(); } @Override protected Iterator getPeriodsFirstLevelGenerator(LocalDate start) { return new LazyGenerator(start) { - @Override protected LocalDate next(LocalDate last) { return last.plus(Months.ONE); @@ -135,14 +123,9 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { @Override protected Iterator getPeriodsSecondLevelGenerator(LocalDate start) { return new LazyGenerator(start) { - @Override protected LocalDate next(LocalDate last) { - if (last.getDayOfWeek() != 1) { - return last.plusDays(getDaysUntilFirstDayNextWeek(last)); - } else { - return last.plusWeeks(1); - } + return last.getDayOfWeek() != 1 ? last.plusDays(getDaysUntilFirstDayNextWeek(last)) : last.plusWeeks(1); } }; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java index 3b470d396..cf2676879 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java @@ -25,42 +25,40 @@ import org.joda.time.DateTime; import org.joda.time.Days; /** - * One of each of the subintervals a time line is divided into + * One of each of the subintervals a time line is divided into. + * * @author Francisco Javier Moran Rúa * @author Lorenzo Tilve Álvaro */ public final class DetailItem { private int size; + private String name; private boolean even; + private boolean bankHoliday; private String bankHolidayWeek; - public String getBankHolidayWeek() { - return bankHolidayWeek; - } - - public void setBankHolidayWeek(String bankHolidayWeek) { - this.bankHolidayWeek = bankHolidayWeek; - } - private boolean currentPeriod; + private int currentDayOffset; private boolean projectStart = false; + private int projectStartOffset = 0; private boolean deadlinePeriod; + private int deadlineOffset; private DateTime startDate; + private DateTime endDate; - public DetailItem(int size, String name, DateTime startDate, - DateTime endDate) { + public DetailItem(int size, String name, DateTime startDate, DateTime endDate) { this(size, name, false); this.startDate = startDate; this.endDate = endDate; @@ -88,32 +86,41 @@ public final class DetailItem { this.currentDayOffset = currentdayoffset; } - public DetailItem(int size, String name, int currentdayoffset, - int deadlineoffset) { + public DetailItem(int size, String name, int currentdayoffset, int deadlineoffset) { this(size, name, currentdayoffset); this.deadlinePeriod = true; this.deadlineOffset = deadlineoffset; } + public String getBankHolidayWeek() { + return bankHolidayWeek; + } + + public void setBankHolidayWeek(String bankHolidayWeek) { + this.bankHolidayWeek = bankHolidayWeek; + } + public void markCurrentDay() { if (this.startDate.isBeforeNow() && this.endDate.isAfterNow()) { - int offsetInPx = Math - .round(((((float) Days.daysBetween(this.startDate, - new DateTime()).getDays()) + (float) 0.5) / ((float) Days - .daysBetween(this.startDate, this.endDate).getDays())) - * this.size); + + int offsetInPx = Math.round( + ( (((float) Days.daysBetween(this.startDate, new DateTime()).getDays()) + (float) 0.5) / + ((float) Days.daysBetween(this.startDate, this.endDate).getDays()) ) + * this.size ); + // 1px per column side, 1px for right border and 1px own bg-width this.markCurrentDay(Math.min(this.size - 4, offsetInPx)); } } public void markProjectStart(DateTime projectStart) { - if (!this.startDate.isAfter(projectStart) - && projectStart.isBefore(endDate)) { - int offsetInPx = Math.round((((float) Days.daysBetween( - this.startDate, projectStart).getDays()) / ((float) Days - .daysBetween(this.startDate, this.endDate).getDays())) - * this.size); + if (!this.startDate.isAfter(projectStart) && projectStart.isBefore(endDate)) { + + int offsetInPx = Math.round( + ( ((float) Days.daysBetween(this.startDate, projectStart).getDays()) / + ((float) Days.daysBetween(this.startDate, this.endDate).getDays()) ) + * this.size); + this.markprojectStart(offsetInPx); } } @@ -121,10 +128,12 @@ public final class DetailItem { public void markDeadlineDay(DateTime maxdeadline) { DateTime deadline = maxdeadline.plusDays(1); if (!this.startDate.isAfter(deadline) && deadline.isBefore(endDate)) { - int offsetInPx = Math.round((((float) Days.daysBetween( - this.startDate, deadline).getDays()) / ((float) Days - .daysBetween(this.startDate, this.endDate).getDays())) - * this.size); + + int offsetInPx = Math.round( + ( ((float) Days.daysBetween(this.startDate, deadline).getDays()) / + ((float) Days.daysBetween(this.startDate, this.endDate).getDays()) ) + * this.size); + // 1px per column side, 1px for right border and 1px own bg-width this.markDeadlineDay(Math.min(this.size - 4, offsetInPx)); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java index 24aa02adc..e03033550 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java @@ -29,24 +29,26 @@ import org.joda.time.Years; /** - * Zoom level with years in the first level and semesters in the second level + * Zoom level with years in the first level and semesters in the second level. + * * @author Francisco Javier Moran Rúa * @author Lorenzo Tilve Álvaro */ -public class DetailOneTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailOneTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { - public static final Period MINIMUN_PERIOD = PeriodType.YEARS.amount(6); + static final Period MINIMUM_PERIOD = PeriodType.YEARS.amount(6); private static final int FIRST_LEVEL_ITEM_SIZE = 200; + private static final int SECOND_LEVEL_ITEM_SIZE = 100; public final double daysPerPixel() { - return ((double) 365 / FIRST_LEVEL_ITEM_SIZE); + return (double) 365 / FIRST_LEVEL_ITEM_SIZE; } - DetailOneTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + DetailOneTimeTrackerState( + IDetailItemModificator firstLevelModificator, IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); } @@ -62,15 +64,11 @@ public class DetailOneTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime start) { - int year = start.getYear(); - DateTime end = new LocalDate(year + 1, 1, 1) - .toDateTimeAtStartOfDay(); - return new DetailItem(FIRST_LEVEL_ITEM_SIZE, start.getYear() - + "", start, end); - } + return start -> { + int year = start.getYear(); + DateTime end = new LocalDate(year + 1, 1, 1).toDateTimeAtStartOfDay(); + + return new DetailItem(FIRST_LEVEL_ITEM_SIZE, Integer.toString(start.getYear()), start, end); }; } @@ -81,15 +79,8 @@ public class DetailOneTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_ITEM_SIZE, - dateTime.getMonthOfYear() == 1 ? "H1" : "H2", dateTime, - dateTime.plusMonths(6)); - } - }; + return dateTime -> new DetailItem( + SECOND_LEVEL_ITEM_SIZE, dateTime.getMonthOfYear() == 1 ? "H1" : "H2", dateTime, dateTime.plusMonths(6)); } @Override @@ -103,12 +94,12 @@ public class DetailOneTimeTrackerState extends } public static LocalDate doYearRound(LocalDate date, boolean down) { - return new LocalDate(date.getYear() + (down?0:1), 1, 1); + return new LocalDate(date.getYear() + (down ? 0 : 1), 1, 1); } @Override protected Period getMinimumPeriod() { - return MINIMUN_PERIOD; + return MINIMUM_PERIOD; } -} +} \ No newline at end of file diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java deleted file mode 100644 index 71b8b1d63..000000000 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of LibrePlan - * - * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e - * Desenvolvemento Tecnolóxico de Galicia - * Copyright (C) 2010-2011 Igalia, S.L. - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package org.zkoss.ganttz.timetracker.zoom; - -import org.joda.time.DateTime; -import org.joda.time.Days; -import org.joda.time.LocalDate; -import org.joda.time.ReadablePeriod; - -/** - * Zoom level for weeks in the first level and days in the second level - * @author Óscar González Fernández - * @author Lorenzo Tilve Álvaro - */ -public class DetailSixTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { - - private static final int NUMBER_OF_DAYS_MINIMUM = 50; - public static final int FIRST_LEVEL_SIZE = 672; - public static final int SECOND_LEVEL_SIZE = 96; - - DetailSixTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); - } - - public final double daysPerPixel() { - return ((double) 1 / SECOND_LEVEL_SIZE); - } - - @Override - protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_SIZE, dateTime - .getWeekOfWeekyear() - + dateTime.toString(", MMM YYYY"), dateTime, dateTime - .plusDays(7)); - } - }; - } - - @Override - protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_SIZE, dateTime - .getDayOfMonth() - + "", dateTime, dateTime.plusDays(1)); - } - }; - } - - @Override - protected ReadablePeriod getPeriodFirstLevel() { - return Days.days(7); - } - - @Override - protected ReadablePeriod getPeriodSecondLevel() { - return Days.days(1); - } - - @Override - protected LocalDate round(LocalDate date, boolean down) { - int dayOfWeek = date.getDayOfWeek(); - if (dayOfWeek == 1) { - return date; - } - return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1) - .plusWeeks(1); - } - - @Override - protected Period getMinimumPeriod() { - return PeriodType.DAYS.amount(NUMBER_OF_DAYS_MINIMUM); - } - - @Override - protected ZoomLevel getZoomLevel() { - return ZoomLevel.DETAIL_FIVE; - } - - @Override - public int getSecondLevelSize() { - return SECOND_LEVEL_SIZE; - } - -} \ No newline at end of file diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java index 086b73a9f..720d7a8b4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java @@ -28,25 +28,27 @@ import org.joda.time.ReadablePeriod; import org.zkoss.util.Locales; /** - * Zoom level with semesters in the first level and months in the second level + * Zoom level with semesters in the first level and months in the second level. + * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro */ -public class DetailThreeTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailThreeTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { private static final int NUMBER_OF_MONTHS_MINIMUM = 30; - DetailThreeTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + private static final int FIRST_LEVEL_SIZE = 300; + + protected static final int SECOND_LEVEL_SIZE = 50; + + DetailThreeTimeTrackerState( + IDetailItemModificator firstLevelModificator, IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); } - private static final int FIRST_LEVEL_SIZE = 300; - protected static final int SECOND_LEVEL_SIZE = 50; - public final double daysPerPixel() { - return ((double) 182.5 / FIRST_LEVEL_SIZE); + return 182.5 / FIRST_LEVEL_SIZE; } @Override @@ -61,31 +63,22 @@ public class DetailThreeTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_SIZE, - getMonthString(dateTime), - dateTime, dateTime.plusMonths(1)); - } - }; + return dateTime -> new DetailItem( + SECOND_LEVEL_SIZE, getMonthString(dateTime), dateTime, dateTime.plusMonths(1)); } @Override protected LocalDate round(LocalDate date, boolean down) { - if (date.getMonthOfYear() == 1 && date.getDayOfMonth() == 1) { - return date; - } - if (date.getMonthOfYear() == 7 && date.getDayOfMonth() == 1) { + if ( (date.getMonthOfYear() == 1 || date.getMonthOfYear() == 7) && date.getDayOfMonth() == 1) { return date; } + date = date.withDayOfMonth(1); + if (date.getMonthOfYear() < 7) { return down ? date.withMonthOfYear(1) : date.withMonthOfYear(7); } else { - return down ? date.withMonthOfYear(7) : date.plusYears(1) - .withMonthOfYear(1); + return down ? date.withMonthOfYear(7) : date.plusYears(1).withMonthOfYear(1); } } @@ -94,20 +87,13 @@ public class DetailThreeTimeTrackerState extends } private String getYearWithSemesterString(DateTime dateTime) { - return dateTime.getYear() + "," - + (dateTime.getMonthOfYear() < 6 ? "H1" : "H2"); + return dateTime.getYear() + "," + (dateTime.getMonthOfYear() < 6 ? "H1" : "H2"); } @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_SIZE, - getYearWithSemesterString(dateTime), dateTime, dateTime - .plusMonths(6)); - } - }; + return dateTime -> new DetailItem( + FIRST_LEVEL_SIZE, getYearWithSemesterString(dateTime), dateTime, dateTime.plusMonths(6)); } @Override diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java index 1c9e57d3b..fba26ac80 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java @@ -21,38 +21,33 @@ package org.zkoss.ganttz.timetracker.zoom; -import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.Months; import org.joda.time.ReadablePeriod; import org.joda.time.Years; /** - * Zoom level with years in the first level and quarters in the second level + * Zoom level with years in the first level and quarters in the second level. + * * @author Francisco Javier Moran Rúa * @author Lorenzo Tilve Álvaro */ -public class DetailTwoTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailTwoTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { private static final int FIRST_LEVEL_ITEM_SIZE = 400; + private static final int SECOND_LEVEL_ITEM_SIZE = 100; - protected DetailTwoTimeTrackerState( - IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + protected DetailTwoTimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + super(firstLevelModificator, secondLevelModificator); } @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_ITEM_SIZE, dateTime.getYear() - + "", dateTime, dateTime); - } - }; + return dateTime -> + new DetailItem(FIRST_LEVEL_ITEM_SIZE, Integer.toString(dateTime.getYear()), dateTime, dateTime); } @Override @@ -62,14 +57,11 @@ public class DetailTwoTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime dateTime) { - int quarterNumber = dateTime.getMonthOfYear() / 3 + 1; - String quarterCaption = "Q" + quarterNumber; - return new DetailItem(SECOND_LEVEL_ITEM_SIZE, quarterCaption, - dateTime, dateTime.plusMonths(3)); - } + return dateTime -> { + int quarterNumber = dateTime.getMonthOfYear() / 3 + 1; + String quarterCaption = "Q" + quarterNumber; + + return new DetailItem(SECOND_LEVEL_ITEM_SIZE, quarterCaption, dateTime, dateTime.plusMonths(3)); }; } @@ -85,12 +77,12 @@ public class DetailTwoTimeTrackerState extends @Override protected Period getMinimumPeriod() { - return DetailOneTimeTrackerState.MINIMUN_PERIOD; + return DetailOneTimeTrackerState.MINIMUM_PERIOD; } @Override public double daysPerPixel() { - return ((double) 365 / FIRST_LEVEL_ITEM_SIZE); + return (double) 365 / FIRST_LEVEL_ITEM_SIZE; } @Override diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java index 38685af02..680d50c54 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java @@ -24,6 +24,6 @@ package org.zkoss.ganttz.timetracker.zoom; public interface IZoomLevelChangedListener { - public void zoomLevelChanged(ZoomLevel detailLevel); + void zoomLevelChanged(ZoomLevel detailLevel); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java index 42ed2f9b1..24bafa2c2 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java @@ -30,12 +30,13 @@ import org.apache.commons.lang3.Validate; /** * @author Óscar González Fernández - * */ public class SeveralModificators implements IDetailItemModificator { + private final List modificators; + public static IDetailItemModificator empty() { - return new SeveralModificators(Collections. emptyList()); + return new SeveralModificators(Collections.emptyList()); } public static IDetailItemModificator create(IDetailItemModificator... modificators) { @@ -46,8 +47,6 @@ public class SeveralModificators implements IDetailItemModificator { return new SeveralModificators(modificators); } - private final List modificators; - private SeveralModificators(Collection modificators) { Validate.noNullElements(modificators); this.modificators = new ArrayList<>(modificators); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java index 7a5fb8765..33c7851c9 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java @@ -47,6 +47,24 @@ import org.zkoss.ganttz.util.Interval; */ public abstract class TimeTrackerState { + protected static final long MILLSECONDS_IN_DAY = 1000 * 60 * 60 * 24L; + + /** + * Pending to calculate interval dinamically + */ + protected static final int NUMBER_OF_ITEMS_MINIMUM = 4; + + private final IDetailItemModificator firstLevelModificator; + + private final IDetailItemModificator secondLevelModificator; + + protected TimeTrackerState(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { + + this.firstLevelModificator = firstLevelModificator; + this.secondLevelModificator = secondLevelModificator; + } + public static Date year(int year) { Calendar calendar = Calendar.getInstance(); calendar.clear(); @@ -54,7 +72,7 @@ public abstract class TimeTrackerState { return calendar.getTime(); } - public static abstract class LazyGenerator implements Iterator { + public abstract static class LazyGenerator implements Iterator { private T current; @@ -69,7 +87,9 @@ public abstract class TimeTrackerState { @Override public T next() { - return this.current = next(this.current); + this.current = next(this.current); + + return this.current; } protected abstract T next(T last); @@ -80,27 +100,15 @@ public abstract class TimeTrackerState { } } - protected static final long MILLSECONDS_IN_DAY = 1000 * 60 * 60 * 24; - - // Pending to calculate interval dinamically - protected static final int NUMBER_OF_ITEMS_MINIMUM = 4; - - private final IDetailItemModificator firstLevelModificator; - - private final IDetailItemModificator secondLevelModificator; - - protected TimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - this.firstLevelModificator = firstLevelModificator; - this.secondLevelModificator = secondLevelModificator; - } - - // When applied after setting current day, removes extra data as current day - // or bank holidays, and must proccess the array twice. May be refactorized - private static List markEvens( - Collection items) { + /** + * When applied after setting current day, removes extra data as current day or bank holidays, + * and must process the array twice. + * + * May be refactorized. + */ + private static List markEvens(Collection items) { boolean even = false; - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); for (DetailItem detailItem : items) { detailItem.setEven(even); @@ -120,26 +128,29 @@ public abstract class TimeTrackerState { public Collection getSecondLevelDetails(Interval interval) { if (getZoomLevel() == ZoomLevel.DETAIL_FIVE) { - // Evens are not highlighted in day view + // Events are not highlighted in day view return applyConfiguredModifications( secondLevelModificator, - createDetailsForSecondLevel(interval), getZoomLevel()); + createDetailsForSecondLevel(interval), + getZoomLevel()); } else { return markEvens(applyConfiguredModifications( secondLevelModificator, - createDetailsForSecondLevel(interval), getZoomLevel())); + createDetailsForSecondLevel(interval), + getZoomLevel())); } } public Collection getFirstLevelDetails(Interval interval) { - return applyConfiguredModifications(firstLevelModificator, - createDetailsForFirstLevel(interval), getZoomLevel()); + return applyConfiguredModifications( + firstLevelModificator, createDetailsForFirstLevel(interval), getZoomLevel()); } - private static List applyConfiguredModifications( - IDetailItemModificator modificator, - Collection detailsItems, ZoomLevel zoomlevel) { - List result = new ArrayList(detailsItems.size()); + private static List applyConfiguredModifications(IDetailItemModificator modificator, + Collection detailsItems, + ZoomLevel zoomlevel) { + + List result = new ArrayList<>(detailsItems.size()); for (DetailItem each : detailsItems) { result.add(modificator.applyModificationsTo(each, zoomlevel)); } @@ -147,41 +158,43 @@ public abstract class TimeTrackerState { } private Collection createDetails(Interval interval, - Iterator datesGenerator, - IDetailItemCreator detailItemCreator) { + Iterator datesGenerator, + IDetailItemCreator detailItemCreator) { + + List result = new ArrayList<>(); LocalDate current = interval.getStart(); LocalDate end = interval.getFinish(); - List result = new ArrayList(); + while (current.isBefore(end)) { - result.add(detailItemCreator.create(current - .toDateTimeAtStartOfDay())); + result.add(detailItemCreator.create(current.toDateTimeAtStartOfDay())); assert datesGenerator.hasNext(); current = datesGenerator.next(); } + return result; } - private final Collection createDetailsForFirstLevel( - Interval interval) { + private final Collection createDetailsForFirstLevel(Interval interval) { Interval realInterval = getRealIntervalFor(interval); - return createDetails(realInterval, + + return createDetails( + realInterval, getPeriodsFirstLevelGenerator(realInterval.getStart()), getDetailItemCreatorFirstLevel()); } - protected abstract Iterator getPeriodsFirstLevelGenerator( - LocalDate start); + protected abstract Iterator getPeriodsFirstLevelGenerator(LocalDate start); - private final Collection createDetailsForSecondLevel( - Interval interval) { + private final Collection createDetailsForSecondLevel(Interval interval) { Interval realInterval = getRealIntervalFor(interval); - return createDetails(realInterval, + + return createDetails( + realInterval, getPeriodsSecondLevelGenerator(realInterval.getStart()), getDetailItemCreatorSecondLevel()); } - protected abstract Iterator getPeriodsSecondLevelGenerator( - LocalDate start); + protected abstract Iterator getPeriodsSecondLevelGenerator(LocalDate start); protected abstract IDetailItemCreator getDetailItemCreatorFirstLevel(); @@ -201,6 +214,7 @@ public abstract class TimeTrackerState { return Years.yearsBetween(start, end); } }, + MONTHS { @Override public ReadablePeriod toPeriod(int amount) { @@ -212,6 +226,7 @@ public abstract class TimeTrackerState { return Months.monthsBetween(start, end); } }, + WEEKS { @Override public ReadablePeriod toPeriod(int amount) { @@ -223,6 +238,7 @@ public abstract class TimeTrackerState { return Weeks.weeksBetween(start, end); } }, + DAYS { @Override public ReadablePeriod toPeriod(int amount) { @@ -237,8 +253,7 @@ public abstract class TimeTrackerState { public abstract ReadablePeriod toPeriod(int amount); - public abstract BaseSingleFieldPeriod differenceBetween( - LocalDate start, LocalDate end); + public abstract BaseSingleFieldPeriod differenceBetween(LocalDate start, LocalDate end); public Period amount(int amount) { return new Period(this, amount); @@ -262,18 +277,16 @@ public abstract class TimeTrackerState { } BaseSingleFieldPeriod asPeriod(Interval interval) { - return type.differenceBetween(interval.getStart(), - interval.getFinish()); + return type.differenceBetween(interval.getStart(), interval.getFinish()); } } protected abstract Period getMinimumPeriod(); private Interval ensureMinimumInterval(Interval interval) { - LocalDate newEnd = interval.getStart().plus( - getMinimumPeriod().toPeriod()); - return new Interval(interval.getStart(), Collections.max(asList(newEnd, - interval.getFinish()))); + LocalDate newEnd = interval.getStart().plus(getMinimumPeriod().toPeriod()); + + return new Interval(interval.getStart(), Collections.max(asList(newEnd, interval.getFinish()))); } public Interval getRealIntervalFor(Interval testInterval) { @@ -283,9 +296,8 @@ public abstract class TimeTrackerState { private Interval calculateForAtLeastMinimum(Interval atLeastMinimum) { LocalDate start = round(atLeastMinimum.getStart(), true); LocalDate finish = round(atLeastMinimum.getFinish(), false); - Interval result = new Interval(start.toDateTimeAtStartOfDay().toDate(), - finish.toDateTimeAtStartOfDay().toDate()); - return result; + + return new Interval(start.toDateTimeAtStartOfDay().toDate(), finish.toDateTimeAtStartOfDay().toDate()); } public abstract double daysPerPixel(); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java index fda2b5a5e..d3ed54340 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java @@ -32,9 +32,8 @@ import org.joda.time.ReadablePeriod; */ public abstract class TimeTrackerStateWithSubintervalsFitting extends TimeTrackerState { - protected TimeTrackerStateWithSubintervalsFitting( - IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + protected TimeTrackerStateWithSubintervalsFitting(IDetailItemModificator firstLevelModificator, + IDetailItemModificator secondLevelModificator) { super(firstLevelModificator, secondLevelModificator); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java index 7d6e62fad..6dd8e3b40 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java @@ -23,8 +23,10 @@ package org.zkoss.ganttz.timetracker.zoom; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.zkoss.ganttz.i18n.I18nHelper; + /** + * Describes levels of zooming (time-zooming) on Gantt panel. + * * @author Francisco Javier Moran Rúa */ public enum ZoomLevel { @@ -32,8 +34,8 @@ public enum ZoomLevel { DETAIL_ONE(_("Year")) { @Override public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + IDetailItemModificator firstLevel, IDetailItemModificator secondLevel) { + return new DetailOneTimeTrackerState(firstLevel, secondLevel); } @@ -42,11 +44,12 @@ public enum ZoomLevel { return days > 950; } }, + DETAIL_TWO(_("Quarter")) { @Override public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + IDetailItemModificator firstLevel, IDetailItemModificator secondLevel) { + return new DetailTwoTimeTrackerState(firstLevel, secondLevel); } @@ -55,11 +58,12 @@ public enum ZoomLevel { return days > 550; } }, + DETAIL_THREE(_("Month")) { @Override public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + IDetailItemModificator firstLevel, IDetailItemModificator secondLevel) { + return new DetailThreeTimeTrackerState(firstLevel, secondLevel); } @@ -68,11 +72,12 @@ public enum ZoomLevel { return days > 175; } }, + DETAIL_FOUR(_("Week")) { @Override public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + IDetailItemModificator firstLevel, IDetailItemModificator secondLevel) { + return new DetailFourTimeTrackerState(firstLevel, secondLevel); } @@ -81,25 +86,13 @@ public enum ZoomLevel { return days > 50; } }, + DETAIL_FIVE(_("Day")) { @Override public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { - return new DetailFiveTimeTrackerState(firstLevel, secondLevel); - } + IDetailItemModificator firstLevel, IDetailItemModificator secondLevel) { - @Override - public boolean isSuitableFor(int days) { - return true; - } - }, - DETAIL_SIX(_("Hour")) { - @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { - return new DetailSixTimeTrackerState(firstLevel, secondLevel); + return new DetailFiveTimeTrackerState(firstLevel, secondLevel); } @Override @@ -108,57 +101,50 @@ public enum ZoomLevel { } }; + private String internalName; + + ZoomLevel(String name) { + this.internalName = name; + } + /** - * Forces to mark the string as needing translation + * Forces to mark the string as needing translation. */ private static String _(String string) { return string; } - private String internalName; - public String getInternalName() { return internalName; } - private ZoomLevel(String name) { - this.internalName = name; - } - /** - * @return if there is no next, returns this. Otherwise returns - * the next one. + * @return if there is no next, returns this. Otherwise returns the next one. */ public ZoomLevel next() { final int next = ordinal() + 1; - if (next == ZoomLevel.values().length) { - return this; - } - return ZoomLevel.values()[next]; + + return next == ZoomLevel.values().length ? this : ZoomLevel.values()[next]; } /** - * @return if there is no previous, returns this. Otherwise - * returns the previous one. + * @return if there is no previous, returns this. Otherwise returns the previous one. */ public ZoomLevel previous() { - if (ordinal() == 0) { - return this; - } - return ZoomLevel.values()[ordinal() - 1]; + return ordinal() == 0 ? this : ZoomLevel.values()[ordinal() - 1]; } public abstract TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel); + IDetailItemModificator firstLevel, IDetailItemModificator secondLevel); @Override public String toString() { - return I18nHelper._(internalName); + return _(internalName); } public static ZoomLevel getFromString(String zoomLevelParameter) { ZoomLevel requiredZoomLevel = ZoomLevel.DETAIL_ONE; + if (zoomLevelParameter != null) { for (ZoomLevel z : ZoomLevel.values()) { if (zoomLevelParameter.equals(z.internalName)) { @@ -170,10 +156,10 @@ public enum ZoomLevel { } - public static ZoomLevel getDefaultZoomByDates(LocalDate initDate, - LocalDate endDate) { + public static ZoomLevel getDefaultZoomByDates(LocalDate initDate, LocalDate endDate) { if (initDate != null && endDate != null) { int days = Days.daysBetween(initDate, endDate).getDays(); + for (ZoomLevel each : ZoomLevel.values()) { if (each.isSuitableFor(days)) { return each; diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java index bd3bdb053..a306e36dc 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java @@ -29,7 +29,7 @@ import org.zkoss.zul.Grid; import org.zkoss.zul.Listbox; import org.zkoss.zul.Listitem; import org.zkoss.zul.Row; -import org.zkoss.zul.api.Rows; +import org.zkoss.zul.Rows; /** * Utility methods to find components @@ -40,55 +40,63 @@ public class ComponentsFinder { private ComponentsFinder() { } - public static List findComponentsOfType(Class type, - List children) { - ArrayList result = new ArrayList(); + public static List findComponentsOfType(Class type, List children) { + ArrayList result = new ArrayList<>(); for (Object child : children) { - if (type.isInstance(child)) { + + if ( type.isInstance(child) ) { result.add(type.cast(child)); } } + return result; } - public static Component findById(String id, - List children) { + public static Component findById(String id, List children) { for (Component child : children) { - if (child.getId().equals(id)) { + + if ( child.getId().equals(id) ) { return child; } } + return null; } public static Row findRowByValue(Grid grid, Object needle) { - if (grid == null || needle == null) { + if ( grid == null || needle == null ) { return null; } Rows rows = grid.getRows(); for (Object each : rows.getChildren()) { - if (each instanceof Row) { + + if ( each instanceof Row ) { Row row = (Row) each; Object value = row.getValue(); - if (needle.equals(value)) { + + if ( needle.equals(value) ) { return row; } } } + return null; } public static Listitem findItemByValue(Listbox listbox, Object needle) { - if (listbox == null || needle == null) { + if ( listbox == null || needle == null ) { return null; } + for (Object each : listbox.getItems()) { Listitem item = (Listitem) each; Object value = item.getValue(); - if (needle.toString().equals(value.toString())) { + + if ( needle.toString().equals(value.toString()) ) { return item; } } + return null; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java index 86ebe68db..fcc342342 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java @@ -41,8 +41,9 @@ import org.zkoss.zk.ui.util.Clients; /** - * @author Óscar González Fernández + * Handler of long operations ( {@link Clients#showBusy(String)}, {@link Clients#clearBusy()} ). * + * @author Óscar González Fernández */ public class LongOperationFeedback { @@ -61,16 +62,20 @@ public class LongOperationFeedback { } }; - public static void execute(final Component component, final ILongOperation longOperation) { + public static void execute(final Component component, + final ILongOperation longOperation) { + Validate.notNull(component); Validate.notNull(longOperation); - if ( alreadyInside.get() ) { + if (alreadyInside.get()) { dispatchActionDirectly(longOperation); + return; } Clients.showBusy(longOperation.getName()); + executeLater(component, new Runnable() { public void run() { try { @@ -86,13 +91,13 @@ public class LongOperationFeedback { }); } - public static void executeLater(final Component component, final Runnable runnable) { + public static void executeLater(final Component component, + final Runnable runnable) { Validate.notNull(runnable); Validate.notNull(component); - final String eventName = generateEventName(); - component.addEventListener(eventName, new EventListener() { + component.addEventListener(eventName, new EventListener() { @Override public void onEvent(Event event) { try { @@ -131,13 +136,9 @@ public class LongOperationFeedback { } public static IDesktopUpdate and(final IDesktopUpdate... desktopUpdates) { - return new IDesktopUpdate() { - - @Override - public void doUpdate() { - for (IDesktopUpdate each : desktopUpdates) { - each.doUpdate(); - } + return () -> { + for (IDesktopUpdate each : desktopUpdates) { + each.doUpdate(); } }; } @@ -149,50 +150,39 @@ public class LongOperationFeedback { private static final ExecutorService executor = Executors.newCachedThreadPool(); public static IDesktopUpdatesEmitter doNothingEmitter() { - return new IDesktopUpdatesEmitter() { - @Override - public void doUpdate(T value) { - } - }; + return value -> {}; } /** - * Executes a long operation. The background operation can send - * {@link IDesktopUpdate} objects that can update desktop state. Trying to - * update the components in any other way would fail - */ - public static void progressive(final Desktop desktop, final IBackGroundOperation operation) { - progressive(desktop, operation, new IDesktopUpdatesEmitter() { - @Override - public void doUpdate(IDesktopUpdate update) { - update.doUpdate(); - } - }); - } - - /** - * Executes a long operation. The background operation can send - * T objects that can update desktop state. A - * {@link IDesktopUpdatesEmitter} that handle these objects is necessary. + * Executes a long operation. + * The background operation can send {@link IDesktopUpdate} objects that can update desktop state. * Trying to update the components in any other way would fail. */ - public static void progressive( - final Desktop desktop, - final IBackGroundOperation operation, - final IDesktopUpdatesEmitter emitter) { + public static void progressive(final Desktop desktop, + final IBackGroundOperation operation) { + progressive(desktop, operation, (update) -> update.doUpdate()); + } + + /** + * Executes a long operation. + * The background operation can send + * T objects that can update desktop state. + * A {@link IDesktopUpdatesEmitter} that handle these objects is necessary. + * Trying to update the components in any other way would fail. + */ + public static void progressive(final Desktop desktop, + final IBackGroundOperation operation, + final IDesktopUpdatesEmitter emitter) { desktop.enableServerPush(true); - executor.execute(new Runnable() { - - public void run() { - try { - IBackGroundOperation operationWithAsyncUpates = withAsyncUpates(operation, desktop); - operationWithAsyncUpates.doOperation(emitter); - } catch (Exception e) { - LOG.error("error executing background operation", e); - } finally { - desktop.enableServerPush(false); - } + executor.execute(() -> { + try { + IBackGroundOperation operationWithAsyncUpates = withAsyncUpates(operation, desktop); + operationWithAsyncUpates.doOperation(emitter); + } catch (Exception e) { + LOG.error("error executing background operation", e); + } finally { + desktop.enableServerPush(false); } }); } @@ -202,14 +192,14 @@ public class LongOperationFeedback { final Desktop desktop) { return new IBackGroundOperation() { + @Override public void doOperation(IDesktopUpdatesEmitter originalEmitter) { NotBlockingDesktopUpdates notBlockingDesktopUpdates = - new NotBlockingDesktopUpdates(desktop, originalEmitter); + new NotBlockingDesktopUpdates<>(desktop, originalEmitter); Future future = executor.submit(notBlockingDesktopUpdates); - try { backgroundOperation.doOperation(notBlockingDesktopUpdates); } finally { @@ -231,7 +221,9 @@ public class LongOperationFeedback { private static class NotBlockingDesktopUpdates implements IDesktopUpdatesEmitter, Runnable { private BlockingQueue> queue = new LinkedBlockingQueue<>(); + private final IDesktopUpdatesEmitter original; + private final Desktop desktop; NotBlockingDesktopUpdates(Desktop desktop, IDesktopUpdatesEmitter original) { @@ -245,30 +237,28 @@ public class LongOperationFeedback { } void finish() { - queue.add(EndOrValue. end()); + queue.add(EndOrValue.end()); } @Override public void run() { + List batch = new ArrayList<>(); while (true) { batch.clear(); EndOrValue current; - try { current = queue.take(); } catch (InterruptedException e) { throw new RuntimeException(e); } - if ( current.isEnd() ) { + if (current.isEnd()) return; - } - if ( !desktop.isAlive() || !desktop.isServerPushEnabled() ) { + if (!desktop.isAlive() || !desktop.isServerPushEnabled()) return; - } try { Executions.activate(desktop); @@ -279,27 +269,30 @@ public class LongOperationFeedback { try { original.doUpdate(current.getValue()); - while ((current = queue.poll()) != null) { - if ( current.isEnd() ) { + while ((current = queue.poll()) != null) { + if (current.isEnd()) { break; } batch.add(current.getValue()); original.doUpdate(current.getValue()); } + } finally { Executions.deactivate(desktop); } - if ( current != null && current.isEnd() ) { + + if (current != null && current.isEnd()) { return; } + } } } - private static abstract class EndOrValue { + private abstract static class EndOrValue { public static EndOrValue end() { return new End<>(); } @@ -309,6 +302,7 @@ public class LongOperationFeedback { } public abstract boolean isEnd(); + public abstract T getValue() throws UnsupportedOperationException; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java index d9569d95c..0e37297d0 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java @@ -31,32 +31,48 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlNativeComponent; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zul.Menuitem; import org.zkoss.zul.Menupopup; import org.zkoss.zul.Menuseparator; -import org.zkoss.zul.impl.api.XulElement; +import org.zkoss.zul.impl.XulElement; +/** + * Create context menu for right-click mouse. + * + * @param + */ public class MenuBuilder { - public static MenuBuilder on(Page page, - Collection elements) { - return new MenuBuilder(page, elements); + private final List elements; + + private final List items = new ArrayList<>(); + + private Component root; + + private T referenced; + + private MenuBuilder(Page page, Collection elements) { + this.elements = new ArrayList<>(elements); + this.root = findVisibleOn(getRoots(page)); } - public static MenuBuilder on(Page page, - T... elements) { + public static MenuBuilder on(Page page, Collection elements) { + return new MenuBuilder<>(page, elements); + } + + public static MenuBuilder on(Page page, T... elements) { return on(page, Arrays.asList(elements)); } - public static interface ItemAction { - - void onEvent(T choosen, Event event); + public interface ItemAction { + void onEvent(T chosen, Event event); } private class Item { + private final String name; + private final String icon; private final ItemAction action; @@ -70,60 +86,50 @@ public class MenuBuilder { Menuitem createMenuItem() { Menuitem result = new Menuitem(); result.setLabel(name); - if (icon != null) { + + if ( icon != null ) { result.setImage(icon); } + return result; } } - private final List elements; - - private final List items = new ArrayList(); - - private Component root; - - private MenuBuilder(Page page, Collection elements) { - this.elements = new ArrayList(elements); - this.root = findVisibleOn(getRoots(page)); - } - private static List getRoots(Page page) { - List result = new ArrayList(); + List result = new ArrayList<>(); Component current = page.getFirstRoot(); + while (current != null) { result.add(current); current = current.getNextSibling(); } + return result; } - private static Component findVisibleOn( - Collection candidates) { + private static Component findVisibleOn(Collection candidates) { for (Component each : candidates) { - if (each.isVisible()) { + if ( each.isVisible() ) { return each; } } - throw new RuntimeException( - "not found visible component on which to attach the menu"); + + throw new RuntimeException("not found visible component on which to attach the menu"); } - public MenuBuilder item(String name, String icon, - ItemAction itemAction) { - if (name == null) { + public MenuBuilder item(String name, String icon, ItemAction itemAction) { + if ( name == null ) { throw new IllegalArgumentException("name cannot be null"); } - if (itemAction == null) { + if ( itemAction == null ) { throw new IllegalArgumentException("itemAction cannot be null"); } items.add(new Item(name, icon, itemAction)); + return this; } - private T referenced; - public Menupopup createWithoutSettingContext() { return create(false); } @@ -134,55 +140,55 @@ public class MenuBuilder { private Menupopup create(boolean setContext) { Menupopup result = new Menupopup(); - result.addEventListener("onOpen", new EventListener() { - @Override - public void onEvent(Event event) { - OpenEvent openEvent = (OpenEvent) event; - referenced = (T) openEvent.getReference(); - } + result.addEventListener("onOpen", event -> { + OpenEvent openEvent = (OpenEvent) event; + referenced = (T) openEvent.getReference(); }); + for (final Item item : items) { - if (!item.name.equals("separator")) { + + if ( !"separator".equals(item.name) ) { Menuitem menuItem = item.createMenuItem(); - menuItem.addEventListener("onClick", new EventListener() { - @Override - public void onEvent(Event event) { - ItemAction action = item.action; - action.onEvent(referenced, event); - } + + menuItem.addEventListener("onClick", event -> { + ItemAction action = item.action; + action.onEvent(referenced, event); }); + result.appendChild(menuItem); } else { Menuseparator separator = new Menuseparator(); result.appendChild(separator); } } + insertInRootComponent(result); - if (setContext) { + + if ( setContext ) { for (T element : elements) { element.setContext(result); } } + return result; } private void insertInRootComponent(Menupopup result) { - ArrayList children = new ArrayList(root - .getChildren()); + ArrayList children = new ArrayList<>(root.getChildren()); Collections.reverse(children); - // the Menupopup cannot be inserted after a HtmlNativeComponent, so we - // try to avoid it - if (children.isEmpty()) { + // The Menupopup cannot be inserted after a HtmlNativeComponent, so we try to avoid it + if ( children.isEmpty() ) { root.appendChild(result); } + for (Component child : children) { - if (!(child instanceof HtmlNativeComponent)) { + if ( !(child instanceof HtmlNativeComponent) ) { root.insertBefore(result, child); return; } } - throw new RuntimeException("all children of " + root - + " are html native"); + + throw new RuntimeException("all children of " + root + " are html native"); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java index 1883f5137..52ca692e8 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java @@ -38,25 +38,29 @@ import org.zkoss.zul.event.TreeDataEvent; /** * @author Óscar González Fernández + * @author Vova Perebykivskyi + * @author Bogdan Bodnarjuk */ + public class MutableTreeModel extends AbstractTreeModel { private static final Log LOG = LogFactory.getLog(MutableTreeModel.class); public interface IChildrenExtractor { - public List getChildren(T parent); + List getChildren(T parent); } - private static class Node { + public static class Node { + private T value; - private List> children = new LinkedList>(); + private List> children = new LinkedList<>(); private Node parentNode; - private Node(T value) { + public Node(T value) { this.value = value; } @@ -64,7 +68,8 @@ public class MutableTreeModel extends AbstractTreeModel { for (Node n : nodes) { n.parentNode = this; } - if (position == null) { + + if ( position == null ) { children.addAll(nodes); } else { children.addAll(position, nodes); @@ -73,44 +78,54 @@ public class MutableTreeModel extends AbstractTreeModel { public int[] down(Node node) { ListIterator> listIterator = children.listIterator(); + while (listIterator.hasNext()) { Node current = listIterator.next(); - if (current == node && listIterator.hasNext()) { + + if ( current == node && listIterator.hasNext() ) { int nextIndex = listIterator.nextIndex(); listIterator.remove(); listIterator.next(); listIterator.add(node); + return new int[] { nextIndex - 1, nextIndex }; } } + return new int[] {}; } public int[] up(Node node) { - ListIterator> listIterator = children.listIterator(children - .size()); - while (listIterator.hasPrevious()) { + ListIterator> listIterator = children.listIterator(children.size()); + + while ( listIterator.hasPrevious() ) { Node current = listIterator.previous(); - if (current == node && listIterator.hasPrevious()) { + + if ( current == node && listIterator.hasPrevious() ) { listIterator.remove(); int previousIndex = listIterator.previousIndex(); listIterator.previous(); listIterator.add(current); + return new int[] { previousIndex, previousIndex + 1 }; } } + return new int[] {}; } private void until(LinkedList result, Node parent) { - if (parent.equals(this)) { - return; - } else if (isRoot()) { - // final reached, but parent not found - result.clear(); - } else { - result.add(0, this.parentNode.getIndexOf(this)); - this.parentNode.until(result, parent); + if ( !parent.equals(this) ) { + + if ( isRoot() ) { + + /* Final reached, but parent not found */ + result.clear(); + + } else { + result.add(0, this.parentNode.getIndexOf(this)); + this.parentNode.until(result, parent); + } } } @@ -124,14 +139,16 @@ public class MutableTreeModel extends AbstractTreeModel { } public LinkedList until(Node parent) { - LinkedList result = new LinkedList(); + LinkedList result = new LinkedList<>(); until(result, parent); + return result; } public int remove() { int positionInParent = parentNode.getIndexOf(this); parentNode.children.remove(positionInParent); + return positionInParent; } @@ -143,10 +160,10 @@ public class MutableTreeModel extends AbstractTreeModel { private final Node root; - private transient Map> nodesByDomainObject = new WeakHashMap>(); + private transient Map> nodesByDomainObject = new WeakHashMap<>(); private static Node wrapOne(T object) { - return new Node(object); + return new Node<>(object); } private static List> wrap(T... objects) { @@ -154,14 +171,22 @@ public class MutableTreeModel extends AbstractTreeModel { } private static List> wrap(Collection objects) { - List> result = new ArrayList>(); + List> result = new ArrayList<>(); + for (T o : objects) { result.add(wrapOne(o)); } + return result; } private Node find(Object domainObject) { + for (Map.Entry> item : nodesByDomainObject.entrySet()) { + if ( item.getKey() != null && item.getKey().equals(domainObject) ) { + return item.getValue(); + } + } + return nodesByDomainObject.get(domainObject); } @@ -170,33 +195,65 @@ public class MutableTreeModel extends AbstractTreeModel { } public static MutableTreeModel create(Class type) { - return new MutableTreeModel(type, new Node(null)); + return new MutableTreeModel<>(type, new Node<>(null)); } public static MutableTreeModel create(Class type, T root) { - return new MutableTreeModel(type, wrapOne(root)); + return new MutableTreeModel<>(type, wrapOne(root)); } private MutableTreeModel(Class type, Node root) { super(root); - if (type == null) { + + if ( type == null ) { throw new IllegalArgumentException("type cannot be null"); } nodesByDomainObject.put(unwrap(root), root); this.root = root; } - @Override + /** + * Is some cases it was returning new int[0], but should return new path instead. + * Reason of that: API changes. Before it was looking for child index manually. + * Now it is not looking at all. + * So I decided to return value by our own + * {@link MutableTreeModel#shouldILookForLastValue(Object, Node), {@link #shouldILookForParentValue(Object, Node)}} + * Not to use {@link AbstractTreeModel#getIndexOfChild(Object parent, Object child)}. + */ public int[] getPath(Object parent, Object last) { Node parentNode = find(parent); Node lastNode = find(last); - if (parentNode == null || lastNode == null) { + + if ( shouldILookForParentValue(parent, parentNode) ) { + parentNode = find( ((Node) parent).value ); + } + + if ( shouldILookForLastValue(last, lastNode) ) { + lastNode = find( ((Node) last).value ); + } + + if ( parentNode == null || lastNode == null) { return new int[0]; } List path = lastNode.until(parentNode); + return asIntArray(path); } + private boolean shouldILookForParentValue(Object parent, Node parentNode) { + return parent != null && + parentNode == null && + parent.getClass().toString().contains("Node") && + ((Node) parent).value != null; + } + private boolean shouldILookForLastValue(Object last, Node lastNode) { + return last != null && + lastNode == null && + last.getClass().toString().contains("Node") && + ((Node) last).value != null; + } + + @Override public int[] getPath(Object last) { return getPath(getRoot(), last); } @@ -205,30 +262,33 @@ public class MutableTreeModel extends AbstractTreeModel { T current = getRoot(); for (int i = 0; i < path.length; i++) { int position = path[i]; - if (position >= getChildCount(current)) { + + if ( position >= getChildCount(current) ) { + throw new IllegalArgumentException( - "Failure acessing the path at: " - + stringRepresentationUntil(path, i)); + "Failure acessing the path at: " + stringRepresentationUntil(path, i)); } current = getChild(current, position); } + return current; } private static String stringRepresentationUntil(int[] path, int endExclusive) { - String valid = Arrays.toString(Arrays - .copyOfRange(path, 0, endExclusive)); - String invalid = Arrays.toString(Arrays.copyOfRange(path, endExclusive, - path.length)); + String valid = Arrays.toString(Arrays.copyOfRange(path, 0, endExclusive)); + String invalid = Arrays.toString(Arrays.copyOfRange(path, endExclusive, path.length)); + return valid + "^" + invalid; } private int[] asIntArray(List path) { int[] result = new int[path.size()]; int i = 0; + for (Integer integer : path) { result[i++] = integer; } + return result; } @@ -237,21 +297,74 @@ public class MutableTreeModel extends AbstractTreeModel { return unwrap(root); } + @Override + public T getChild(int[] path){ + T node = getRoot(); + + for (int item : path) { + if (item < 0 || item > _childCount(node)) + return null; + + node = getChild(node, item); + } + + return node; + } + + private int _childCount(T parent) { + return isLeaf(parent) ? 0 : getChildCount(parent); + } + + /** + * Previously index was correct, + * because ZK API was calling {@link AbstractTreeModel#getIndexOfChild(Object, Object)} method. + * Now it is not calling that method and sometimes index could be incorrect. + * So I decided to make --index if it will throw exception. + */ @Override public T getChild(Object parent, int index) { - Node node = find(parent); - return unwrap(node.children.get(index)); + Node node; + + if (parent instanceof MutableTreeModel.Node) { + node = find(((Node) parent).value); + } else { + node = find(parent); + } + + T nodeToReturn; + + try { + nodeToReturn = unwrap(node.children.get(index)); + } catch (IndexOutOfBoundsException e) { + if (parent != null) { + nodeToReturn = unwrap(node.parentNode.children.get(index)); + } else if (index - 1 >= 0) { + nodeToReturn = unwrap(node.children.get(index - 1)); + } else { + throw new IndexOutOfBoundsException("Something wrong with indexes"); + } + } + + return nodeToReturn; } @Override public int getChildCount(Object parent) { - Node node = find(parent); + Node node; + + if (parent instanceof MutableTreeModel.Node) { + node = find(((Node) parent).value); + } else { + node = find(parent); + } + return node.children.size(); } @Override public boolean isLeaf(Object object) { Node node = find(object); + return node.children.isEmpty(); } @@ -265,35 +378,31 @@ public class MutableTreeModel extends AbstractTreeModel { } private IChildrenExtractor noChildrenExtractor() { - return new IChildrenExtractor() { - - @Override - public List getChildren(T parent) { - return Collections.emptyList(); - } - }; + return parent -> Collections.emptyList(); } - private void add(Node parent, Integer position, List> children, - IChildrenExtractor extractor) { - if (children.isEmpty()) { + private void add(Node parent, Integer position, List> children, IChildrenExtractor extractor) { + if ( children.isEmpty() ) { return; } + int indexFrom = position == null ? parent.children.size() : position; int indexTo = indexFrom + children.size() - 1; addWithoutSendingEvents(parent, position, children, extractor); - fireEvent(unwrap(parent), indexFrom, indexTo, - TreeDataEvent.INTERVAL_ADDED); + fireEvent(TreeDataEvent.INTERVAL_ADDED, getPath(parent), indexFrom, indexTo); } - private void addWithoutSendingEvents(Node parent, Integer position, - List> children, IChildrenExtractor extractor) { + private void addWithoutSendingEvents(Node parent, + Integer position, + List> children, + IChildrenExtractor extractor) { + parent.addAll(position, children); addToNodesAndDomainMapping(children); + for (Node each : children) { T value = each.value; - addWithoutSendingEvents(each, 0, - wrap(extractor.getChildren(value)), extractor); + addWithoutSendingEvents(each, 0, wrap(extractor.getChildren(value)), extractor); } } @@ -304,7 +413,7 @@ public class MutableTreeModel extends AbstractTreeModel { } public void add(T parent, T child) { - ArrayList children = new ArrayList(); + ArrayList children = new ArrayList<>(); children.add(child); add(parent, children); } @@ -314,7 +423,7 @@ public class MutableTreeModel extends AbstractTreeModel { T parent = getParent(object); Node parentNode = find(parent); int position = parentNode.getIndexOf(node); - fireEvent(parent, position, position, TreeDataEvent.CONTENTS_CHANGED); + fireEvent(TreeDataEvent.CONTENTS_CHANGED,getPath(parent), position, position); } public void add(T parent, int position, Collection children) { @@ -326,64 +435,64 @@ public class MutableTreeModel extends AbstractTreeModel { add(parentNode, null, wrap(children)); } - public void add(T parent, int position, Collection children, - IChildrenExtractor childrenExtractor) { + public void add(T parent, int position, Collection children, IChildrenExtractor childrenExtractor) { add(find(parent), position, wrap(children), childrenExtractor); } - public void add(T parent, Collection children, - IChildrenExtractor childrenExtractor) { + public void add(T parent, Collection children, IChildrenExtractor childrenExtractor) { add(find(parent), null, wrap(children), childrenExtractor); } public void remove(T node) { Node found = find(node); - if (found.isRoot()) { - throw new IllegalArgumentException(node - + " is root. It can't be removed"); + + if ( found.isRoot() ) { + throw new IllegalArgumentException(node + " is root. It can't be removed"); } + int positionInParent = found.remove(); nodesByDomainObject.remove(node); - fireEvent(unwrap(found.parentNode), positionInParent, positionInParent, - TreeDataEvent.INTERVAL_REMOVED); + fireEvent(TreeDataEvent.INTERVAL_REMOVED, getPath(found.parentNode), positionInParent, positionInParent); } public T getParent(T node) { Node associatedNode = find(node); - if (associatedNode.equals(root)) { + if ( associatedNode.equals(root) ) { throw new IllegalArgumentException(node + " is root"); } + return unwrap(associatedNode.getParent()); } public List getParents(T node) { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); + try { T current = node; - while (!isRoot(current)) { + + while ( !isRoot(current) ) { current = getParent(current); result.add(current); } } catch (Exception e) { LOG.error("Trying to get the parent of a removed node", e); } + return result; } public boolean isRoot(T node) { - Node associatedNode = find(node); - return associatedNode.isRoot(); + return find(node).isRoot(); } - public void replace(T nodeToRemove, T nodeToAdd, - IChildrenExtractor childrenExtractor) { + public void replace(T nodeToRemove, T nodeToAdd, IChildrenExtractor childrenExtractor) { T parent = getParent(nodeToRemove); Node parentNode = find(parent); final int insertionPosition = parentNode.getIndexOf(find(nodeToRemove)); remove(nodeToRemove); - if (childrenExtractor != null) { - add(parent, insertionPosition, - Collections.singletonList(nodeToAdd), childrenExtractor); + + if ( childrenExtractor != null ) { + add(parent, insertionPosition, Collections.singletonList(nodeToAdd), childrenExtractor); } else { add(parent, insertionPosition, Collections.singletonList(nodeToAdd)); } @@ -397,7 +506,8 @@ public class MutableTreeModel extends AbstractTreeModel { T parent = getParent(node); Node parentNode = find(parent); int[] changed = parentNode.down(find(node)); - if (changed.length != 0) { + + if ( changed.length != 0 ) { fireRecreationOfInterval(parentNode, changed[0], changed[1]); } } @@ -406,27 +516,21 @@ public class MutableTreeModel extends AbstractTreeModel { T parent = getParent(node); Node parentNode = find(parent); int[] changed = parentNode.up(find(node)); - if (changed.length != 0) { + + if ( changed.length != 0 ) { fireRecreationOfInterval(parentNode, changed[0], changed[1]); } } - private void fireRecreationOfInterval(Node parentNode, int start, - int endInclusive) { - fireEvent(parentNode.value, start, endInclusive, - TreeDataEvent.INTERVAL_REMOVED); - fireEvent(parentNode.value, start, endInclusive, - TreeDataEvent.INTERVAL_ADDED); + private void fireRecreationOfInterval(Node parentNode, int start, int endInclusive) { + fireEvent(TreeDataEvent.INTERVAL_REMOVED,getPath(parentNode.value), start, endInclusive); + fireEvent(TreeDataEvent.INTERVAL_ADDED, getPath(parentNode.value), start, endInclusive); } public boolean isEmpty() { return getChildCount(getRoot()) == 0; } - public boolean hasChildren(T node) { - return getChildCount(node) > 0; - } - public boolean contains(T object) { return find(object) != null; } @@ -435,21 +539,25 @@ public class MutableTreeModel extends AbstractTreeModel { Node parentNode = find(parent); Node childNode = find(child); - return parentNode != null && childNode != null - && childNode.getParent() != null - && childNode.getParent().equals(parentNode); + return parentNode != null && + childNode != null && + childNode.getParent() != null && + childNode.getParent().equals(parentNode); } public List asList() { - List result = new ArrayList(); + List result = new ArrayList<>(); asList(getRoot(), result); + return result; } private void asList(T root, List result) { - List list = new ArrayList(); + List list = new ArrayList<>(); + for (int i = 0; i < getChildCount(root); i++) { final T child = getChild(root, i); + list.add(child); result.add(child); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java index 7a90a67f4..628248ff7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java @@ -37,18 +37,19 @@ public class WeakReferencedListeners { } + private LinkedList> listeners = new LinkedList<>(); + + private List> pendingOfNotification = new ArrayList<>(); + + private WeakReferencedListeners() {} + public static WeakReferencedListeners create() { return new WeakReferencedListeners<>(); } - private LinkedList> listeners = new LinkedList<>(); - - private WeakReferencedListeners() { - - } - public enum Mode { - RECEIVE_PENDING, FROM_NOW_ON; + RECEIVE_PENDING, + FROM_NOW_ON } public void addListener(T listener) { @@ -61,11 +62,9 @@ public class WeakReferencedListeners { if ( getActiveListeners().isEmpty() && mode == Mode.RECEIVE_PENDING ) { notifyPendingOfNotificationTo(listener); } - listeners.add(new WeakReference(listener)); + listeners.add(new WeakReference<>(listener)); } - private List> pendingOfNotification = new ArrayList<>(); - private void notifyPendingOfNotificationTo(T listener) { for (IListenerNotification each : pendingOfNotification) { each.doNotify(listener); diff --git a/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml b/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml index fcca06ce0..df6a3790a 100755 --- a/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml +++ b/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml @@ -4,8 +4,7 @@ ganttz xul/html - + @@ -22,22 +21,18 @@ org.zkoss.ganttz.Planner ganttz.Planner ~./ganttz/zul/plannerLayout.zul - - tabSwitcher - org.zkoss.ganttz.TabSwitcher - ~./ganttz/zul/tabSwitcher.zul + tabSwitcher + org.zkoss.ganttz.TabSwitcher + ~./ganttz/zul/tabSwitcher.zul resourcesLoadPanel org.zkoss.ganttz.resourceload.ResourcesLoadPanel - ~./ganttz/zul/resourcesLoadLayout.zul + ~./ganttz/zul/resourcesLoadLayout.zul @@ -47,7 +42,6 @@ default mold/resource-load-list.js - @@ -76,20 +70,17 @@ ganttz.GanttPanel default - mold/gantt-panel.js resourceload - org.zkoss.ganttz.resourceload.ResourceLoadComponent - + org.zkoss.ganttz.resourceload.ResourceLoadComponent ganttz.resourceload.ResourceLoadComponent default mold/resource-load-component.js - @@ -100,7 +91,6 @@ ganttz.TaskRow default - mold/task-row.js @@ -111,7 +101,6 @@ ganttz.TaskComponent default - mold/task-component.js @@ -122,21 +111,17 @@ ganttz.Milestone default - mold/milestone.js - taskcontainer - org.zkoss.ganttz.TaskContainerComponent - + org.zkoss.ganttz.TaskContainerComponent ganttz.TaskContainerComponent default mold/task-container.js - @@ -146,7 +131,6 @@ ganttz.TaskList default - mold/task-list.js @@ -157,24 +141,20 @@ ganttz.DependencyList default - mold/dependency-list.js dependency - org.zkoss.ganttz.DependencyComponent - + org.zkoss.ganttz.DependencyComponent ganttz.DependencyComponent default mold/dependency-component.js - - timetracker org.zkoss.ganttz.timetracker.TimeTrackerComponent @@ -183,9 +163,9 @@ - timeTrackedTable - org.zkoss.ganttz.timetracker.TimeTrackedTable - ~./ganttz/zul/timetracker/timetrackedtable.zul + timeTrackedTable + org.zkoss.ganttz.timetracker.TimeTrackedTable + ~./ganttz/zul/timetracker/timetrackedtable.zul diff --git a/ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css b/ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css new file mode 100644 index 000000000..de15fff5b --- /dev/null +++ b/ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css @@ -0,0 +1 @@ +.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em;}.jqplot-axis{font-size:.75em;}.jqplot-xaxis{margin-top:10px;}.jqplot-x2axis{margin-bottom:10px;}.jqplot-yaxis{margin-right:10px;}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px;}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick{position:absolute;white-space:pre;}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top;}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom;}.jqplot-yaxis-tick{right:0;top:15px;text-align:right;}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px 1px 5px;z-index:2;font-size:1.5em;}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left;}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap;}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute;}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute;}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute;}.jqplot-yMidAxis-label{font-size:11pt;position:absolute;}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute;}.jqplot-meterGauge-tick{font-size:.75em;color:#999;}.jqplot-meterGauge-label{font-size:1em;color:#999;}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px;}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em;}td.jqplot-table-legend{vertical-align:middle;}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer;}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through;}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px;}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid;}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em;}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-highlighter-tooltip,.jqplot-canvasOverlay-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-point-label{font-size:.75em;z-index:2;}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center;}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em;}.jqplot-error{text-align:center;}.jqplot-error-message{position:relative;top:46%;display:inline-block;}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%);}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7);}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,0.3);} \ No newline at end of file diff --git a/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul b/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul index 4e803d00d..12b97d99e 100644 --- a/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul +++ b/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul @@ -20,10 +20,10 @@ --> - - - - + + + + \ No newline at end of file diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul index 59ff7ff7e..8a0d6e72c 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul @@ -20,6 +20,5 @@ --> -
-
+
\ No newline at end of file diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul index a77490678..7db75bf8f 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul @@ -20,15 +20,15 @@ --> + signature="java.lang.String _(java.lang.String name)" ?>
- - - - - - - - + + + + + + + +
diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul index 63e0987c3..57430706e 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul @@ -20,20 +20,20 @@ --> - - - + + + + - +
diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul index 82a216b58..7cee61311 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul @@ -20,20 +20,21 @@ --> - - + - + - + - + - +
diff --git a/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul b/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul index ae21cb7ae..5dec45071 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul @@ -18,108 +18,127 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - - - - - + + + + + + + + - - + + - - + -