001: /*
002: * Copyright 2006-2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt.
007: *
008: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
009: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
010: * the license for the specific language governing your rights and limitations.
011: *
012: * Additional Contributor(s): Martin Schmid gridvision engineering GmbH
013: */
014: package org.pentaho.reportdesigner.lib.client.components.docking;
015:
016: import org.jetbrains.annotations.NotNull;
017:
018: import javax.swing.*;
019: import java.awt.*;
020: import java.awt.event.MouseAdapter;
021: import java.awt.event.MouseEvent;
022: import java.awt.event.MouseMotionAdapter;
023: import java.util.ArrayList;
024: import java.util.Arrays;
025:
026: /**
027: * User: Martin
028: * Date: 18.03.2005
029: * Time: 11:49:05
030: */
031: public class BorderComponent extends JPanel {
032: @NotNull
033: private ArrayList<ToolWindow> toolWindows;
034:
035: @NotNull
036: private JPanel dragPanel;
037:
038: @NotNull
039: private DockingPane.Split split;
040: @NotNull
041: private DockingPane.SplitpaneDirection splitpaneDirection;
042:
043: private int startX;
044: private int startY;
045:
046: public BorderComponent(@NotNull
047: final DockingPane.Split split, @NotNull
048: final DockingPane.SplitpaneDirection splitpaneDirection, @NotNull
049: final DockingPane dockingPane) {
050: this .split = split;
051: this .splitpaneDirection = splitpaneDirection;
052:
053: setLayout(new BorderLayout());
054:
055: toolWindows = new ArrayList<ToolWindow>();
056:
057: dragPanel = new JPanel();
058: dragPanel.setPreferredSize(new Dimension(5, 5));
059: dragPanel.setSize(5, 5);
060: dragPanel.setOpaque(true);
061:
062: switch (split) {
063: case TOP:
064: add(dragPanel, BorderLayout.SOUTH);
065: dragPanel.setCursor(Cursor
066: .getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
067: break;
068: case BOTTOM:
069: add(dragPanel, BorderLayout.NORTH);
070: dragPanel.setCursor(Cursor
071: .getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
072: break;
073: case LEFT:
074: add(dragPanel, BorderLayout.EAST);
075: dragPanel.setCursor(Cursor
076: .getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
077: break;
078: case RIGHT:
079: add(dragPanel, BorderLayout.WEST);
080: dragPanel.setCursor(Cursor
081: .getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
082: break;
083: }
084:
085: dragPanel
086: .setBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0));
087:
088: final Color origColor = dragPanel.getBackground();
089:
090: dragPanel.addMouseListener(new MouseAdapter() {
091: public void mousePressed(@NotNull
092: MouseEvent e) {
093: startX = e.getX();
094: startY = e.getY();
095: }
096:
097: public void mouseReleased(@NotNull
098: MouseEvent e) {
099: dragPanel.setBackground(origColor);
100: }
101: });
102:
103: dragPanel.addMouseMotionListener(new MouseMotionAdapter() {
104: public void mouseDragged(@NotNull
105: MouseEvent e) {
106: if (split == DockingPane.Split.LEFT) {
107: int x = e.getX();
108: int xDiff = startX - x;
109: for (ToolWindow toolWindow1 : toolWindows) {
110: int w = getWidth() - xDiff;
111: ToolWindow toolWindow = toolWindow1;
112: Dimension s = toolWindow.getSize();
113: int maxSize = dockingPane
114: .getMaxSize(ToolWindow.Alignment.LEFT);
115: //int minSize = dockingPane.getMinSize(ToolWindow.Alignment.LEFT);
116: int minSize = dragPanel.getWidth();
117: if (w > maxSize) {
118: w = maxSize;
119: }
120: if (w < minSize) {
121: w = minSize;
122: }
123: s.width = w - dragPanel.getWidth();
124: toolWindow.setSize(s);
125: }
126: } else if (split == DockingPane.Split.RIGHT) {
127: int x = e.getX();
128: int xDiff = startX - x;
129:
130: for (ToolWindow toolWindow1 : toolWindows) {
131: int w = getWidth() + xDiff;
132: ToolWindow toolWindow = toolWindow1;
133: Dimension s = toolWindow.getSize();
134: int maxSize = dockingPane
135: .getMaxSize(ToolWindow.Alignment.RIGHT);
136: //int minSize = dockingPane.getMinSize(ToolWindow.Alignment.RIGHT);
137: int minSize = dragPanel.getWidth();
138: if (w > maxSize) {
139: w = maxSize;
140: }
141: if (w < minSize) {
142: w = minSize;
143: }
144: s.width = w - dragPanel.getWidth();
145: toolWindow.setSize(s);
146: }
147: } else if (split == DockingPane.Split.TOP) {
148: int y = e.getY();
149: int yDiff = startY - y;
150: for (ToolWindow toolWindow1 : toolWindows) {
151: int h = getHeight() - yDiff;
152: ToolWindow toolWindow = toolWindow1;
153: Dimension s = toolWindow.getSize();
154: int maxSize = dockingPane
155: .getMaxSize(ToolWindow.Alignment.TOP);
156: //int minSize = dockingPane.getMinSize(ToolWindow.Alignment.TOP);
157: int minSize = dragPanel.getHeight();
158:
159: if (h > maxSize) {
160: h = maxSize;
161: }
162: if (h < minSize) {
163: h = minSize;
164: }
165: s.height = h - dragPanel.getHeight();
166: toolWindow.setSize(s);
167: }
168: } else if (split == DockingPane.Split.BOTTOM) {
169: int y = e.getY();
170: int yDiff = startY - y;
171: for (ToolWindow toolWindow1 : toolWindows) {
172: int h = getHeight() + yDiff;
173: ToolWindow toolWindow = toolWindow1;
174: Dimension s = toolWindow.getSize();
175: int maxSize = dockingPane
176: .getMaxSize(ToolWindow.Alignment.BOTTOM);
177: //int minSize = dockingPane.getMinSize(ToolWindow.Alignment.BOTTOM);
178: int minSize = dragPanel.getHeight();
179: if (h > maxSize) {
180: h = maxSize;
181: }
182: if (h < minSize) {
183: h = minSize;
184: }
185: s.height = h - dragPanel.getHeight();
186: toolWindow.setSize(s);
187: }
188: }
189: }
190: });
191: }
192:
193: public void setToolWindowHeight(int height) {
194: for (ToolWindow toolWindow : toolWindows) {
195: if (toolWindow.getSizeState() == ToolWindow.SizeState.NORMAL) {
196: Dimension size = toolWindow.getSize();
197: size.height = height - dragPanel.getHeight();
198: toolWindow.setSize(size);
199: }
200: }
201: }
202:
203: public void setToolWindowWidth(int width) {
204: for (ToolWindow toolWindow : toolWindows) {
205: if (toolWindow.getSizeState() == ToolWindow.SizeState.NORMAL) {
206: Dimension size = toolWindow.getSize();
207: size.width = width - dragPanel.getWidth();
208: toolWindow.setSize(size);
209: }
210: }
211: }
212:
213: @NotNull
214: public JComponent getDragPanel() {
215: return dragPanel;
216: }
217:
218: public int getToolWindowCount() {
219: return toolWindows.size();
220: }
221:
222: public void add(@NotNull
223: ToolWindow toolWindow) {
224: toolWindows.add(toolWindow);
225: rebuildComponent();
226: }
227:
228: public void remove(@NotNull
229: ToolWindow toolWindow) {
230: toolWindows.remove(toolWindow);
231: rebuildComponent();
232: }
233:
234: public void setToolWindows(@NotNull
235: ToolWindow[] tWs) {
236: toolWindows.clear();
237: toolWindows.addAll(Arrays.asList(tWs));
238:
239: rebuildComponent();
240: }
241:
242: public void clearToolWindows() {
243: toolWindows.clear();
244:
245: rebuildComponent();
246: }
247:
248: @NotNull
249: public Dimension getPreferredSize() {
250: Dimension d = new Dimension();
251: for (ToolWindow toolWindow : toolWindows) {
252: if (toolWindow.getSizeState() == ToolWindow.SizeState.NORMAL) {
253: if (split == DockingPane.Split.TOP
254: || split == DockingPane.Split.BOTTOM) {
255: d.height = Math.max(d.height,
256: toolWindow.getSize().height
257: + dragPanel.getHeight());
258: } else {
259: d.width = Math.max(d.width,
260: toolWindow.getSize().width
261: + dragPanel.getWidth());
262: }
263: }
264: }
265:
266: return d;
267: }
268:
269: public boolean isVisible() {
270: for (ToolWindow toolWindow : toolWindows) {
271: if (toolWindow.getSizeState() == ToolWindow.SizeState.NORMAL) {
272: return true;
273: }
274: }
275:
276: return false;
277: }
278:
279: private void rebuildComponent() {
280: removeAll();
281:
282: switch (split) {
283: case TOP:
284: add(dragPanel, BorderLayout.SOUTH);
285: break;
286: case BOTTOM:
287: add(dragPanel, BorderLayout.NORTH);
288: break;
289: case LEFT:
290: add(dragPanel, BorderLayout.EAST);
291: break;
292: case RIGHT:
293: add(dragPanel, BorderLayout.WEST);
294: break;
295: }
296:
297: if (toolWindows.isEmpty()) {
298: //noinspection UnnecessaryReturnStatement
299: return;//just to be more clear
300: } else if (toolWindows.size() == 1) {
301: add(toolWindows.get(0).getCategory().getMainComponent(),
302: BorderLayout.CENTER);
303: } else {
304: ToolWindow firstToolWindow = toolWindows.get(0);
305:
306: JSplitPane splitPane = new JSplitPane(
307: splitpaneDirection == DockingPane.SplitpaneDirection.HORIZONTAL ? JSplitPane.HORIZONTAL_SPLIT
308: : JSplitPane.VERTICAL_SPLIT);
309: splitPane.setBorder(BorderFactory.createEmptyBorder());
310: add(splitPane, BorderLayout.CENTER);
311: splitPane.setTopComponent(firstToolWindow.getCategory()
312: .getMainComponent());
313: splitPane.setDividerLocation(0.5);
314: splitPane.setResizeWeight(0.5);
315: splitPane.setContinuousLayout(true);
316:
317: for (int i = 1; i < toolWindows.size(); i++) {
318: ToolWindow toolWindow = toolWindows.get(i);
319: if (i == toolWindows.size() - 1) {
320: splitPane.setBottomComponent(toolWindow
321: .getCategory().getMainComponent());
322: splitPane.setDividerLocation(0.5);
323: splitPane.setResizeWeight(0.5);
324: } else {
325: JSplitPane childSplitPane = new JSplitPane(
326: splitpaneDirection == DockingPane.SplitpaneDirection.HORIZONTAL ? JSplitPane.HORIZONTAL_SPLIT
327: : JSplitPane.VERTICAL_SPLIT, true);
328: childSplitPane.setBorder(BorderFactory
329: .createEmptyBorder());
330: splitPane.setBottomComponent(childSplitPane);
331: splitPane.setDividerLocation(0.5);
332: splitPane.setResizeWeight(0.5);
333: childSplitPane.setTopComponent(toolWindow
334: .getCategory().getMainComponent());
335: childSplitPane.setDividerLocation(0.5);
336: childSplitPane.setResizeWeight(0.5);
337: splitPane = childSplitPane;
338: }
339: }
340:
341: revalidate();
342: repaint();
343: }
344: }
345:
346: public void setSplitpaneDirection(@NotNull
347: DockingPane.SplitpaneDirection splitpaneDirection) {
348: this .splitpaneDirection = splitpaneDirection;
349: rebuildComponent();
350: }
351:
352: @NotNull
353: public DockingPane.SplitpaneDirection getSplitpaneDirection() {
354: return splitpaneDirection;
355: }
356: }
|