Package net.helipilot50.stocktrade.displayproject

Source Code of net.helipilot50.stocktrade.displayproject.PanelLayoutManager

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package net.helipilot50.stocktrade.displayproject;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JComponent;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

import net.helipilot50.stocktrade.displayproject.controls.Panel;
import net.helipilot50.stocktrade.framework.TextData;

import org.apache.log4j.Logger;

/**
* This class simulates the Forte panel with natural size policy and takes in consideration the
* margin or border
*
*/
public class PanelLayoutManager implements LayoutManager2, MoveListener {
    /**
     * A helper to aid with the layout
     */
    private LayoutManagerHelper helper = new LayoutManagerHelper();

    /**
     * A flag to indicate if anything has changed on this container
     */
    private boolean isDirty = false;

    /**
     * This is the size of a panel which has no visible children
     */
    protected static Dimension EMPTY_DIMENSION = new Dimension(0, 0);
    /**
     * A normal panel can be resized to be smaller than it's natural size, hiding some widgets
     * However, in some cases, such as panels that come from window forms, we need the smallest
     * size to be the natural size.
     */
    protected boolean isMinimumChildSizeEnforced = false;

    /**
     * The panel associate with this panel layout manager.
     */
//    private final Panel panel;
   
    private static Logger _log = Logger.getLogger(PanelLayoutManager.class);
    public PanelLayoutManager(){
        super();
//        this.panel = panel;
//        this.panel.putClientProperty("qqVirtalLoc", new Point(0, 0));
    }

    public PanelLayoutManager(boolean pIsMinimumChildSizeEnforced){
        this();
        this.isMinimumChildSizeEnforced = pIsMinimumChildSizeEnforced;
    }

    /**
     * The rules for panel layout are:
     * - A panel that is parented directly on the window form or is parented immediately
     *   inside a tab folder has a minimum size of it's natural size.
     */
    public void layoutContainer(Container parent) {
        if (_log.isDebugEnabled()) {
            Component[] comps = parent.getComponents();
            for ( int k = 0; k < comps.length; k++){
                if (!(comps[k].isVisible())) continue;
                _log.debug("Panel ["+ comps[k].getName() + "] :" +
                                            comps[k].getX() + ":" +
                                            comps[k].getY() + ":" +
                                            comps[k].getWidth() + ":" +
                                            comps[k].getHeight());
            }
        }
        performLayout(parent, true);
    }

    /**
     * Return the width of the caption of the parent, in pixels
     * @param parent
     * @return
     */
    private int getCaptionWidth(Container parent) {
        // calculate caption width if one exists
        int captionWidth = 0;
        if (parent instanceof Panel){
            Panel parentPanel = (Panel)parent;
            TextData tdCaption = parentPanel.getCaption();
            String caption = (tdCaption == null) ? "": tdCaption.toString();
            if ("".equals(caption)) {
                captionWidth = 0;
            }
            else {
                Font font = null;
                if (parentPanel.getCaptionFont() != null)
                    font = parentPanel.getCaptionFont();
                else
                    font = parentPanel.getFont();
                FontMetrics fm = parentPanel.getFontMetrics(font);
                // TF:21/8/07:Set the caption to be a little bigger to allow some dashes on the side.
                captionWidth = SwingUtilities.computeStringWidth(fm, caption) + 10;
            }
        }
        return captionWidth;
    }

private int adjustingDueToLayout = 0;
    /**
     * This calculates the minimum size of the panel based on visible components
     * and height and width policy. It returns the minimum size this component
     * can possibly be.
     */ 
    public Dimension performLayout(Container pParent, boolean pAdjustSizes) {
        // TF:21/8/07:We need to get the insets, but this will already cater for the border insets if needed
        Insets borderInsets = pParent.getInsets();
        //Insets borderInsets = LayoutManagerHelper.getBorderInsets(pParent);

boolean useOld = false;

        int widthPolicy = LayoutManagerHelper.getWidthPolicy(pParent);
        int heightPolicy = LayoutManagerHelper.getHeightPolicy(pParent);
        int minX = Integer.MAX_VALUE;
        int minY = Integer.MAX_VALUE;
        // These 2 variables hold the maximum X and Y location of the widgets minumum size.
        int maxMinimumX = 0;
        int maxMinimumY = 0;

        // These 2 variables hold the maximum X and Y location of the widgets current size. These
        // will never be less than maxMinimumX and maxMinimumY
        int maxCurrentX = 0;
        int maxCurrentY = 0;

        Component[] comps = pParent.getComponents();
        int visibleChildren = 0;

//        Point virtualLoc = pParent.getLocation();
//        Point actualLoc = pParent.getLocation();
//        if (pParent instanceof Panel) {
//          virtualLoc = ((Panel)pParent).getVirtualLocation();
//        }
       
        boolean ignoreInvisibleChildren = (pParent instanceof Panel) ? ((Panel)pParent).getIgnoreInvisibleChildren() : true;

        // The minimum size of a panel on a tab folder or form is the same as if it were natural
        boolean isMinSizeEnforced = pParent.getParent() == null || pParent.getParent() instanceof JTabbedPane ||
                                    isMinimumChildSizeEnforced;

        // TF:10/7/07: Ensured there is at least one visible child to prevent the calculation going haywire
        // theChild variable holds the last visited child, important if there is only one
        Component theChild = null;
        for ( int k = 0; k < comps.length; k++){
            // TF:2/10/07:Compensated for the ignoreInvisibleChildren flag
            if (ignoreInvisibleChildren && !(comps[k].isVisible())) {
                continue;
            }
            theChild = comps[k];
            if (theChild.isVisible()) {
                visibleChildren++;
            }

            if (theChild instanceof JComponent) {
                LayoutManagerHelper.makeDebugTooltip((JComponent)theChild);
            }

            int childX;
            int childY;
            if (useOld) {
              childX = theChild.getX();
              childY = theChild.getY();
            }
            else {
              Integer value = (Integer)((JComponent)theChild).getClientProperty("qq_XinPanel");
              childX = value == null ? theChild.getX() : value.intValue();
              value = (Integer)((JComponent)theChild).getClientProperty("qq_YinPanel");
              childY = value == null ? theChild.getY() : value.intValue();
            }
           
            Dimension minSize = LayoutManagerHelper.getMinimumSize(theChild);
            minX = Math.min(childX, minX);
            int compWidth = Math.max(theChild.getWidth(), minSize.width);
            maxMinimumX = Math.max(childX + minSize.width, maxMinimumX);
            maxCurrentX = Math.max(childX + compWidth, maxCurrentX);

            minY = Math.min(childY, minY);
            int compHeight = Math.max(theChild.getHeight(), minSize.height);
            maxMinimumY = Math.max(childY + minSize.height, maxMinimumY);
            maxCurrentY = Math.max(childY + compHeight, maxCurrentY);
        }

        // TF:21/9/07:The co-ordinates gathered so far include the border, which we have to remove
        // TF:28/04/2008:if there are no components, we don't need any of these sized
        if (theChild == null) {
          minX = minY = 0;
          maxMinimumX = maxMinimumY = 0;
          maxCurrentX = maxCurrentY = 0;
        }
        else {
          minX -= borderInsets.left;
          maxMinimumX -= borderInsets.left;
          maxCurrentX -= borderInsets.left;
          minY -= borderInsets.top;
          maxMinimumY -= borderInsets.top;
          maxCurrentY -= borderInsets.top;
        }
       
        // Now determine the appropriate width and height based on the sizing
        // policy of the widget under question.
        int naturalWidth = 0, naturalHeight = 0;
        int width = 0, height = 0;
        int minWidth = 0, minHeight = 0;
        // TF:26/07/2009:Added in Constants.SP_TO_PARENT
        if (widthPolicy == Constants.SP_NATURAL || widthPolicy == Constants.SP_TO_PARTNER || widthPolicy == Constants.SP_TO_PARENT || isMinSizeEnforced) {
            // Our size is the bounding box containing all the children plus the frame size if any plus margins.
            if ((ignoreInvisibleChildren && visibleChildren > 0) || (!ignoreInvisibleChildren && pParent.getComponentCount() > 0)) {
                naturalWidth = maxMinimumX - minX /*+ 1*/;
            }
            naturalWidth += borderInsets.left + borderInsets.right;
            // Add the border margins and panel margin twice (for both left and right margins)
            if (pParent instanceof Panel) {
                Panel aPanel = (Panel)pParent;
                naturalWidth += 2*aPanel.getMargin();

                // TF:02/03/2010:Compensate the locations by the difference between the real locations and the virtual locations
                //naturalWidth += actualLoc.x - virtualLoc.x;
            }
        }

        switch (widthPolicy) {
        case Constants.SP_NATURAL:
            minWidth = width = naturalWidth;
            break;

        case Constants.SP_TO_PARENT:
            // To parent size: our minimum is our border insets, but we can go up to the parent size
          // TF:26/07/2009:The minimum size of the panel is larger of the natural width and the borders
          // This condition about the tab panel is an issue for DET-103, but may just be eratic behaviour in Forte
            width = borderInsets.left + borderInsets.right;
            if (width < naturalWidth && !isMinSizeEnforced) {
              // TF:14/08/2009:This isn't correct in most cases, removed this change.
              //width = naturalWidth;
            }
            minWidth = width;
            if (width < pParent.getWidth()) {
                width = pParent.getWidth();
            }
            break;

        case Constants.SP_FORM:
            // We form a border around the panel the size of the minX component
            width = 2* minX + (maxCurrentX - minX);
            width += borderInsets.left + borderInsets.right;
            minWidth = width;
            if (width < pParent.getWidth()) {
                width = pParent.getWidth();
            }
            break;
           
        case Constants.SP_TO_PARTNER:
          // Our size is the size of the largest minimum size of us or our partners
            JComponent partner = LayoutManagerHelper.getWidthPartner((JComponent)pParent);
            width = minWidth = naturalWidth;
            while (partner != null && partner != pParent && partner.isVisible()) {
              // Need to perform this check to prevent infinite recursion
              if (partner.isMinimumSizeSet()) {
                  Dimension d = LayoutManagerHelper.getMinimumSizeWithoutPartners(partner);
                  if (d.width >width) {
                      width = d.width;
                  }
              }
                partner = LayoutManagerHelper.getWidthPartner(partner);
            }
          break;

        default:
            // We're using explicit, our size cannot change
            width = pParent.getWidth();
            minWidth = width;
        }
       
        // TF:29/04/2008:If we're a folder in a tab pane, we can leave our width wider than
        // normal, if it's already there. Otherwise, a grid which is sized to parent in a panel
        // which has natural size inside a tab folder will be the wrong size (too small)
        if (pParent.getParent() instanceof JTabbedPane) {
          if (pParent.getWidth() > width) {
            width = pParent.getWidth();
          }
        }
       
        // Width can also never shrink smaller than the title width
        int titleWidth = getCaptionWidth(pParent);
        // TF:2/10/07: Added a margin to make the titles look like forte
        if (minWidth < titleWidth + 8) {
            minWidth = titleWidth + 8;
        }
        if (isMinSizeEnforced) {
            // Tab folders have a size of the natural size + the offset of the child
            if (pParent.getParent() instanceof JTabbedPane) {
                naturalWidth += minX;
            }
            if (minWidth < naturalWidth) {
                minWidth = naturalWidth;
            }
        }
        // We can never shrink smaller than the min size
        if (pParent instanceof Panel) {
            int aMinWidth = ((Panel)pParent).getMinWidth();
            if (aMinWidth > width) {
                width = ((Panel)pParent).getMinWidth();
            }
            // TF:18/9/07:Separated this logic out as the width is not always the same as the minWidth
            if (aMinWidth > minWidth) {
                minWidth = aMinWidth;
            }
        }
        // Enforce the minimum width
        if (width < minWidth) {
            width = minWidth;
        }

        // Now repeat with height
        // TF:26/07/2009:Added in Constants.SP_TO_PARENT
        if (heightPolicy == Constants.SP_NATURAL || heightPolicy == Constants.SP_TO_PARTNER || heightPolicy == Constants.SP_TO_PARENT || isMinSizeEnforced) {
            // Our size is the bounding box containing all the children plus the frame size if any plus margins.
            if ((ignoreInvisibleChildren && visibleChildren > 0) || (!ignoreInvisibleChildren && pParent.getComponentCount() > 0)) {
                naturalHeight = maxMinimumY - minY /* + 1 */;
            }
            naturalHeight += borderInsets.top + borderInsets.bottom;
            // Add the border margins and panel margin twice (for both left and right margins)
            if (pParent instanceof Panel) {
                Panel aPanel = (Panel)pParent;
                naturalHeight += 2*aPanel.getMargin();

                // TF:02/03/2010:Compensate the locations by the difference between the real locations and the virtual locations
//                naturalHeight += actualLoc.y - virtualLoc.y;
            }
        }
        switch (heightPolicy) {
        case Constants.SP_NATURAL:
            minHeight = height = naturalHeight;
            break;

        case Constants.SP_TO_PARENT:
            // To parent size: our minimum is our border insets, but we can go up to the parent size
          // TF:26/07/2009:The minimum height of the panel is larger of the natural height and the borders
          // This condition about the tab panel is an issue for DET-103, but may just be eratic behaviour in Forte
            height = borderInsets.top + borderInsets.bottom;
            if (height < naturalHeight && !isMinSizeEnforced) {
              // TF:14/08/2009:This isn't correct in most cases, removed this change.
              // height = naturalHeight;
            }
            minHeight = height;
            if (height < pParent.getHeight()) {
                height = pParent.getHeight();
            }
            break;

        case Constants.SP_FORM:
            // We form a border around the panel the size of the minX component
            height = 2* minY + (maxCurrentY - minY);
            height += borderInsets.top + borderInsets.bottom;
            minHeight = height;
            if (height < pParent.getHeight()) {
                height = pParent.getHeight();
            }
            break;

        case Constants.SP_TO_PARTNER:
          // Our size is the size of the largest minimum size of us or our partners
            JComponent partner = LayoutManagerHelper.getHeightPartner((JComponent)pParent);
            width = minHeight = naturalHeight;
            while (partner != null && partner != pParent && partner.isVisible()) {
              // Need to perform this check to prevent infinite recursion
              if (partner.isMinimumSizeSet()) {
                  Dimension d = LayoutManagerHelper.getMinimumSizeWithoutPartners(partner);
                  if (d.height > height) {
                      height = d.height;
                  }
              }
                partner = LayoutManagerHelper.getHeightPartner(partner);
            }
          break;

        default:
            // We're using explicit, our size cannot change
            height = pParent.getHeight();
            minHeight = height;
        }
       
        // TF:29/04/2008:If we're a folder in a tab pane, we can leave our width wider than
        // normal, if it's already there. Otherwise, a grid which is sized to parent in a panel
        // which has natural size inside a tab folder will be the wrong size (too small)
        if (pParent.getParent() instanceof JTabbedPane) {
          if (pParent.getHeight() > height) {
            height = pParent.getHeight();
          }
        }
       
        // We can never shrink smaller than the min size
        if (pParent instanceof Panel) {
            int aMinHeight = ((Panel)pParent).getMinHeight();
            if (aMinHeight > height) {
                height = aMinHeight;
            }
            // TF:18/9/07:Separated this logic out as the height is not always the same as the minHeight
            if (aMinHeight > minHeight) {
                minHeight = aMinHeight;
            }
        }
        if (isMinSizeEnforced) {
            // Tab folders have a size of the natural size + the offset of the child
            if (pParent.getParent() instanceof JTabbedPane) {
                // The y-coordinate of a tab pane seems funny -- like it doesn't compensate for the
                // bottom 2 pixels of the drawing. If we don't add this "fudge factor" of 2 in, we'll
                // draw over the bottom part of the panel. (This doesn't seem to happen on the width)
                naturalHeight += minY + 2;
            }
            if (minHeight < naturalHeight) {
                minHeight = naturalHeight;
            }
        }
        // Enforce the minimum height
        if (height < minHeight) {
            height = minHeight;
        }

        // TF:06/11/2008:Added in a new change which can force layouts to be performed, as we were missing some...
        if ((widthPolicy == Constants.SP_NATURAL && pParent.getWidth() != naturalWidth) ||
            (heightPolicy == Constants.SP_NATURAL && pParent.getHeight() != naturalHeight)) {
          isDirty = true;
        }
         
        // Now, if this component has changed, we need to resize properly
        // TF:16/8/07:Optimisation -- if nothing has changed, no need to layout
        if (pAdjustSizes && (isDirty || helper.isChanged())) {
//        if (pAdjustSizes) {
            isDirty = false;
            helper.populateChangeInformation(pParent);

            LayoutManagerHelper.setDebugBackgroundColor(pParent);

            Dimension compMinSize = pParent.getMinimumSize();
            Dimension compCurrSize = pParent.getSize();
            boolean sizeAdjusted = false;
            if (compMinSize.height > compCurrSize.height) {
                compCurrSize.height = compMinSize.height;
                sizeAdjusted = true;
            }
            if (compMinSize.width > compCurrSize.width) {
                compCurrSize.width = compMinSize.width;
                sizeAdjusted = true;
            }
           
            // Adjust the location of the kids if we need to
            adjustingDueToLayout++;
            if ((ignoreInvisibleChildren && visibleChildren > 0) || (!ignoreInvisibleChildren && pParent.getComponentCount() > 0)) {
                for ( int k = 0; k < comps.length; k++){
                    // TF:2/10/07:Compensated for the ignoreInvisibleChildren flag
                    if (ignoreInvisibleChildren && !(comps[k].isVisible())) {
                        continue;
                    }

                    LayoutManagerHelper.makeDebugTooltip((JComponent)comps[k]);

                    int newX = comps[k].getX();
                    int newY = comps[k].getY();
                    int newWidth = comps[k].getWidth();
                    int newHeight = comps[k].getHeight();
                    // Adjust the location based on this component, a policy of NATURAL can affect it's
                    // location as the parent component effectively "shrinks" around these components
                    if (widthPolicy == Constants.SP_NATURAL) {
                        // TF:2/10/08:We've already adjusted the minX for the border but not the current X, so don't re-do it.
                        // ie it's really:
                        //  newX = comps[k].getX() - (minX + borderInsets.left) + borderInsets.left;
            if (useOld) {
              newX = comps[k].getX() - minX;
            }
            else {
              newX = ((Integer)(((JComponent)comps[k]).getClientProperty("qq_XinPanel"))).intValue() - minX;
            }
                        if (pParent instanceof Panel) {
                          // TF:03/03/2010:compensate the panel location if we need to
                            newX += ((Panel)pParent).getMargin();
                        }
                    }
                    else {
                      // We need to adjust the new location by the border and the margin
                      newX = virtualToRealX(comps[k]);
                    }
                   
                    if (heightPolicy == Constants.SP_NATURAL) {
                        // TF:2/10/08:We've already adjusted the minY like above for minX
            if (useOld) {
              newY = comps[k].getY() - minY;
            }
            else {
              newY = ((Integer)(((JComponent)comps[k]).getClientProperty("qq_YinPanel"))).intValue() - minY;
            }
                        if (pParent instanceof Panel) {
                            newY += ((Panel)pParent).getMargin();
                        }
                    }
                    else {
                      newY = virtualToRealY(comps[k]);
                    }

                    if (widthPolicy == Constants.SP_FORM) {
                        // If there's only 1 child and it's resizable we size it to us
                        if (visibleChildren == 1 && LayoutManagerHelper.getWidthPolicy(comps[k]) == Constants.SP_TO_PARENT) {
                            newWidth = width - borderInsets.left - borderInsets.right - 2 * minX;
                        }
                    }
                    else if (LayoutManagerHelper.getWidthPolicy(comps[k]) == Constants.SP_TO_PARENT) {
                        // We need to resize this component to our size less our margins
                        // TF:20/9/07:Catered for the borders around the components too
                        newWidth = width - borderInsets.left - borderInsets.right - minX * 2;
                        newX = borderInsets.left + minX;
                    }
                    if (heightPolicy == Constants.SP_FORM) {
                        // If there's only 1 child and it's resizable we size it to us
                        if (visibleChildren == 1 && LayoutManagerHelper.getHeightPolicy(comps[k]) == Constants.SP_TO_PARENT) {
                            newHeight = height - borderInsets.top - borderInsets.bottom - 2 * minY;
                        }
                    }
                    else if (LayoutManagerHelper.getHeightPolicy(comps[k]) == Constants.SP_TO_PARENT) {
                        // We need to resize this component to our size less our margins
                        // TF:20/9/07:Catered for the borders around the components too
                        newHeight = height - borderInsets.top - borderInsets.bottom - minY * 2;
                        newY = borderInsets.top + minY;
                    }

                    // TF:21/9/07: We can never shrink any component less than it's minimum size
                    Dimension minSize = LayoutManagerHelper.getMinimumSize(comps[k]);
                    newWidth = Math.max(newWidth, minSize.width);
                    newHeight = Math.max(newHeight, minSize.height);
                    if (comps[k].getX() != newX || comps[k].getY() != newY ||
                            comps[k].getWidth() != newWidth || comps[k].getHeight() != newHeight) {

                        comps[k].setBounds(newX, newY, newWidth, newHeight);
                        LayoutManagerHelper.setPartnerSizes(comps[k]);
                    }
                }
            }
            adjustingDueToLayout--;

            // TF:20/9/07: We must set the sizes AFTER doing our children, otherwise it is possible to get into a situation
            // where the sizing of the parent affects the location of the children (if they're say grid fields and they
            // re-layout as a result of the parent size changing) and this can then move the children, invalidating our
            // calculated minX and minY, resulting in moving the child too far
            Dimension newSize = new Dimension(width, height);
            boolean hasChanged = false;
            if (!newSize.equals(compCurrSize) || sizeAdjusted) {
                pParent.setSize(newSize);
                pParent.setPreferredSize(newSize);
                hasChanged = true;
            }

            // TF:14/11/07:Added the check for isMinimumSizeSet() on the condition. This is needed so that
            // a change event is triggered. If we have a grid field as a parent, we need to fire this event
            // when our minimum size has changed. If the minimum size has never been set, this will call
            // PanelLayoutManager.minimumLayoutSize() to get the minimum size and will never fire this event
            if (compMinSize.width != minWidth || compMinSize.height != minHeight || !pParent.isMinimumSizeSet()) {
                pParent.setMinimumSize(new Dimension(minWidth, minHeight));
                hasChanged = true;
            }

            // TF:21/9/07: We don't need to tell a grid field to re-layout itself as it will be listening for us re-sizing anyway
            Container grandMa = pParent.getParent();
            if (hasChanged && grandMa != null && (!grandMa.isValid())&& !(grandMa.getLayout() instanceof GridFieldLayout)){
                grandMa.doLayout();
            }
//            helper.populateChangeInformation(pParent);
            isDirty = false;
        }

        Dimension size = new Dimension(minWidth, minHeight);
        return size;
    }

