⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultdockingport.java

📁 定要上载质量高而定要上载质量高而定要上载质量高而定要上载质量高而定要上载质量高而
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     * If the {@code DockingPort} is <b>not</b> empty, and the specified region
     * is {@code NORTH_REGION}, {@code SOUTH_REGION}, {@code EAST_REGION}, or
     * {@code WEST_REGION}, then the currently docked {@code Component} is
     * removed and replaced with a {@code JSplitPane}. Two new
     * {@code DefaultDockingPorts} are created as sub-ports and are added to
     * each side of the {@code JSplitPane}. The previously docked
     * {@code Component} is docked to the CENTER_REGION of one of the sub-ports
     * and the new {@code Component} is added to the other. In this case,
     * subsequent calls to {@code getDockedComponent()} will return the
     * {@code JSplitPane}. In this fasion, the sub-ports will now be capable of
     * handling further sub-docking within the layout.
     * <p>
     * {@code JSplitPane} and sub-{@code DockingPort} creation are delegated to
     * the {@code DockingStrategy} returned by {@code getDockingStrategy()}.
     * Initial splitpane divider location is also controlled by this
     * {@code DockingStrategy}.
     * 
     * @param dockable
     *            the {@code Dockable} to be docked within this
     *            {@code DockingPort}
     * @param region
     *            the region within this {@code DockingPort} to dock the
     *            specified {@code Dockable}
     * @return {@code true} if the docking operation was successful,
     *         {@code false} otherwise.
     * @see DockingPort#dock(Dockable, String)
     * @see #isDockingAllowed(Component, String)
     * @see #getDockedComponent()
     * @see #getDockingStrategy()
     * @see DockingStrategy#createDockingPort(DockingPort)
     * @see DockingStrategy#createSplitPane(DockingPort, String)
     * @see DockingStrategy#getInitialDividerLocation(DockingPort, JSplitPane)
     * @see DockingStrategy#getDividerProportion(DockingPort, JSplitPane)
     */
    public boolean dock(Dockable dockable, String region) {
        if (dockable == null)
            return false;

        Component comp = dockable.getComponent();
        if (comp == null || !isDockingAllowed(comp, region))
            return false;

        // can't dock the same component twice. This will also keep them from
        // moving CENTER to NORTH and that sort of thing, which would just be a
        // headache to manage anyway.
        Component docked = getDockedComponent();
        if (comp == docked)
            return false;

        // if there is nothing currently in the docking port, then we can only
        // dock into the CENTER region.
        if (docked == null)
            region = CENTER_REGION;

        String tabTitle = DockingUtility.getTabText(dockable);
        COMPONENT_TITLES.put(comp, tabTitle);

        if (!isSingleTabAllowed() && docked == null) {
            setComponent(comp);
            evaluateDockingBorderStatus();
            return true;
        }

        boolean success = CENTER_REGION.equals(region) ? dockInCenterRegion(comp)
                : dockInOuterRegion(comp, region);

        if (success) {
            evaluateDockingBorderStatus();
            // if we docked in an outer region, then there is a new JSplitPane.
            // We'll want to divide it in half. this is done after
            // evaluateDockingBorderStatus(), so we'll know any border
            // modification that took place has already happened, and we can be
            // relatively safe about assumptions regarding our current insets.
            if (!CENTER_REGION.equals(region))
                resetSplitDividerLocation();
        }
        return success;
    }

    private void resetSplitDividerLocation() {
        Component c = getDockedComponent();
        if (c instanceof JSplitPane)
            deferSplitDividerReset((JSplitPane) c);
    }

    private void deferSplitDividerReset(final JSplitPane splitPane) {
        applySplitDividerLocation(splitPane);
        // we don't need to defer split divider location reset until after
        // a DockingSplitPane has rendered, since that class is able to figure
        // out its proper divider location by itself.
        if (splitPane instanceof DockingSplitPane) {
            return;
        }

        // check to see if we've rendered
        int size = SwingUtility.getSplitPaneSize(splitPane);
        if (splitPane.isVisible() && size > 0 && EventQueue.isDispatchThread()) {
            // if so, apply the split divider location and return
            applySplitDividerLocation(splitPane);
            splitPane.validate();
            return;
        }

        // otherwise, defer applying the divider location reset until
        // the split pane is rendered.
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                deferSplitDividerReset(splitPane);
            }
        });
    }

    private void applySplitDividerLocation(JSplitPane splitPane) {
        DockingStrategy strategy = DockingManager.getDockingStrategy(this);
        int loc = strategy.getInitialDividerLocation(this, splitPane);
        splitPane.setDividerLocation(loc);
    }

    private boolean dockInCenterRegion(Component comp) {
        Component docked = getDockedComponent();
        JTabbedPane tabs = null;

        if (docked instanceof JTabbedPane) {
            tabs = (JTabbedPane) docked;
            addTab(tabs, comp);
            tabs.revalidate();
            tabs.setSelectedIndex(tabs.getTabCount() - 1);
            return true;
        }

        tabs = createTabbedPane();
        // createTabbedPane() is protected and may be overridden, so we'll have
        // to check for a possible null case here. Though why anyone would
        // return a null, I don't know. Maybe we should throw a
        // NullPointerException instead.
        if (tabs == null)
            return false;

        // remove the currently docked component and add it to the tabbed pane
        if (docked != null) {
            remove(docked);
            addTab(tabs, docked);
        }

        // add the new component to the tabbed pane
        addTab(tabs, comp);

        // now add the tabbed pane back to the main container
        setComponent(tabs);
        tabs.setSelectedIndex(tabs.getTabCount() - 1);
        return true;
    }

    private void addTab(JTabbedPane tabs, Component comp) {
        String tabText = getValidTabTitle(tabs, comp);
        tabs.add(comp, tabText);
        Dockable d = DockingManager.getDockable(comp);
        if (d == null)
            return;

        Icon icon = d.getDockingProperties().getTabIcon();
        int indx = tabs.getTabCount() - 1;
        tabs.setIconAt(indx, icon);
    }

    private boolean dockInOuterRegion(Component comp, String region) {
        // cache the current size and cut it in half for later in the method.
        Dimension halfSize = getSize();
        halfSize.width /= 2;
        halfSize.height /= 2;

        // remove the old docked content. we'll be adding it to another
        // dockingPort.
        Component docked = getDockedComponent();
        remove(docked);

        // add the components to their new parents.
        DockingStrategy strategy = getDockingStrategy();
        DockingPort oldContent = strategy.createDockingPort(this);
        DockingPort newContent = strategy.createDockingPort(this);
        addCmp(oldContent, docked);
        dockCmp(newContent, comp);

        JSplitPane newDockedContent = strategy.createSplitPane(this, region);

        // put the ports in the correct order and add them to a new wrapper
        // panel
        DockingPort[] ports = putPortsInOrder(oldContent, newContent, region);

        if (ports[0] instanceof JComponent) {
            ((JComponent) ports[0]).setMinimumSize(new Dimension(0, 0));
        }
        if (ports[1] instanceof JComponent) {
            ((JComponent) ports[1]).setMinimumSize(new Dimension(0, 0));
        }

        if (ports[0] instanceof Component)
            newDockedContent.setLeftComponent((Component) ports[0]);
        if (ports[1] instanceof Component)
            newDockedContent.setRightComponent((Component) ports[1]);

        // set the split in the middle
        double ratio = .5;

        if (docked instanceof Dockable
                && newDockedContent instanceof DockingSplitPane) {
            Float siblingRatio = ((Dockable) docked).getDockingProperties()
                    .getSiblingSize(region);
            if (siblingRatio != null) {
                ratio = siblingRatio.doubleValue();
            }

            ((DockingSplitPane) newDockedContent).setInitialDividerRatio(ratio);
        }
        newDockedContent.setDividerLocation(ratio);

        // now set the wrapper panel as the currently docked component
        setComponent(newDockedContent);
        // if we're currently showing, then we can exit now
        if (isShowing())
            return true;

        // otherwise, we have unrealized components whose sizes cannot be
        // determined until after we're visible. cache the desired size
        // values now for use later during rendering.
        double proportion = strategy.getDividerProportion(this,
                newDockedContent);
        SwingUtility.putClientProperty((Component) oldContent,
                DefaultDockingStrategy.PREFERRED_PROPORTION, new Float(
                        proportion));
        SwingUtility.putClientProperty((Component) newContent,
                DefaultDockingStrategy.PREFERRED_PROPORTION, new Float(
                        1f - proportion));

        return true;
    }

    /**
     * Returns the child {@code Component} currently embedded within with
     * {@code DockingPort}. If the {@code DockingPort} is empty, then this
     * method returns a {@code null} reference. If there is a single
     * {@code Dockable} docked within it with no tabbed layout, then the
     * {@code Component} for that {@code Dockable} is returned per its
     * {@code getComponent()} method. If there is a tabbed layout present, then
     * a {@code JTabbedPane} is returned. If there is a split layout present,
     * then a {@code JSplitPane} is returned.
     * 
     * @see DockingPort#getDockedComponent()
     */
    public Component getDockedComponent() {
        return dockedComponent;
    }

    // private JSplitPane getDockedSplitPane() {
    // Component docked = getDockedComponent();
    // return docked instanceof JSplitPane? (JSplitPane)docked: null;
    // }

    /**
     * Returns a {@code String} identifier that is unique to
     * {@code DockingPorts} within a JVM instance, but persistent across JVM
     * instances. This is used for configuration mangement, allowing the JVM to
     * recognize a {@code DockingPort} instance within an application instance,
     * persist the ID, and recall it in later application instances. The ID
     * should be unique within an appliation instance so that there are no
     * collisions with other {@code DockingPort} instances, but it should also
     * be consistent from JVM to JVM so that the association between a
     * {@code DockingPort} instance and its ID can be remembered from session to
     * session.
     * <p>
     * The value returned by this method will come from the most recent call to
     * {@code setPersistentId(String id)}. If
     * {@code setPersistentId(String id)} was invoked with a {@code null}
     * argument, then the {@code String} verion of this {@code DockingPort's}
     * hash code is used. Therefore, this method will never return a
     * {@code null} reference.
     * 
     * @return the persistent ID for this {@code DockingPort}
     * @see DockingPort#getPersistentId()
     * @see #setPersistentId(String)
     * @see DockingManager#getDockingPort(String)
     */
    public String getPersistentId() {
        return persistentId;
    }

    /**
     * Sets the persisent ID to be used for this {@code DockingPort}. If
     * {@code id} is {@code null}, then the {@code String} value of this
     * {@code DockingPort's} hash code is used.
     * <p>
     * {@code DockingPorts} are tracked by persistent ID within
     * {@code DockingManager}. Whenever this method is called, the
     * {@code DockingManager's} tracking mechanism is automatically upated for
     * this {@code DockingPort}.
     * 
     * @param id
     *            the persistent ID to be used for this {@code DockingPort}
     * @see #getPersistentId()
     * @see DockingManager#getDockingPort(String)
     * @see DockingPortTracker#updateIndex(DockingPort)
     */
    public void setPersistentId(String id) {
        if (id == null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -