/* * ScrollLayout.java * :tabSize=4:indentSize=4:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2004 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gjt.sp.jedit.textarea; //{{{ Imports import java.awt.*; import javax.swing.border.Border; import javax.swing.JComponent; //}}} /** * Similar to a javax.swing.ScrollPaneLayout, but not as restrictive on the * components that can be added. This layout is essentially a 3 x 3 grid layout, * with the intent that the bottom and right will hold scroll bars. When installed * a TextArea, the bottom has a scroll bar, the right has a vertical box containing * a scroll bar, the left has a Gutter, and the center holds a TextAreaPainter. * The corners and top are not used by the TextArea. * * The corners are intended to be a place to put a button or other small component. * The corner dimensions are constrained by the left, right, top, and bottom * components, so, for example, the width of the top left corner is the width * of the left component and the height of the top left corner is the height of * the top component. */ public class ScrollLayout implements LayoutManager { public static final String CENTER = "center"; public static final String RIGHT = "right"; public static final String LEFT = "left"; public static final String BOTTOM = "bottom"; public static final String TOP = "top"; public static final String TOP_LEFT = "topLeft"; public static final String TOP_RIGHT = "topRight"; public static final String BOTTOM_LEFT = "bottomLeft"; public static final String BOTTOM_RIGHT = "bottomRight"; //{{{ addLayoutComponent() method /** * Adds a component to the layout using the <code>name</code> parameter to * position the component. * @param name One of CENTER, RIGHT, LEFT, BOTTOM, TOP, TOP_LEFT, TOP_RIGHT, * BOTTOM_LEFT, BOTTOM_RIGHT. * @param comp The component to add at the given position. If <code>null</code>, the * component will be removed from that position. */ public void addLayoutComponent(String name, Component comp) { switch(name) { case CENTER: center = comp; break; case RIGHT: right = comp; break; case LEFT: left = comp; break; case BOTTOM: bottom = comp; break; case TOP: top = comp; break; case TOP_LEFT: topLeft = comp; break; case TOP_RIGHT: topRight = comp; break; case BOTTOM_LEFT: bottomLeft = comp; break; case BOTTOM_RIGHT: bottomRight = comp; break; } } //}}} //{{{ removeLayoutComponent() method /** * Removes the specified component from the layout. * @param comp The component to be removed. */ public void removeLayoutComponent(Component comp) { if(center == comp) center = null; else if(right == comp) right = null; else if(left == comp) left = null; else if(bottom == comp) bottom = null; else if(top == comp) top = null; else if(topLeft == comp) topLeft = null; else if(topRight == comp) topRight = null; else if(bottomLeft == comp) bottomLeft = null; else if(bottomRight == comp) bottomRight = null; } //}}} //{{{ preferredLayoutSize() method public Dimension preferredLayoutSize(Container parent) { Dimension dim = new Dimension(); Insets insets = getInsets(parent); dim.width = insets.left + insets.right; dim.width += getLeftPreferredWidth(); dim.width += getCenterPreferredWidth(); dim.width += getRightPreferredWidth(); dim.height = insets.top + insets.bottom; dim.height += getTopPreferredHeight(); dim.height += getCenterPreferredHeight(); dim.height += getBottomPreferredHeight(); return dim; } //}}} //{{{ preferred widths // constrained by left component preferred width private int getLeftPreferredWidth() { if (left != null) { return left.getPreferredSize().width; } int tlw = topLeft == null ? 0 : topLeft.getPreferredSize().width; int lw = left == null ? 0 : left.getPreferredSize().width; int blw = bottomLeft == null ? 0 : bottomLeft.getPreferredSize().width; return Math.max(lw, Math.max(tlw, blw)); } private int getCenterPreferredWidth() { int tw = top == null ? 0 : top.getPreferredSize().width; int cw = center == null ? 0 : center.getPreferredSize().width; int bw = bottom == null ? 0 : bottom.getPreferredSize().width; return Math.max(cw, Math.max(tw, bw)); } // constrained by right component preferred width private int getRightPreferredWidth() { if (right != null) { return right.getPreferredSize().width; } int trw = topRight == null ? 0 : topRight.getPreferredSize().width; int rw = right == null ? 0 : right.getPreferredSize().width; int brw = bottomRight == null ? 0 : bottomRight.getPreferredSize().width; return Math.max(rw, Math.max(trw, brw)); } //}}} //{{{ preferred heights // constrained by top component preferred height private int getTopPreferredHeight() { if (top != null) { return top.getPreferredSize().height; } int tlh = topLeft == null ? 0 : topLeft.getPreferredSize().height; int th = top == null ? 0 : top.getPreferredSize().height; int trh = topRight == null ? 0 : topRight.getPreferredSize().height; return Math.max(th, Math.max(tlh, trh)); } private int getCenterPreferredHeight() { int lh = left == null ? 0 : left.getPreferredSize().height; int ch = center == null ? 0 : center.getPreferredSize().height; int rh = right == null ? 0 : right.getPreferredSize().height; return Math.max(ch, Math.max(lh, rh)); } // constrained by bottom component preferred height private int getBottomPreferredHeight() { if (bottom != null) { return bottom.getPreferredSize().height; } int blh = bottomLeft == null ? 0 : bottomLeft.getPreferredSize().height; int bh = bottom == null ? 0 : bottom.getPreferredSize().height; int brh = bottomRight == null ? 0 : bottomRight.getPreferredSize().height; return Math.max(bh, Math.max(brh, blh)); } //}}} //{{{ minimumLayoutSize() method public Dimension minimumLayoutSize(Container parent) { Dimension dim = new Dimension(); Insets insets = getInsets(parent); dim.width = insets.left + insets.right; dim.height = insets.top + insets.bottom; int tlw = topLeft == null ? 0 : topLeft.getMinimumSize().width; int lw = left == null ? 0 : left.getMinimumSize().width; int blw = bottomLeft == null ? 0 : bottomLeft.getMinimumSize().width; dim.width += Math.max(lw, Math.max(tlw, blw)); int tw = top == null ? 0 : top.getMinimumSize().width; int cw = center == null ? 0 : center.getMinimumSize().width; int bw = bottom == null ? 0 : bottom.getMinimumSize().width; dim.width += Math.max(cw, Math.max(tw, bw)); int trw = topRight == null ? 0 : topRight.getMinimumSize().width; int rw = right == null ? 0 : right.getMinimumSize().width; int brw = bottomRight == null ? 0 : bottomRight.getMinimumSize().width; dim.width += Math.max(rw, Math.max(trw, brw)); int tlh = topLeft == null ? 0 : topLeft.getMinimumSize().height; int lh = left == null ? 0 : left.getMinimumSize().height; int blh = bottomLeft == null ? 0 : bottomLeft.getMinimumSize().height; dim.height += Math.max(lh, Math.max(tlh, blh)); int th = top == null ? 0 : top.getMinimumSize().height; int ch = center == null ? 0 : center.getMinimumSize().height; int bh = bottom == null ? 0 : bottom.getMinimumSize().height; dim.height += Math.max(ch, Math.max(th, bh)); int trh = topRight == null ? 0 : topRight.getMinimumSize().height; int rh = right == null ? 0 : right.getMinimumSize().height; int brh = bottomRight == null ? 0 : bottomRight.getMinimumSize().height; dim.height += Math.max(rh, Math.max(trh, brh)); return dim; } //}}} //{{{ layoutContainer() method public void layoutContainer(Container parent) { Dimension size = parent.getSize(); Insets insets = getInsets(parent); int itop = insets.top; int ileft = insets.left; int ibottom = insets.bottom; int iright = insets.right; int leftWidth = getLeftPreferredWidth(); int rightWidth = getRightPreferredWidth(); int topHeight = getTopPreferredHeight(); int bottomHeight = getBottomPreferredHeight(); int centerWidth = Math.max(0,size.width - leftWidth - rightWidth - ileft - iright); int centerHeight = Math.max(0,size.height - topHeight - bottomHeight - itop - ibottom); if (left != null) { left.setBounds( ileft, itop+topHeight, leftWidth, centerHeight); } if (center != null) { center.setBounds( ileft + leftWidth, itop+topHeight, centerWidth, centerHeight); } if (right != null) { right.setBounds( ileft + leftWidth + centerWidth, itop + topHeight, rightWidth, centerHeight); } if (bottom != null) { bottom.setBounds( ileft + leftWidth, itop + topHeight + centerHeight, centerWidth, bottomHeight); } if(top != null) { top.setBounds( ileft + leftWidth, itop, centerWidth, topHeight); } if (topLeft != null) { topLeft.setBounds( ileft, itop, leftWidth, topHeight); } if (topRight != null) { topRight.setBounds( ileft + leftWidth + centerWidth, itop, rightWidth, topHeight); } if (bottomLeft != null) { bottomLeft.setBounds( ileft, itop + topHeight + centerHeight, leftWidth, bottomHeight); } if (bottomRight != null) { bottomRight.setBounds( ileft + leftWidth + centerWidth, itop + topHeight + centerHeight, rightWidth, bottomHeight); } } //}}} //{{{ Private members private Component center; private Component left; private Component right; private Component bottom; private Component top; private Component topLeft; private Component topRight; private Component bottomLeft; private Component bottomRight; //{{{ getInsets() method private Insets getInsets(Component parent) { Border border = ((JComponent)parent).getBorder(); if(border == null) return new Insets(0,0,0,0); else return border.getBorderInsets(parent); } //}}} //}}} }