    public Dimension preferredLayoutSize(Container parent) {
        return minimumLayoutSize(parent);
    }

    private ComponentAdapter moveAdapter = new ComponentAdapter() {
      public void componentMoved(ComponentEvent e) {
        if (e.getComponent() instanceof JComponent) {
          JComponent comp = (JComponent)e.getComponent();
            comp.putClientProperty("virtualX", realToVirtualX(comp));
            comp.putClientProperty("virtualY", realToVirtualY(comp));
           
//            if (adjustingDueToLayout == 0) {
//                    comp.putClientProperty("qq_XinPanel", Integer.valueOf(comp.getX()));
//                    comp.putClientProperty("qq_YinPanel", Integer.valueOf(comp.getY()));
//            }
        }
      }
    };
   
    public void componentMoved(Component component) {
      if (component instanceof JComponent && component.getParent() != null && component.getParent().getLayout() == this) {
        // This is one of our children, and it's just been moved.
        JComponent comp = (JComponent)component;
        comp.putClientProperty("virtualX", realToVirtualX(comp));
        comp.putClientProperty("virtualY", realToVirtualY(comp));       
            comp.putClientProperty("qq_XinPanel", Integer.valueOf(comp.getX()));
            comp.putClientProperty("qq_YinPanel", Integer.valueOf(comp.getY()));
      }
    }
    public void removeLayoutComponent(Component comp) {
      // TF:02/03/2010:Added code to ensure the adapter was removed from the component
      comp.removeComponentListener(moveAdapter);
        helper.removeLayoutComponent(comp);
    }

    public void addLayoutComponent(String name, Component comp) {
      // Do nothing, this method should never get called.
    }

    public void addLayoutComponent(Component comp, Object constraint) {
        if (comp instanceof JComponent) {
            if (constraint instanceof GridBagConstraints) {
                // We must merge the new parts from the constraints against the existing cell. For example, if the field
                // is a grid field, it can have it's own constraints from having properties set on it such as height and
                // width policies. When it's added to it's parent grid, it's added with the values from the GridBagConstraints
                // so we must pick and choose which ones we really want.
                GridCell cell = GridField.getConstraints((JComponent)comp);
                GridCell newCell = new GridCell((GridBagConstraints)constraint);
                cell.merge(newCell);
                GridField.setConstraints((JComponent)comp, cell);
            }
            else if (constraint instanceof GridCell) {
                GridField.setConstraints((JComponent)comp, (GridCell)constraint);
            }
            // TF:05/11/2008:We need to add in the X and Y location as set. The actual location will be compensated for
            // by the border and title height and margins, but we want to be able to know what the original X and Y location
            // were so we can compensate for these.
            ((JComponent) comp).putClientProperty("virtualX", Integer.valueOf(comp.getX()));
            ((JComponent) comp).putClientProperty("virtualY", Integer.valueOf(comp.getY()));
//            comp.addComponentListener(moveAdapter);
           
            // When we add a component to the panel, we need to compensate it's location for what they will be within the panel.
            // For example, a Line could be inserted from -2000, 0 to 2000, 10 into a panel which currently has a size of 0 to 1000
            // In this case, the panel would need to expand to 4000mils, shift it's origin to -2000 (but remembering as it's "virtual"
            // origin 0) and then re-locate each of it's children up by 2000 to compensate for the shift in origin. This is only
            // necessary for NATURAL panels as the others do not shift their origins
            ((JComponent) comp).putClientProperty("qq_XinPanel", Integer.valueOf(comp.getX()));
            ((JComponent) comp).putClientProperty("qq_YinPanel", Integer.valueOf(comp.getY()));
//            Point virtualLocOffsets = (Point)this.panel.getClientProperty("qqVirtalLoc");
//            if (virtualLocOffsets == null) {
//              // Simple case where we haven't inserted an object yet.
//              virtualLocOffsets = new Point();
//              this.panel.putClientProperty("qqVirtualLoc", virtualLocOffsets);
//              virtualLocOffsets.x = comp.getX();
//              virtualLocOffsets.y = comp.getY();
//            }
//            else {
//              int xDelta = 0, yDelta = 0;
//              if (comp.getX() < virtualLocOffsets.x) {
//                xDelta = virtualLocOffsets.x - comp.getX();
//                virtualLocOffsets.x = comp.getX();
//               
//                // Need to shift all components left by xDelta components
//              }
//             
//             
//            }
        }
    }

