All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drombler.commons.docking.spi.DockingAreaManager Maven / Gradle / Ivy

Go to download

Drombler Commons - Docking - SPI provides some utility classes and frameworks to help building a client side docking framework.

There is a newer version: 1.0
Show newest version
/*
 *         COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Notice
 *
 * The contents of this file are subject to the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.opensource.org/licenses/cddl1.txt
 *
 * The Original Code is Drombler.org. The Initial Developer of the
 * Original Code is Florian Brunner (Sourceforge.net user: puce).
 * Copyright 2012 Drombler.org. All Rights Reserved.
 *
 * Contributor(s): .
 */
package org.drombler.commons.docking.spi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * A Docking Area manager.
 *
 * @param  the type of the Docking Area
 * @author puce
 */
// TODO: check thread safty
// TODO: move this class to Client - Docking - SPI
public class DockingAreaManager> {

    private final Map dockingAreas = new HashMap<>();
    private final Map> dockingAreaManagers = new HashMap<>();
    private final DockingAreaManager parent;
    private final int position;
    private final SplitLevel level;

    /**
     * Creates a new instance of this class.
     *
     * @param parent the parent Docking Area manager
     * @param position the position this manager manages
     * @param level the level
     */
    public DockingAreaManager(DockingAreaManager parent, int position, int level) {
        this(parent, position, SplitLevel.valueOf(level));
    }

    /**
     * Creates a new instance of this class.
     *
     * @param parent the parent Docking Area manager
     * @param position the position this manager manages
     * @param level the level
     */
    public DockingAreaManager(DockingAreaManager parent, int position, SplitLevel level) {
        this.parent = parent;
        this.position = position;
        this.level = level;
    }

    /**
     * Adds a Docking Area.
     *
     * @param path the path where the Docking Area should be added to
     * @param dockingArea the Docking Area to add
     */
    public void addDockingArea(List path, A dockingArea) {
        addDockingArea(path.iterator(), dockingArea);
    }

    private void addDockingArea(Iterator path, A dockingArea) {
        if (path.hasNext()) {
            Integer childPosition = path.next();
            if (!dockingAreaManagers.containsKey(childPosition)) {
                dockingAreaManagers.put(childPosition, new DockingAreaManager<>(this, childPosition,
                        SplitLevel.valueOf(level.getLevel() + 1)));
            }
            dockingAreaManagers.get(childPosition).addDockingArea(path, dockingArea); // recursion
        } else {
            // TODO: handle case where 2 dockingAreas have the same position
            // TODO: handle case where dockingArea and dockingAreaManager have the same position
            dockingArea.setParentManager(this);
            dockingAreas.put(dockingArea.getPosition(), dockingArea);
        }
    }

    private ShortPathPart createShortPathPart(int position) {
        return new ShortPathPart(position, level);
    }

    private boolean isShortPathRelevant(int position, boolean emptyPath) {
        return (!isOnlyActualContent(position)) || (emptyPath && parent == null);
    }

    private boolean isOnlyActualContent(int position) {
        return isCurrentlyOnlyActualContent(position)
                || isFutureOnlyActualContent(position);
    }

    private boolean isCurrentlyOnlyActualContent(int position) {
        return containsActualPosition(position) && getActualContentSize() == 1;
    }

    private boolean isFutureOnlyActualContent(int position) {
        return !containsActualPosition(position) && getActualContentSize() == 0;
    }

    private int getActualContentSize() {
        return getNonEmptyAreaManagers().size() + getVisualizableDockingAreas().size();
    }

    private Map> getNonEmptyAreaManagers() {
        Map> nonEmptyAreaManagers = new HashMap<>();
        dockingAreaManagers.entrySet().stream().
                filter(entry -> entry.getValue().getActualContentSize() > 0).
                forEach(entry -> nonEmptyAreaManagers.put(entry.getKey(), entry.getValue()));
        return nonEmptyAreaManagers;
    }

    private Map getVisualizableDockingAreas() {
        Map visualizableDockingAreas = new HashMap<>();
        dockingAreas.entrySet().stream().
                filter(entry -> entry.getValue().isVisual()).
                forEach(entry -> visualizableDockingAreas.put(entry.getKey(), entry.getValue()));
        return visualizableDockingAreas;
    }

    private boolean containsActualPosition(int position) {
        return (dockingAreaManagers.containsKey(position)
                && dockingAreaManagers.get(position).getActualContentSize() > 0)
                || (dockingAreas.containsKey(position)
                && dockingAreas.get(position).isVisual());
    }

    /**
     * Gets the short path for the provided Docking Area. The short path is the path without any unnecessary split panes.
*
* The provided Docking Area must be managed by this manager. * * @param dockingArea the Docking Area * @return the short path for the provided Docking Area */ public List getShortPath(A dockingArea) { if (!(dockingAreas.containsKey(dockingArea.getPosition()) && dockingAreas.get(dockingArea.getPosition()).equals(dockingArea))) { throw new IllegalStateException( "The specified docking area must be a child of this manager: " + dockingArea); } if (dockingArea.isVisual()) { return calculateShortPath(dockingArea); } else { return Collections.emptyList(); } } private List calculateShortPath(A dockingArea) { List shortPath = calculateReversedShortPath(dockingArea); Collections.reverse(shortPath); return shortPath; } private List calculateReversedShortPath(A dockingArea) { List shortPath = new ArrayList<>(); int currentChildPosition = dockingArea.getPosition(); for (DockingAreaManager
currentParent = this; currentParent != null; currentParent = currentParent.parent) { if (currentParent.isShortPathRelevant(currentChildPosition, shortPath.isEmpty())) { shortPath.add(currentParent.createShortPathPart(currentChildPosition)); } currentChildPosition = currentParent.position; } return shortPath; } /** * {@inheritDoc } */ @Override public String toString() { return String.format("%s[position=%d, level=%s]", DockingAreaManager.class.getSimpleName(), position, level); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy