--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/visual-panels/core/src/java/util/com/oracle/solaris/vp/util/swing/layout/UniformLayout.java Thu May 24 04:16:47 2012 -0400
@@ -0,0 +1,359 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package com.oracle.solaris.vp.util.swing.layout;
+
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.border.LineBorder;
+
+public class UniformLayout extends AbstractLayout {
+ //
+ // Enums
+ //
+
+ public enum Orientation {
+ HORIZONTAL,
+ VERTICAL,
+ }
+
+ public enum FillPolicy {
+ RESIZE_COMPONENTS,
+ RESIZE_GAPS,
+ }
+
+ //
+ // Instance data
+ //
+
+ private int gap;
+ private Orientation o;
+ private FillPolicy policy;
+
+ //
+ // Constructors
+ //
+
+ /**
+ * Constructs a {@code UniformLayout} with the given orientation, gap,
+ * and fill policy.
+ *
+ * @param o
+ * the orientation to use when positioning Components
+ *
+ * @param gap
+ * the gap between each Component
+ *
+ * @param policy
+ * the fill policy, if the Container is longer than necessary
+ */
+ public UniformLayout(Orientation o, int gap, FillPolicy policy) {
+ this.o = o;
+ this.gap = gap;
+ this.policy = policy;
+ }
+
+ /**
+ * Constructs a {@code UniformLayout} with the given orientation and
+ * gap, and the default fill policy (FillPolicy.RESIZE_COMPONENTS).
+ *
+ * @param o
+ * the orientation to use when positioning Components
+ *
+ * @param gap
+ * the gap between each Component
+ */
+ public UniformLayout(Orientation o, int gap) {
+ this(o, gap, FillPolicy.RESIZE_COMPONENTS);
+ }
+
+ /**
+ * Constructs a {@code UniformLayout} with the given orientation and
+ * the default gap (0) and fill policy (FillPolicy.RESIZE_COMPONENTS).
+ *
+ * @param o
+ * the orientation to use when positioning Components
+ */
+ public UniformLayout(Orientation o) {
+ this(o, 0);
+ }
+
+ /**
+ * Constructs a {@code UniformLayout} with the default orientation
+ * (Orientation.HORIZONTAL), gap (0), and fill policy
+ * (FillPolicy.RESIZE_COMPONENTS).
+ */
+ public UniformLayout() {
+ this(Orientation.HORIZONTAL);
+ }
+
+ /**
+ * Constructs a {@code UniformLayout} with the given gap, and the default
+ * orientation (Orientation.HORIZONTAL) and fill policy
+ * (FillPolicy.RESIZE_COMPONENTS).
+ */
+ public UniformLayout(int gap) {
+ this(Orientation.HORIZONTAL, gap);
+ }
+
+ //
+ // LayoutManager methods
+ //
+
+ @Override
+ public void layoutContainer(Container container) {
+ Insets insets = translate(container.getInsets());
+ Dimension cSize = translate(container.getSize());
+
+ // The amount of space we have to work with
+ int cWidth = cSize.width - insets.left - insets.right;
+ int cHeight = cSize.height - insets.top - insets.bottom;
+
+ // Weed out invisible Components
+ Component[] comps = getLayoutComponents(container.getComponents());
+
+ // Preferred size of each Component
+ Dimension pSize = translate(getComponentSize(comps, true));
+
+ FillPolicy policy = getFillPolicy();
+
+ int gap = getGap();
+ int[] widths = new int[comps.length];
+ int[] gaps = new int[comps.length];
+
+ // Total width
+ int tWidth = 0;
+ for (int i = 0; i < comps.length; i++) {
+ widths[i] = pSize.width;
+ gaps[i] = i == 0 ? 0 : gap;
+ tWidth += widths[i] + gaps[i];
+ }
+
+ // Excess/insufficient space
+ int extra = cWidth - tWidth;
+ if (extra != 0) {
+ if (extra < 0) {
+ distributeSpace(extra, widths, null);
+ } else {
+ switch (policy) {
+ default:
+ case RESIZE_COMPONENTS:
+ distributeSpace(extra, widths, null);
+ break;
+
+ case RESIZE_GAPS:
+ float[] weights = new float[gaps.length];
+ for (int i = 1; i < comps.length; i++) {
+ weights[i] = 1;
+ }
+ distributeSpace(extra, gaps, weights);
+ break;
+ }
+ }
+ }
+
+ int left = insets.left;
+
+ // Lay out components
+ for (int i = 0; i < comps.length; i++) {
+ left += gaps[i];
+
+ comps[i].setBounds(translate(new Rectangle(
+ left, 0, widths[i], cHeight)));
+ left += widths[i];
+ }
+ }
+
+ //
+ // AbstractLayout methods
+ //
+
+ @Override
+ protected Dimension getLayoutSize(Container container, boolean preferred) {
+ Component[] components = getLayoutComponents(container.getComponents());
+ Insets insets = container.getInsets();
+
+ int width = insets.left + insets.right;
+ int height = insets.top + insets.bottom;
+
+ Dimension size = getComponentSize(components, preferred);
+
+ switch (getOrientation()) {
+ default:
+ case HORIZONTAL:
+ width += components.length * size.width +
+ (components.length - 1) * getGap();
+ height += size.height;
+ break;
+
+ case VERTICAL:
+ height += components.length * size.height +
+ (components.length - 1) * getGap();
+ width += size.width;
+ break;
+ }
+
+ return new Dimension(width, height);
+ }
+
+ @Override
+ protected boolean needsLayout(Component c) {
+ return c != null && c.isVisible();
+ }
+
+ //
+ // UniformLayout methods
+ //
+
+ public int getGap() {
+ return gap;
+ }
+
+ public FillPolicy getFillPolicy() {
+ return policy;
+ }
+
+ public Orientation getOrientation() {
+ return o;
+ }
+
+ //
+ // Private methods
+ //
+
+ private Dimension getComponentSize(Component[] components,
+ boolean preferred) {
+
+ int width = 0;
+ int height = 0;
+ for (int i = 0; i < components.length; i++) {
+ if (components[i].isVisible()) {
+ Dimension s = preferred ?
+ components[i].getPreferredSize() :
+ components[i].getMinimumSize();
+ width = Math.max(width, s.width);
+ height = Math.max(height, s.height);
+ }
+ }
+ return new Dimension(width, height);
+ }
+
+ private Dimension translate(Dimension d) {
+ switch (getOrientation()) {
+ default:
+ case HORIZONTAL:
+ return d;
+
+ case VERTICAL:
+ return new Dimension(d.height, d.width);
+ }
+ }
+
+ private Insets translate(Insets i) {
+ switch (getOrientation()) {
+ default:
+ case HORIZONTAL:
+ return i;
+
+ case VERTICAL:
+ return new Insets(i.left, i.top, i.right, i.bottom);
+ }
+ }
+
+ private Rectangle translate(Rectangle r) {
+ switch (getOrientation()) {
+ default:
+ case HORIZONTAL:
+ return r;
+
+ case VERTICAL:
+ return new Rectangle(r.y, r.x, r.height, r.width);
+ }
+ }
+
+ //
+ // Static methods
+ //
+
+ /**
+ * Unit test/example usage.
+ */
+ public static void main(String[] args) {
+ Orientation[] orients = {
+ Orientation.HORIZONTAL,
+ Orientation.VERTICAL,
+ };
+
+ FillPolicy[] policies = {
+ FillPolicy.RESIZE_COMPONENTS,
+ FillPolicy.RESIZE_GAPS,
+ };
+
+ JFrame frame = new JFrame();
+ Container contentPane = frame.getContentPane();
+ contentPane.setBackground(new Color(
+ (int)(Math.random() * 256),
+ (int)(Math.random() * 256),
+ (int)(Math.random() * 256)));
+ frame.setLayout(
+ new GridLayout(orients.length, policies.length, 15, 15));
+
+ for (int i = 0; i < orients.length; i++) {
+ for (int j = 0; j < policies.length; j++) {
+ UniformLayout layout =
+ new UniformLayout(orients[i], 0, policies[j]);
+
+ JPanel p = new JPanel(layout);
+ p.setBackground(new Color(
+ (int)(Math.random() * 256),
+ (int)(Math.random() * 256),
+ (int)(Math.random() * 256)));
+
+ char[] c = new char[] {'a', 'b', 'c', 'd'};
+ String text = "";
+ for (int k = 0; k < c.length; k++) {
+ if (k != 0) {
+ text += "\n";
+ }
+ for (int l = 0; l < k; l++) {
+ text += c[l];
+ }
+ JComponent comp = new JTextArea(text);
+ comp.setBorder(new LineBorder(Color.black, 1));
+ p.add(comp);
+ }
+
+ contentPane.add(p);
+ }
+ }
+
+// frame.pack();
+ GraphicsEnvironment env =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ Rectangle bounds = env.getMaximumWindowBounds();
+ frame.setSize(bounds.width, bounds.height);
+ frame.setVisible(true);
+ }
+}