Package gov.nasa.arc.mct.plot.settings

Source Code of gov.nasa.arc.mct.plot.settings.PlotControlsLayout

/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package gov.nasa.arc.mct.plot.settings;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JComponent;
import javax.swing.JScrollPane;

/**
* This layout manager allows a lower panel to remain visible and on top of a middle panel
* when the parent cannot accommodate the heights of both. It also allows the lower panel to
* remain adjacent to the middle panel when the parent has more height than its children require.
*/

public class PlotControlsLayout implements LayoutManager2 {

  /**
   * This scroll pane class provides a convenient way to access the resizeable components
   * that reside in this scroll pane, eliminating a search.
   */
  @SuppressWarnings("serial")
  public static class ResizersScrollPane extends JScrollPane {

    private JComponent[] resizers;

    public ResizersScrollPane(JComponent component, JComponent... resizerWidget) {
      super(component);
      int numResizers = resizerWidget.length;
      resizers = new JComponent[numResizers];
      for (int k = 0; k < numResizers; k++) {
        resizers[k] = resizerWidget[k];
      }
    }

    public JComponent[] getResizers() {
      return resizers;
    }
  }

  private static final int DEFAULT_PADDING = 0;
  public static final String MIDDLE = "Middle";
  public static final String LOWER = "Lower";

  private int minWidth = 0;
  private int minHeight = 0;
  private boolean sizeUnknown = true;
  private int preferredWidth;
  private int preferredHeight;
  /*
   * The padding between the middle panel and the lower panel
   */
  private int innerPadding = 0;
  private Component middleComponent;
  private Component lowerComponent;


  public PlotControlsLayout() {
    this(DEFAULT_PADDING);
  }

  public PlotControlsLayout(int padding) {
    innerPadding = padding;
  }

  /*
   * LayoutManager2
   * NOTE: there is another method with same name in LayoutManager
   */
  @Override
  public void addLayoutComponent(final Component comp, Object constraints) {
    if (constraints instanceof String) {
      String name = (String) constraints;
      if (MIDDLE.equals(name)) {
        middleComponent = comp;
        if (comp instanceof ResizersScrollPane) {
          final JComponent parent = (JComponent) comp.getParent();
          JComponent[] children = ((ResizersScrollPane) comp).getResizers();
          for (JComponent child : children) {
            if (child.getComponentListeners().length == 0) {
              child.addComponentListener(new ComponentListener() {
                @Override
                public void componentResized(ComponentEvent e) {
                  parent.revalidate();
                }
 
                @Override
                public void componentShown(ComponentEvent e) {
                }
                @Override
                public void componentMoved(ComponentEvent e) {
                }
                @Override
                public void componentHidden(ComponentEvent e) {
                }
              });
            }
          }
        }
      } else
        if (LOWER.equals(name)) {
          lowerComponent = comp;
        } else {
          throw new IllegalArgumentException("Cannot use unknown constraint in layout: " + name);
        }
    }
  }
   
  /* LayoutManager2 */
  @Override
    public float getLayoutAlignmentX(Container target) {
      return 0.5f;
    }

  /* LayoutManager2 */
  @Override
    public float getLayoutAlignmentY(Container target) {
      return 0.5f;
    }

  /* LayoutManager2 */
  @Override
    public void invalidateLayout(Container target) {
    }

  /* LayoutManager2 */
  @Override
    public Dimension maximumLayoutSize(Container target) {
    if (sizeUnknown) {
      setSizes(target);
    }
      return new Dimension(preferredWidth, preferredHeight);
    }

  /*
   * LayoutManager
   * NOTE: another method with same name in LayoutManager2
   */
  @Override
    public void addLayoutComponent(String name, Component comp) {
    }

  /* LayoutManager */
    /*
     * This is called when the panel is first displayed, and every time its size changes.
     * Note: You can't assume preferredLayoutSize or minimumLayoutSize will be called.
     */
  @Override
    public void layoutContainer(Container parent) {
        if (sizeUnknown) {
          setSizes(parent);
        }

        if (middleComponent != null && lowerComponent != null ) {
          doLayout(parent, middleComponent, lowerComponent);
        } else
          if (middleComponent != null) {
            middleComponent.setBounds(0, 0, parent.getSize().width, middleComponent.getPreferredSize().height);
          } else
            if (lowerComponent != null) {
              lowerComponent.setBounds(0, 0, parent.getSize().width, lowerComponent.getPreferredSize().height);
            }
    }

  private void doLayout(Container parent, Component middleComp, Component lowerComp) {
      Dimension parentDim = parent.getSize();
      Dimension middleDim = middleComp.getPreferredSize();
      Dimension lowerDim = lowerComp.getPreferredSize();

      // In the following, the middle component is a scroll pane and the lower component is a panel.
      // a) The widths of both the scroll pane and the panel are expanded to the width of the parent
      // b) Maintain a buffer (INNER_PADDING) between the scroll pane and the panel
      // c) The panel is positioned at the bottom of the parent, and is allowed its preferred height
      // d) The scroll pane shrinks to fit the remaining space after the panel and buffer are handled

      // Does the parent have enough space for both components ?
      if (middleDim.height + lowerDim.height + innerPadding < parentDim.height) {
        // If so, position the scroll pane at the top of the parent
        middleComp.setBounds(0, 0, parentDim.width, middleDim.height);
        lowerComp.setBounds(0, middleDim.height + innerPadding - 1, parentDim.width, lowerDim.height);
      } else {
        // If not, shrink the height of the scroll pane, and ensure the panel is completely visible
        // as long as possible while parent shrinks.
        int overlapY = middleDim.height + lowerDim.height + innerPadding - parentDim.height;
        middleComp.setBounds(0, 0, parentDim.width, middleDim.height - overlapY);
        lowerComp.setBounds(0, middleDim.height + innerPadding - overlapY - 1, parentDim.width, lowerDim.height);
        parent.setComponentZOrder(lowerComp, 0);
      }
    }

  /* LayoutManager */
  @Override
    public Dimension minimumLayoutSize(Container parent) {
    if (sizeUnknown) {
      setSizes(parent);
    }
        Dimension dim = new Dimension(0, 0);

        // Always add the container's insets
        Insets insets = parent.getInsets();
        dim.width = minWidth + insets.left + insets.right;
        dim.height = minHeight + insets.top + insets.bottom;
        return dim;
    }

  /* LayoutManager */
  @Override
    public Dimension preferredLayoutSize(Container parent) {
    if (sizeUnknown) {
      setSizes(parent);
    }
        Dimension dim = new Dimension(0, 0);

        // Always add the container's insets
        Insets insets = parent.getInsets();
        dim.width = preferredWidth + insets.left + insets.right;
        dim.height = preferredHeight + insets.top + insets.bottom;
        return dim;
    }

  private void setSizes(Container parent) {
      int nComps = parent.getComponentCount();

        // Reset preferred/minimum width and height.
        preferredWidth = 0;
        preferredHeight = 0;
        minWidth = 0;
        minHeight = 0;

        for (int i = 0; i < nComps; i++) {
            Component comp = parent.getComponent(i);
            if (comp.isVisible()) {
                Dimension prefSize = comp.getPreferredSize();

                preferredWidth = (prefSize.width > preferredWidth) ? prefSize.width : preferredWidth;
                preferredHeight += prefSize.height;

                minWidth = Math.max(comp.getMinimumSize().width, minWidth);
                minHeight += comp.getMinimumSize().height;
            }
        }
        sizeUnknown = false;
    }

  /* LayoutManager */
  @Override
    public void removeLayoutComponent(Component comp) {
    if (comp == middleComponent) {
      middleComponent = null;
    } else
      if (comp == lowerComponent) {
        lowerComponent = null;
      }
    }

  void resetSizeFlag() {
    sizeUnknown = true;
  }

}
TOP

Related Classes of gov.nasa.arc.mct.plot.settings.PlotControlsLayout

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.