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

org.flexdock.perspective.Layout Maven / Gradle / Ivy

The newest version!
/*
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.flexdock.perspective;

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.Window;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.flexdock.docking.Dockable;
import org.flexdock.docking.DockingManager;
import org.flexdock.docking.DockingPort;
import org.flexdock.docking.floating.frames.DockingFrame;
import org.flexdock.docking.state.DockingState;
import org.flexdock.docking.state.FloatManager;
import org.flexdock.docking.state.FloatingGroup;
import org.flexdock.docking.state.LayoutNode;
import org.flexdock.event.EventManager;
import org.flexdock.perspective.event.LayoutEvent;
import org.flexdock.perspective.event.LayoutListener;
import org.flexdock.perspective.event.RegistrationEvent;
import org.flexdock.util.DockingUtility;
import org.flexdock.util.RootWindow;
import org.flexdock.util.SwingUtility;

/**
 * @author Christopher Butler
 */
public class Layout implements Cloneable, FloatManager, Serializable {

    private HashMap dockingInfo;  // contains DockingState objects
    private Hashtable floatingGroups;  // contains FloatingGroup objects
    private LayoutNode restorationLayout;

    private transient ArrayList layoutListeners;

    public Layout() {
        this(new HashMap(), new ArrayList(), new Hashtable());
    }

    private Layout(HashMap info, ArrayList listeners, Hashtable floatGroups) {
        dockingInfo = info;
        layoutListeners = listeners;
        floatingGroups = floatGroups;
    }

    private ArrayList getLayoutListeners() {
        if(layoutListeners==null) {
            layoutListeners = new ArrayList();
        }
        return layoutListeners;
    }

    public void addListener(LayoutListener listener) {
        if(listener!=null) {
            synchronized(getLayoutListeners()) {
                getLayoutListeners().add(listener);
            }
        }
    }

    public void removeListener(LayoutListener listener) {
        if(listener!=null) {
            synchronized(getLayoutListeners()) {
                getLayoutListeners().remove(listener);
            }
        }
    }

    public LayoutListener[] getListeners() {
        return (LayoutListener[])getLayoutListeners().toArray(new LayoutListener[0]);
    }

    public void add(Dockable dockable) {
        String key = dockable==null? null: dockable.getPersistentId();
        add(key);
    }

    public void add(String dockableId) {
        if(dockableId==null) {
            return;
        }

        DockingState info = null;
        synchronized(dockingInfo) {
            // return if we're already managing this dockable
            if (dockingInfo.containsKey(dockableId)) {
                return;
            }

            // create and add dockingstateinfo here
            info = new DockingState(dockableId);
            dockingInfo.put(dockableId, info);
        }

        EventManager.dispatch(new RegistrationEvent(info, this, true));
    }

    public DockingState remove(String dockableId) {
        if(dockableId==null) {
            return null;
        }

        DockingState info = null;
        synchronized(dockingInfo) {
            info = (DockingState)dockingInfo.remove(dockableId);
        }
        // dispatch event notification if we actually removed something
        if(info!=null) {
            EventManager.dispatch(new RegistrationEvent(info, this, false));
        }
        return info;
    }

    public boolean contains(Dockable dockable) {
        return dockable==null? false: contains(dockable.getPersistentId());
    }

    public boolean contains(String dockable) {
        return dockable==null? false: dockingInfo.containsKey(dockable);
    }

    public Dockable getDockable(String id) {
        if(dockingInfo.containsKey(id)) {
            return DockingManager.getDockable(id);
        }
        return null;
    }

    public Dockable[] getDockables() {
        ArrayList list = new ArrayList(dockingInfo.size());
        for(Iterator it=dockingInfo.keySet().iterator(); it.hasNext();) {
            String dockingId = (String)it.next();
            Dockable d = DockingManager.getDockable(dockingId);
            if(d!=null) {
                list.add(d);
            }
        }
        return (Dockable[])list.toArray(new Dockable[0]);
    }

    public DockingState getDockingState(String dockableId) {
        return getDockingState(dockableId, false);
    }

    public DockingState getDockingState(Dockable dockable) {
        return getDockingState(dockable, false);
    }

    public DockingState getDockingState(Dockable dockable, boolean load) {
        if(dockable==null) {
            return null;
        }

        return getDockingState(dockable.getPersistentId(), load);
    }

    public DockingState getDockingState(String dockableId, boolean load) {
        if(dockableId==null) {
            return null;
        }

        if(load) {
            Dockable dockable = DockingManager.getDockable(dockableId);
            if(dockable!=null) {
                isMaintained(dockable);
            }
        }
        Object obj = dockingInfo.get(dockableId);
        return (DockingState)obj;
    }

    public void setDockingState(String dockableId, DockingState dockingState) {
        if(dockableId==null || dockingState == null) {
            return;
        }
        this.dockingInfo.put(dockableId, dockingState);
    }

    public void apply(DockingPort dockingPort) {
        Component comp = (Component)dockingPort;
        if(comp==null || !isInitialized()) {
            //                if(comp==null || comp.getParent()==null || !isInitialized())
            return;
        }

        // clear out the existing components
        PerspectiveManager.clear(dockingPort);

        // restore the layout
        boolean listening = PerspectiveManager.isDockingStateListening();
        PerspectiveManager.setDockingStateListening(false);
        try {
            dockingPort.importLayout(restorationLayout);
        } finally {
            PerspectiveManager.setDockingStateListening(listening);
        }

        // not restore floating and minimized layouts
        Dockable[] dockables = getDockables();

        // if there is no active window into which to restore our minimized
        // dockables, then we'll have to defer restoration until a window appears.
        ArrayList deferredMinimizedDockables = new ArrayList();
        boolean deferMinimized = SwingUtility.getActiveWindow()==null;

        boolean restoreFloatOnLoad = PerspectiveManager.isRestoreFloatingOnLoad();
        for(int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy