001: /*
002: * Copyright (C) 2004 NNL Technology AB
003: * Visit www.infonode.net for information about InfoNode(R)
004: * products and how to contact NNL Technology AB.
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
019: * MA 02111-1307, USA.
020: */
021:
022: // $Id: SimpleSplitPane.java,v 1.28 2005/12/04 13:46:04 jesper Exp $
023: package net.infonode.gui;
024:
025: import net.infonode.gui.panel.BaseContainer;
026: import net.infonode.gui.panel.SimplePanel;
027:
028: import javax.swing.*;
029: import java.awt.*;
030: import java.awt.event.MouseAdapter;
031: import java.awt.event.MouseEvent;
032: import java.awt.event.MouseMotionAdapter;
033: import java.util.ArrayList;
034:
035: /**
036: * @author $Author: jesper $
037: * @version $Revision: 1.28 $
038: */
039: public class SimpleSplitPane extends BaseContainer {
040: private LayoutManager splitLayout = new LayoutManager() {
041: public void addLayoutComponent(String name, Component comp) {
042: }
043:
044: public void layoutContainer(Container parent) {
045: if (leftComponent == null || !leftComponent.isVisible()) {
046: maximize(rightComponent);
047: } else if (rightComponent == null
048: || !rightComponent.isVisible()) {
049: maximize(leftComponent);
050: } else {
051: float dividerLocation = fixDividerLocation(getDividerLocation());
052: int totalSize = getViewSize();
053: int leftSize = (int) (totalSize * dividerLocation);
054: int otherSize = getOtherSize();
055: int offsetX = getInsets().left;
056: int offsetY = getInsets().top;
057:
058: Dimension d = createSize(leftSize, otherSize);
059: leftComponent.setBounds(offsetX, offsetY, (int) d
060: .getWidth(), (int) d.getHeight());
061:
062: Point p = createPoint(leftSize, 0);
063: d = createSize(dividerSize, otherSize);
064: dividerPanel.setBounds(p.x + offsetX, p.y + offsetY,
065: (int) d.getWidth(), (int) d.getHeight());
066:
067: p = createPoint(leftSize + dividerSize, 0);
068: d = createSize(totalSize - leftSize, otherSize);
069: rightComponent.setBounds(p.x + offsetX, p.y + offsetY,
070: (int) d.getWidth(), (int) d.getHeight());
071: }
072: }
073:
074: private void maximize(Component component) {
075: if (component != null && component.isVisible()) {
076: Insets i = getInsets();
077: Dimension d = getSize();
078: component.setBounds(i.left, i.top, d.width - i.left
079: - i.right, d.height - i.top - i.bottom);
080: }
081:
082: dividerPanel.setBounds(0, 0, 0, 0);
083: }
084:
085: public Dimension minimumLayoutSize(Container parent) {
086: Dimension d = createSize((leftComponent == null ? 0
087: : getDimensionSize(leftComponent.getMinimumSize()))
088: + dividerSize
089: + (rightComponent == null ? 0
090: : getDimensionSize(rightComponent
091: .getMinimumSize())), Math.max(
092: leftComponent == null ? 0
093: : getOtherSize(leftComponent
094: .getMinimumSize()),
095: rightComponent == null ? 0
096: : getOtherSize(rightComponent
097: .getMinimumSize())));
098: return new Dimension(d.width + getInsets().left
099: + getInsets().right, d.height + getInsets().top
100: + getInsets().bottom);
101: }
102:
103: public Dimension preferredLayoutSize(Container parent) {
104: boolean lv = leftComponent != null
105: && leftComponent.isVisible();
106: boolean rv = rightComponent != null
107: && rightComponent.isVisible();
108: Dimension d = createSize(
109: (lv ? getDimensionSize(leftComponent
110: .getPreferredSize()) : 0)
111: + (lv && rv ? dividerSize : 0)
112: + (rv ? getDimensionSize(rightComponent
113: .getPreferredSize()) : 0), Math
114: .max(lv ? getOtherSize(leftComponent
115: .getPreferredSize()) : 0,
116: rv ? getOtherSize(rightComponent
117: .getPreferredSize()) : 0));
118: return new Dimension(d.width + getInsets().left
119: + getInsets().right, d.height + getInsets().top
120: + getInsets().bottom);
121: }
122:
123: public void removeLayoutComponent(Component comp) {
124: }
125: };
126:
127: private Component leftComponent;
128: private Component rightComponent;
129: private SimplePanel dividerPanel = new SimplePanel();
130: private Component dragIndicator;
131: private boolean dividerDraggable = true;
132: private boolean continuousLayout = true;
133: private float dragLocation;
134: private boolean horizontal;
135: private float dividerLocation = 0.5F;
136: private int dividerSize = 6;
137: private ArrayList listeners = new ArrayList(0);
138: private Color dragIndicatorColor = Color.DARK_GRAY;
139:
140: public SimpleSplitPane(boolean horizontal) {
141: this (horizontal, false);
142: }
143:
144: public SimpleSplitPane(boolean horizontal,
145: boolean heavyWeightDragIndicator) {
146: setLayout(splitLayout);
147: add(dividerPanel);
148: setHorizontal(horizontal);
149:
150: setHeavyWeightDragIndicator(heavyWeightDragIndicator);
151:
152: dividerPanel.addMouseListener(new MouseAdapter() {
153: public void mousePressed(MouseEvent e) {
154: if (e.getButton() == MouseEvent.BUTTON1) {// &&
155: // MouseEventCoalesceManager.getInstance().isPressedAllowed(e))
156: // {
157: CursorManager.setGlobalCursor(getRootPane(),
158: dividerPanel.getCursor());
159: if (dividerDraggable && !continuousLayout) {
160: float location = (float) (getPos(dividerPanel
161: .getLocation())
162: - getOffset() + getPos(e.getPoint()))
163: / getViewSize();
164: setDragIndicator(location);
165: }
166: }
167: }
168:
169: public void mouseReleased(MouseEvent e) {
170: if (e.getButton() == MouseEvent.BUTTON1) {// &&
171: // MouseEventCoalesceManager.getInstance().isReleasedAllowed(e))
172: // {
173: CursorManager.resetGlobalCursor(getRootPane());
174:
175: if (dividerDraggable && !continuousLayout) {
176: dragIndicator.setVisible(false);
177: setDividerLocation(dragLocation);
178: }
179: }
180: }
181: });
182:
183: dividerPanel.addMouseMotionListener(new MouseMotionAdapter() {
184: public void mouseDragged(MouseEvent e) {
185: if (dividerDraggable
186: && /* MouseEventCoalesceManager.getInstance().isDraggedAllowed(e) && */(e
187: .getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0) {
188: float location = (float) (getPos(dividerPanel
189: .getLocation())
190: - getOffset() + getPos(e.getPoint()))
191: / getViewSize();
192:
193: if (continuousLayout)
194: setDividerLocation(location);
195: else
196: setDragIndicator(location);
197: }
198: }
199: });
200: }
201:
202: public SimpleSplitPane(boolean horizontal, Component leftComponent,
203: Component rightComponent) {
204: this (horizontal);
205: setLeftComponent(leftComponent);
206: setRightComponent(rightComponent);
207: }
208:
209: public void addListener(SimpleSplitPaneListener listener) {
210: ArrayList newListeners = new ArrayList(listeners.size() + 1);
211: newListeners.addAll(listeners);
212: listeners = newListeners;
213: listeners.add(listener);
214: }
215:
216: public JComponent getDividerPanel() {
217: return dividerPanel;
218: }
219:
220: public boolean isDividerDraggable() {
221: return dividerDraggable;
222: }
223:
224: public void setDividerDraggable(boolean dividerDraggable) {
225: this .dividerDraggable = dividerDraggable;
226: updateDividerCursor();
227: }
228:
229: public void setHeavyWeightDragIndicator(boolean heavyWeight) {
230: initDragIndicatior(heavyWeight);
231: }
232:
233: public Color getDragIndicatorColor() {
234: return dragIndicatorColor;
235: }
236:
237: public void setDragIndicatorColor(Color dragIndicatorColor) {
238: this .dragIndicatorColor = dragIndicatorColor;
239: dragIndicator.setBackground(dragIndicatorColor);
240: }
241:
242: private void setDragIndicator(float location) {
243: dragLocation = fixDividerLocation(location);
244: dragIndicator.setVisible(true);
245: Point p = createPoint((int) (getViewSize() * dragLocation), 0);
246: Dimension d = createSize(dividerSize, getOtherSize());
247: dragIndicator.setBounds((int) (p.getX() + getInsets().left),
248: (int) (p.getY() + getInsets().top), (int) d.getWidth(),
249: (int) d.getHeight());
250: }
251:
252: private void initDragIndicatior(boolean heavyWeight) {
253: if (dragIndicator != null)
254: remove(dragIndicator);
255:
256: if (heavyWeight) {
257: dragIndicator = new Canvas();
258: } else {
259: dragIndicator = new BaseContainer();
260: }
261:
262: add(dragIndicator, 0);
263: dragIndicator.setBackground(dragIndicatorColor);
264: dragIndicator.setVisible(false);
265: }
266:
267: private float fixDividerLocation(float location) {
268: int totalSize = getViewSize();
269:
270: if (totalSize <= 0)
271: return 0.5F;
272:
273: int leftSize = Math.max((int) (totalSize * location),
274: leftComponent == null || !leftComponent.isVisible() ? 0
275: : getDimensionSize(leftComponent
276: .getMinimumSize()));
277: leftSize = Math.min(leftSize, totalSize
278: - (rightComponent == null
279: || !rightComponent.isVisible() ? 0
280: : getDimensionSize(rightComponent
281: .getMinimumSize())));
282: return (float) leftSize / totalSize;
283: }
284:
285: public void setContinuousLayout(boolean value) {
286: continuousLayout = value;
287: }
288:
289: public boolean isContinuousLayout() {
290: return continuousLayout;
291: }
292:
293: public int getDividerSize() {
294: return dividerSize;
295: }
296:
297: public void setDividerSize(int dividerSize) {
298: this .dividerSize = dividerSize;
299: revalidate();
300: }
301:
302: private int getOffset() {
303: return horizontal ? getInsets().left : getInsets().top;
304: }
305:
306: private int getOtherSize() {
307: return horizontal ? getHeight() - getInsets().top
308: - getInsets().bottom : getWidth() - getInsets().left
309: - getInsets().right;
310: }
311:
312: private int getViewSize() {
313: return getDimensionSize(getSize())
314: - dividerSize
315: - (horizontal ? getInsets().left + getInsets().right
316: : getInsets().top + getInsets().bottom);
317: }
318:
319: private int getDimensionSize(Dimension d) {
320: return (int) (horizontal ? d.getWidth() : d.getHeight());
321: }
322:
323: private int getOtherSize(Dimension d) {
324: return (int) (horizontal ? d.getHeight() : d.getWidth());
325: }
326:
327: private int getPos(Point p) {
328: return (int) (horizontal ? p.getX() : p.getY());
329: }
330:
331: private Dimension createSize(int size, int otherSize) {
332: return horizontal ? new Dimension(size, otherSize)
333: : new Dimension(otherSize, size);
334: }
335:
336: private Point createPoint(int pos, int otherPos) {
337: return horizontal ? new Point(pos, otherPos) : new Point(
338: otherPos, pos);
339: }
340:
341: public boolean isHorizontal() {
342: return horizontal;
343: }
344:
345: public void setHorizontal(boolean horizontal) {
346: this .horizontal = horizontal;
347: updateDividerCursor();
348: revalidate();
349: }
350:
351: public float getDividerLocation() {
352: return dividerLocation;
353: }
354:
355: public void setDividerLocation(float dividerLocation) {
356: this .dividerLocation = dividerLocation;
357: revalidate();
358:
359: for (int i = 0; i < listeners.size(); i++)
360: ((SimpleSplitPaneListener) listeners.get(i))
361: .dividerLocationChanged(this );
362: }
363:
364: public Component getLeftComponent() {
365: return leftComponent;
366: }
367:
368: public void setLeftComponent(Component leftComponent) {
369: if (this .leftComponent != null)
370: remove(this .leftComponent);
371:
372: this .leftComponent = leftComponent;
373:
374: if (leftComponent != null)
375: add(leftComponent);
376:
377: revalidate();
378: }
379:
380: public Component getRightComponent() {
381: return rightComponent;
382: }
383:
384: public void setRightComponent(Component rightComponent) {
385: if (this .rightComponent != null)
386: remove(this .rightComponent);
387:
388: this .rightComponent = rightComponent;
389:
390: if (rightComponent != null)
391: add(rightComponent);
392:
393: revalidate();
394: }
395:
396: private void updateDividerCursor() {
397: dividerPanel.setCursor(dividerDraggable ? new Cursor(
398: horizontal ? Cursor.W_RESIZE_CURSOR
399: : Cursor.N_RESIZE_CURSOR) : Cursor
400: .getDefaultCursor());
401: }
402:
403: public void setComponents(Component leftComponent,
404: Component rightComponent) {
405: setLeftComponent(leftComponent);
406: setRightComponent(rightComponent);
407: }
408: }
|