    /**
     * Map a "virtual" X location to the real screen coordinates. The virtual location refers to the location within
     * the internal borders of the panel, compensating for title, borders and margins. For example, a widget at
     * the top left hand corner of a panel, just inside it's border of 13 pixels would have a virtual location of
     * 0,0 but a real location of 13,13
     * @param comp
     * @return
     */
    private int virtualToRealX(Component comp) {
      Container container = comp.getParent();
      if (container instanceof Panel && comp instanceof JComponent) {
        Panel panel = (Panel)container;
        Insets insets = panel.getInsets();
        Integer virtualXObj = (Integer)((JComponent)comp).getClientProperty("virtualX");
        if (virtualXObj != null) {
          int virtualX = virtualXObj.intValue() + insets.left + panel.getMargin();
          return virtualX;
        }
      }
    return comp.getX();
    }

    /**
     * Map a "virtual" Y location to the real screen coordinates. The virtual location refers to the location within
     * the internal borders of the panel, compensating for title, borders and margins. For example, a widget at
     * the top left hand corner of a panel, just inside it's border of 13 pixels would have a virtual location of
     * 0,0 but a real location of 13,13
     * @param comp
     * @return
     */
    private int virtualToRealY(Component comp) {
      Container container = comp.getParent();
      if (container instanceof Panel && comp instanceof JComponent) {
        Panel panel = (Panel)container;
        Insets insets = panel.getInsets();
        Integer virtualYObj = (Integer)((JComponent)comp).getClientProperty("virtualY");
        if (virtualYObj != null) {
          int virtualY = virtualYObj.intValue() + insets.top + panel.getMargin();
          return virtualY;
        }
      }
    return comp.getY();
    }
   
    /**
     * Map a "real" X location to the virtual control coordinates. The virtual location refers to the location within
     * the internal borders of the panel, compensating for title, borders and margins. For example, a widget at
     * the top left hand corner of a panel, just inside it's border of 13 pixels would have a virtual location of
     * 0,0 but a real location of 13,13
     * @param comp
     * @return
     */
    private int realToVirtualX(JComponent comp) {
      Container container = comp.getParent();
      if (container instanceof Panel) {
        Panel panel = (Panel)container;
        Insets insets = panel.getInsets();
        return comp.getX() - insets.left - panel.getMargin();
      }
    return comp.getX();
    }

    /**
     * Map a "real" Y location to the virtual control coordinates. The virtual location refers to the location within
     * the internal borders of the panel, compensating for title, borders and margins. For example, a widget at
     * the top left hand corner of a panel, just inside it's border of 13 pixels would have a virtual location of
     * 0,0 but a real location of 13,13
     * @param comp
     * @return
     */
    private int realToVirtualY(JComponent comp) {
      Container container = comp.getParent();
      if (container instanceof Panel) {
        Panel panel = (Panel)container;
        Insets insets = panel.getInsets();
        return comp.getY() - insets.top - panel.getMargin();
      }
    return comp.getY();
    }
   
    public float getLayoutAlignmentX(Container target) {
        return 0;
    }

    public float getLayoutAlignmentY(Container target) {
        return 0;
    }

    public void invalidateLayout(Container target) {
    }

    public Dimension maximumLayoutSize(Container target) {
        return null;
    }

    public Dimension minimumLayoutSize(Container parent) {
        return performLayout(parent, false);
    }
}
TOP

Related Classes of net.helipilot50.stocktrade.displayproject.PanelLayoutManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.