package ru.khasang.cachoeira.view.mainwindow.diagram.ganttplan.relationlayer; import javafx.application.Platform; import javafx.collections.ListChangeListener; import javafx.collections.WeakListChangeListener; import javafx.scene.layout.Pane; import ru.khasang.cachoeira.model.IDependentTask; import ru.khasang.cachoeira.model.ITask; import ru.khasang.cachoeira.viewcontroller.MainWindowController; import ru.khasang.cachoeira.view.mainwindow.diagram.ganttplan.objectslayer.taskbar.TaskBar; import ru.khasang.cachoeira.view.mainwindow.diagram.ganttplan.relationlayer.relationline.RelationLine; import ru.khasang.cachoeira.view.mainwindow.diagram.ganttplan.relationlayer.relationline.TaskGanttPlanRelationLine; public abstract class RelationsLayer extends Pane{ @SuppressWarnings("FieldCanBeLocal") private ListChangeListener<ITask> taskListChangeListener; public RelationsLayer() { } /** * Метод перерисовывает связи всех задач. * */ public void refreshRelationsDiagram(MainWindowController controller) { this.getChildren().clear(); for (ITask task : controller.getProject().getTaskList()) { for (IDependentTask dependentTask : task.getParentTasks()) { TaskBar parentTaskBar = controller.getTaskGanttPlan().getObjectsLayer() .findTaskBarByTask(dependentTask.getTask()); TaskBar childTaskBar = controller.getTaskGanttPlan().getObjectsLayer() .findTaskBarByTask(task); RelationLine relationLine = new TaskGanttPlanRelationLine( parentTaskBar, childTaskBar, dependentTask.dependenceTypeProperty() ); this.getChildren().add(relationLine); } } } /** * Метод рисует связь между двумя задачами. * * @param parentTask Предыдущая задача (от нее идет стрелка). * @param childTask Задача к которой идет стрелка. */ public void addRelation(IDependentTask parentTask, ITask childTask, MainWindowController controller) { TaskBar parentTaskBar = controller.getTaskGanttPlan().getObjectsLayer() .findTaskBarByTask(parentTask.getTask()); TaskBar childTaskBar = controller.getTaskGanttPlan().getObjectsLayer() .findTaskBarByTask(childTask); RelationLine relationLine = new TaskGanttPlanRelationLine( parentTaskBar, childTaskBar, parentTask.dependenceTypeProperty()); this.getChildren().add(relationLine); } /** * Метод с помощью которого удаляется связь между задачами с диаграммы. * * @param parentTask Предыдущая задача (от нее идет стрелка). * @param childTask Задача к которой идет стрелка. */ public void removeRelation(ITask parentTask, ITask childTask) { this.getChildren().removeIf(node -> { RelationLine relationLine = (RelationLine) node; return relationLine.getParentTask().equals(parentTask) && relationLine.getChildTask().equals(childTask); }); } /** * Метод инициализирующий листенеры. * */ public void setListeners(MainWindowController controller) { // Листенер который следит за добавлением новых задач. // Нужен для обновления связей при изменении положения задачи в таблице задач (при драг'н'дропе). // Если после драг'н'дропа не обновить связь, то она работает не корректно. // TODO: 04.03.2016 По хорошему необходимо обновлять связь только у тех задач которые добавились, а не перерисовывать все связи. taskListChangeListener = change -> { while (change.next()) { if (change.wasAdded()) { Platform.runLater(() -> refreshRelationsDiagram(controller)); } } }; controller.getProject().getTaskList().addListener(new WeakListChangeListener<>(taskListChangeListener)); } }