|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * 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.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core.windows.view.ui; import org.netbeans.core.windows.Constants; import org.netbeans.core.windows.ModeImpl; import org.netbeans.core.windows.WindowManagerImpl; import org.netbeans.core.windows.view.SplitView; import org.netbeans.core.windows.view.ViewElement; import org.netbeans.core.windows.view.dnd.TopComponentDroppable; import org.openide.windows.TopComponent; import javax.swing.*; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; import java.awt.*; // PENDING /** * JSplitPane component which uses resizing policy according the UI spec. * I.e. the nested splits don't propagate draggig of parent split etc. * * @author Marek Slama, Peter Zavadsky */ public class NestedSplitPane extends JSplitPane { private static final String uiClassID = "NestedSplitPaneUI"; // NOI18N private final SplitView splitView; private double tempResizeWeight = -1; /** Creates a new instance of NestedSplitPane */ public NestedSplitPane(SplitView splitView, int orientation, Component first, Component second) { super(orientation, first, second); this.splitView = splitView; setOpaque(false); setBorder (BorderFactory.createEmptyBorder()); } /** Returns location of innnermost divider with given orientation. If there is not * such divider (orientation is different) it returns -1. */ public int getInnerDividerLocation (int orientation, String side, int ind) { if (orientation == getOrientation()) { if (orientation == JSplitPane.HORIZONTAL_SPLIT) { if (JSplitPane.LEFT.equals(side)) { Component c = getRightComponent(); if (c instanceof NestedSplitPane) { //Recursion NestedSplitPane sp = (NestedSplitPane) c; ind++; int loc = sp.getInnerDividerLocation(orientation, side, ind); int newLoc; if (loc != -1) { //Recompute location from inner pane to this pane Point p = SwingUtilities.convertPoint(sp, loc, 0, this); newLoc = p.x; } else { newLoc = getDividerLocation(); } return newLoc; } else { int loc = getDividerLocation(); return loc; } } else { //RIGHT Component c = getLeftComponent(); if (c instanceof NestedSplitPane) { //Recursion NestedSplitPane sp = (NestedSplitPane) c; ind++; int loc = sp.getInnerDividerLocation(orientation, side, ind); int newLoc; if (loc != -1) { //Recompute location from inner pane to this pane Point p = SwingUtilities.convertPoint(sp, loc, 0, this); newLoc = p.x; } else { newLoc = getDividerLocation(); } return newLoc; } else { int loc = getDividerLocation(); return loc; } } } else { //VERTICAL if (JSplitPane.TOP.equals(side)) { Component c = getBottomComponent(); if (c instanceof NestedSplitPane) { //Recursion NestedSplitPane sp = (NestedSplitPane) c; ind++; int loc = sp.getInnerDividerLocation(orientation, side, ind); int newLoc; if (loc != -1) { //Recompute location from inner pane to this pane Point p = SwingUtilities.convertPoint(sp, 0, loc, this); newLoc = p.y; } else { newLoc = getDividerLocation(); } return newLoc; } else { int loc = getDividerLocation(); return loc; } } else { //BOTTOM Component c = getTopComponent(); if (c instanceof NestedSplitPane) { //Recursion NestedSplitPane sp = (NestedSplitPane) c; ind++; int loc = sp.getInnerDividerLocation(orientation, side, ind); int newLoc; if (loc != -1) { //Recompute location from inner pane to this pane Point p = SwingUtilities.convertPoint(sp, 0, loc, this); newLoc = p.y; } else { newLoc = getDividerLocation(); } return newLoc; } else { int loc = getDividerLocation(); return loc; } } } } else { return -1; } } private void setTemporaryResizeWeight(double tempResizeWeight) { this.tempResizeWeight = tempResizeWeight; } public double getResizeWeight() { if (tempResizeWeight != -1) { // Reset back, it is used only once during one dragging 'session'. double ret = tempResizeWeight; tempResizeWeight = -1; return ret; } else { return super.getResizeWeight(); } } /** Overwritten to get desired divider dragging behaviour. Minimum size must * be set according to orientation of parent if parent is also split pane. * Otherwise delegate to superclass. */ public Dimension getMinimumSize () { final Dimension originalMinimum = super.getMinimumSize(); if(getParent() != null && (getParent() instanceof NestedSplitPane)) { NestedSplitPane parent = (NestedSplitPane)getParent(); if((parent.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) && (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)) { //Check left if (JSplitPane.LEFT.equals(parent.getChildConstraint(this))) { Component child = getRightComponent(); if (child instanceof NestedSplitPane && ((NestedSplitPane)child).getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { NestedSplitPane childSplit = (NestedSplitPane)child; int loc = childSplit.getInnerDividerLocation(JSplitPane.HORIZONTAL_SPLIT, JSplitPane.LEFT, 0); //Recompute location from inner pane to this pane Point point = SwingUtilities.convertPoint(childSplit, loc, 0, this); int newLoc = point.x; return new Dimension(newLoc + child.getMinimumSize().width, originalMinimum.height); } else { int loc = getDividerLocation(); return new Dimension(loc + child.getMinimumSize().width, originalMinimum.height); } } else { //RIGHT Component child = getLeftComponent(); if (child instanceof NestedSplitPane && ((NestedSplitPane)child).getOrientation() == JSplitPane.HORIZONTAL_SPLIT) { NestedSplitPane childSplit = (NestedSplitPane)child; int loc = childSplit.getInnerDividerLocation(JSplitPane.HORIZONTAL_SPLIT, JSplitPane.RIGHT, 0); //Recompute location from inner pane to this pane Point point = SwingUtilities.convertPoint(childSplit, loc, 0, this); int newLoc = point.x; return new Dimension(getWidth() - newLoc + child.getMinimumSize().width, originalMinimum.height); } else { int loc = getDividerLocation(); return new Dimension(getWidth() - loc + child.getMinimumSize().width, originalMinimum.height); } } } if ((parent.getOrientation() == JSplitPane.VERTICAL_SPLIT) && (getOrientation() == JSplitPane.VERTICAL_SPLIT)) { //Check top if (JSplitPane.TOP.equals(parent.getChildConstraint(this))) { Component child = getBottomComponent(); if (child instanceof NestedSplitPane && ((NestedSplitPane)child).getOrientation() == JSplitPane.VERTICAL_SPLIT) { NestedSplitPane childSplit = (NestedSplitPane)child; int loc = childSplit.getInnerDividerLocation(JSplitPane.VERTICAL_SPLIT, JSplitPane.TOP, 0); //Recompute location from inner pane to this pane Point point = SwingUtilities.convertPoint(childSplit, 0, loc, this); int newLoc = point.y; return new Dimension(originalMinimum.width, newLoc + child.getMinimumSize().height); } else { int loc = getDividerLocation(); return new Dimension(originalMinimum.width, loc + child.getMinimumSize().height); } } else { //BOTTOM Component child = getTopComponent(); if (child instanceof NestedSplitPane && ((NestedSplitPane)child).getOrientation() == JSplitPane.VERTICAL_SPLIT) { NestedSplitPane childSplit = (NestedSplitPane)child; int loc = childSplit.getInnerDividerLocation(JSplitPane.VERTICAL_SPLIT, JSplitPane.BOTTOM, 0); //Recompute location from inner pane to this pane Point point = SwingUtilities.convertPoint(childSplit, 0, loc, this); int newLoc = point.y; return new Dimension(originalMinimum.width, getHeight() - newLoc + child.getMinimumSize().height); } else { int loc = getDividerLocation(); return new Dimension(originalMinimum.width, getHeight() - loc + child.getMinimumSize().height); } } } } return originalMinimum; } private String getChildConstraint (Component c) { if (getOrientation() == VERTICAL_SPLIT) { if (c == getTopComponent()) { return JSplitPane.TOP; } else if (c == getBottomComponent()) { return JSplitPane.BOTTOM; } } else { if (c == getLeftComponent()) { return JSplitPane.LEFT; } else if (c == getRightComponent()) { return JSplitPane.RIGHT; } } return null; } private void draggingFinishedTo(int location) { firePropertyChange("topDividerLocation", null, new Integer(location)); // NOI18N } /** Overriden to fix #45988 */ public void doLayout() { fixPreferredSizes(getSize()); super.doLayout(); } /** Whole method is just hacky fix of #45988. Pref sizes are kept in sync * to prevent JSplitPane's layout manager in JDK 1.5 to use minimum sizes */ private void fixPreferredSizes(Dimension availableSpace) { JComponent firstC = (JComponent)getLeftComponent(); JComponent secondC = (JComponent)getRightComponent(); if (firstC == null || secondC == null) { return; } Dimension firstPref = firstC.getPreferredSize(); Dimension secondPref = secondC.getPreferredSize(); Insets insets = getInsets(); boolean shouldFix = false; if (orientation == JSplitPane.HORIZONTAL_SPLIT) { int curPrefW = firstPref.width + secondPref.width + getDividerSize() + insets.left + insets.right; if (availableSpace.width < curPrefW) { shouldFix = true; firstPref.width = Math.max(0, firstPref.width - (curPrefW - availableSpace.width)); } } else { // Vertical split int curPrefH = firstPref.height + secondPref.height + getDividerSize() + insets.top + insets.bottom; if (availableSpace.height < curPrefH) { shouldFix = true; firstPref.height = Math.max(0, firstPref.height - (curPrefH - availableSpace.height)); } } if (shouldFix) { firstC.setPreferredSize(firstPref); } } // UI staff>> public void updateUI() { // Ensure there is the (special) value in UIDefaults. try { //Does not work on Plastic L&F via classname - plastic returns //something else for the class name that's not assignable //to NestedSplitPanelUI Object className = UIManager.getDefaults().get(uiClassID); if(className == null) { UIManager.getDefaults().put(uiClassID, "org.netbeans.core.windows.view.ui.NestedSplitPane$NestedSplitPaneUI"); // NOI18N } if (!"org.netbeans.core.windows.view.ui.NestedSplitPane$NestedSplitPaneUI".equals(className)) { // NOI18N //Avoid error on Plastic L&F that starts main window with no //contents - Tim setUI (new NestedSplitPaneUI()); } else { setUI((NestedSplitPaneUI)UIManager.getUI(this)); } revalidate(); } catch (Error e) { setUI (new NestedSplitPaneUI()); } } public String getUIClassID() { return uiClassID; } // UI staff<< // XXX It should be refined to 'interface'-like UI for NestedSplitPane and this one as a basic one. /** UI class for NestedSplitPane. * Only purpose of overriding the defaul is to get the event, when user starts * and finish dragging the split divider. */ public static class NestedSplitPaneUI extends BasicSplitPaneUI { /** Overriden, set our own defaults for dividers in addition to * superclass version. No border for dividers. */ public void installUI(JComponent c) { super.installUI(c); getDivider().setBorder(null); if ("GTK".equals(UIManager.getLookAndFeel().getID())) { ((JSplitPane) c).setDividerSize(2); } } protected void startDragging() { // Set temporary resize policy for left child if it is a split pane. Component c = splitPane.getLeftComponent(); if(c instanceof NestedSplitPane) { NestedSplitPane leftSplit = (NestedSplitPane)c; if(leftSplit.getOrientation() == splitPane.getOrientation()) { leftSplit.setTemporaryResizeWeight(0.0D); } } // Set temporary resize policy for right child if it is a split pane. c = splitPane.getRightComponent(); if(c instanceof NestedSplitPane) { NestedSplitPane rightSplit = (NestedSplitPane)c; if(rightSplit.getOrientation() == splitPane.getOrientation()) { rightSplit.setTemporaryResizeWeight(1.0D); } } super.startDragging (); } protected void finishDraggingTo(int location) { super.finishDraggingTo(location); ((NestedSplitPane)splitPane).draggingFinishedTo(location); } public static ComponentUI createUI(JComponent x) { return new NestedSplitPaneUI(); } /** Creates the default divider. Overrides superclass method */ public BasicSplitPaneDivider createDefaultDivider() { BasicSplitPaneDivider div = new NestedSplitPaneDivider(this); if (isXPLF()) { div.setBackground((Color)UIManager.get("nb_workplace_fill")); } return div; } /** Sublclassed to implement |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.