1 package org.catacomb.druid.swing.split;
2
3 import org.catacomb.interlish.interact.DComponent;
4
5 import javax.swing.*;
6 import java.awt.*;
7 import java.awt.event.*;
8
9 public class DSplitterBar extends JPanel implements DComponent {
10
11 private static final long serialVersionUID = 1L;
12 static final Cursor VERT_CURSOR = new Cursor(Cursor.N_RESIZE_CURSOR);
13 static final Cursor HORIZ_CURSOR = new Cursor(Cursor.E_RESIZE_CURSOR);
14 static final Cursor DEF_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
15 private int orientation = SplitterLayout.VERTICAL;
16
17 private boolean alreadyDrawn = false;
18 private Rectangle originalBounds = null;
19 private Window wBar;
20
21
22 public DSplitterBar() {
23 addMouseMotionListener(new SplitterBarMouseMotionListener(this));
24 addMouseListener(new SplitterBarMouseListener(this));
25 }
26
27 private void checkOtherComponents() {
28 Rectangle currBounds = getBounds();
29 Component comps[] = getParent().getComponents();
30 Insets insets = getParent().getInsets();
31 Rectangle parentBounds = getParent().getBounds();
32
33
34 int curr;
35 for (curr = 0; (curr<comps.length) && (comps[curr]!=this); curr++) ;
36 int origCurr = curr;
37
38 if (orientation==SplitterLayout.VERTICAL) {
39 if (currBounds.y<originalBounds.y) {
40
41
42
43
44 boolean done = false;
45 for (int temp = curr-1; !done && temp>-1; temp--) {
46 if (comps[temp] instanceof DSplitterBar) {
47 Rectangle r = comps[temp].getBounds();
48 if (currBounds.y<=r.y+r.height) {
49 comps[temp].setLocation(r.x, currBounds.y-r.height);
50
51 for (int c = curr-1; c>temp; c--)
52 comps[c].setVisible(false);
53 curr = temp;
54 currBounds = comps[temp].getBounds();
55 }
56 else
57 done = true;
58 }
59 }
60
61
62 if (currBounds.y<=insets.top) {
63 int delta = currBounds.y-insets.top;
64
65 for (int temp = curr-1; temp>-1; temp--)
66 comps[temp].setVisible(false);
67
68 done = false;
69 for (int temp = curr; !done && temp<=origCurr; temp++)
70 if (comps[temp] instanceof DSplitterBar) {
71 Point p = comps[temp].getLocation();
72 p.y -= delta;
73 comps[temp].setLocation(p);
74 } else
75 done = comps[temp].isVisible();
76 }
77
78
79 curr = origCurr;
80
81
82 for (int temp = curr+1; temp<comps.length && !comps[temp].isVisible(); temp++)
83 comps[temp].setVisible(true);
84 }
85 else if (currBounds.y>originalBounds.y) {
86
87
88
89
90 boolean done = false;
91 for (int temp = curr+1; !done && temp<comps.length; temp++) {
92 if (comps[temp] instanceof DSplitterBar) {
93 Rectangle r = comps[temp].getBounds();
94 if (currBounds.y+currBounds.height>= r.y) {
95 comps[temp].setLocation(r.x, currBounds.y+currBounds.height);
96
97 for (int c = curr+1; c<temp; c++)
98 comps[c].setVisible(false);
99 curr = temp;
100 currBounds = comps[temp].getBounds();
101 }
102 else
103 done = true;
104 }
105 }
106
107
108 if ((currBounds.y+currBounds.height)>= (parentBounds.height-insets.bottom)) {
109 int delta = currBounds.y+currBounds.height-(parentBounds.height-insets.bottom);
110
111 for (int temp = curr+1; temp<comps.length; temp++)
112 comps[temp].setVisible(false);
113
114 done = false;
115 for (int temp = curr; !done && temp>= origCurr; temp--)
116 if (comps[temp] instanceof DSplitterBar) {
117 Point p = comps[temp].getLocation();
118 p.y -= delta;
119 comps[temp].setLocation(p);
120 } else
121 done = comps[temp].isVisible();
122 }
123
124
125 curr = origCurr;
126
127
128 for (int temp = curr-1; temp>-1 && !comps[temp].isVisible(); temp--)
129 comps[temp].setVisible(true);
130 }
131 }
132 else {
133 if (currBounds.x<originalBounds.x) {
134
135
136
137
138 boolean done = false;
139 for (int temp = curr-1; !done && temp>-1; temp--) {
140 if (comps[temp] instanceof DSplitterBar) {
141 Rectangle r = comps[temp].getBounds();
142 if (currBounds.x<=r.x+r.width) {
143 comps[temp].setLocation(currBounds.x-r.width, r.y);
144
145 for (int c = curr-1; c>temp; c--)
146 comps[c].setVisible(false);
147 curr = temp;
148 currBounds = comps[temp].getBounds();
149 }
150 else
151 done = true;
152 }
153 }
154
155
156 if (currBounds.x<=insets.left) {
157 int delta = currBounds.x-insets.left;
158
159 for (int temp = curr-1; temp>-1; temp--)
160 comps[temp].setVisible(false);
161
162 done = false;
163 for (int temp = curr; !done && temp<=origCurr; temp++)
164 if (comps[temp] instanceof DSplitterBar) {
165 Point p = comps[temp].getLocation();
166 p.x -= delta;
167 comps[temp].setLocation(p);
168 } else
169 done = comps[temp].isVisible();
170 }
171
172
173 curr = origCurr;
174
175
176 for (int temp = curr+1; temp<comps.length && !comps[temp].isVisible(); temp++)
177 comps[temp].setVisible(true);
178 }
179 else if (currBounds.x>originalBounds.x) {
180
181
182
183
184 boolean done = false;
185 for (int temp = curr+1; !done && temp<comps.length; temp++) {
186 if (comps[temp] instanceof DSplitterBar) {
187 Rectangle r = comps[temp].getBounds();
188 if (currBounds.x+currBounds.width>= r.x) {
189 comps[temp].setLocation(currBounds.x+currBounds.width, r.y);
190
191 for (int c = curr+1; c<temp; c++)
192 comps[c].setVisible(false);
193 curr = temp;
194 currBounds = comps[temp].getBounds();
195 }
196 else
197 done = true;
198 }
199 }
200
201
202 if ((currBounds.x+currBounds.width)>= (parentBounds.width-insets.right)) {
203 int delta = currBounds.x+currBounds.width-(parentBounds.width-insets.right);
204
205 for (int temp = curr+1; temp<comps.length; temp++)
206 comps[temp].setVisible(false);
207
208 done = false;
209 for (int temp = curr; !done && temp>= origCurr; temp--)
210 if (comps[temp] instanceof DSplitterBar) {
211 Point p = comps[temp].getLocation();
212 p.x -= delta;
213 comps[temp].setLocation(p);
214 } else
215 done = comps[temp].isVisible();
216 }
217
218
219 curr = origCurr;
220
221
222 for (int temp = curr-1; temp>-1 && !comps[temp].isVisible(); temp--)
223 comps[temp].setVisible(true);
224 }
225 }
226
227 }
228
229 public int getOrientation() {
230 return orientation;
231 }
232
233 void mouseDrag(MouseEvent e) {
234 if (SplitterLayout.dragee==null)
235 SplitterLayout.dragee = this;
236 else if (SplitterLayout.dragee!=this)
237 return;
238 Component c = getParent();
239 Point fl = c.getLocationOnScreen();
240 while (c.getParent()!=null)
241 c = c.getParent();
242 if (!alreadyDrawn) {
243 originalBounds = getBounds();
244 wBar = new Window((Frame)c);
245 wBar.setBackground(getBackground().darker());
246 }
247 Container cp = getParent();
248 Dimension parentDim = cp.getSize();
249 Point l = getLocationOnScreen();
250 Insets insets = cp.getInsets();
251 if (orientation==SplitterLayout.VERTICAL)
252 parentDim.width -= insets.right+insets.left;
253 else
254 parentDim.height -= insets.top+insets.bottom;
255 Rectangle r = getBounds();
256 int x = l.x+(orientation==SplitterLayout.HORIZONTAL ? e.getX() : 0);
257 int y = l.y+(orientation==SplitterLayout.VERTICAL ? e.getY() : 0);
258 if (x<fl.x+insets.left)
259 x = fl.x+insets.left;
260 else if ((orientation==SplitterLayout.HORIZONTAL) && (x>fl.x+parentDim.width-r.width))
261 x = fl.x+parentDim.width-r.width;
262 if (y<fl.y+insets.top)
263 y = fl.y+insets.top;
264 else if ((orientation==SplitterLayout.VERTICAL) && (y>fl.y+parentDim.height-r.height))
265 y = fl.y+parentDim.height-r.height;
266 wBar.setBounds(x, y,
267 (orientation==SplitterLayout.HORIZONTAL) ? 3 : parentDim.width,
268 (orientation==SplitterLayout.VERTICAL) ? 3 : parentDim.height);
269 if (!alreadyDrawn) {
270 wBar.setVisible(true);
271 alreadyDrawn = true;
272 }
273 }
274 void mouseEnter(MouseEvent e) {
275 if (SplitterLayout.dragee!=null) return;
276 setCursor((orientation==SplitterLayout.VERTICAL) ? VERT_CURSOR : HORIZ_CURSOR);
277
278 invalidate();
279 validate();
280 repaint();
281 }
282 void mouseExit(MouseEvent e) {
283 if (SplitterLayout.dragee!=null) return;
284 setCursor(DEF_CURSOR);
285
286 invalidate();
287 validate();
288 repaint();
289 }
290
291 void mouseRelease(MouseEvent e) {
292 if (alreadyDrawn) {
293 if (SplitterLayout.dragee!=this) return;
294 SplitterLayout.dragee = null;
295 wBar.setVisible(false);
296 wBar.dispose();
297 wBar = null;
298 alreadyDrawn = false;
299 Rectangle r = getBounds();
300 r.x += (orientation==SplitterLayout.HORIZONTAL ? e.getX() : 0);
301 r.y += (orientation==SplitterLayout.VERTICAL ? e.getY() : 0);
302 setLocation(r.x, r.y);
303 setCursor(DEF_CURSOR);
304
305
306
307
308
309 checkOtherComponents();
310
311 invalidate();
312 getParent().validate();
313 SplitterLayout.dragee = null;
314 }
315 }
316
317
318
319
320
321
322
323
324 public void paint(Graphics g) {
325 super.paint(g);
326 g.setColor(getBackground());
327
328
329
330
331 Component c[] = getComponents();
332 if (c!=null && c.length>0)
333 for (int i = 0; i<c.length; i++) {
334 if (c[i] instanceof DSplitterSpace) {
335
336 Rectangle r = c[i].getBounds();
337 if (orientation==SplitterLayout.VERTICAL)
338 g.fill3DRect(r.x+2, r.y+r.height/2-1, r.width-5, 3, true);
339 else
340 g.fill3DRect(r.x+r.width/2-1, r.y+2, 3, r.y+r.height-5, true);
341 }
342 }
343 else {
344 Rectangle r = getBounds();
345 if (orientation==SplitterLayout.VERTICAL)
346 g.fill3DRect(2, r.height/2-1, r.width-5, 3, true);
347 else
348 g.fill3DRect(r.width/2-1, 2, 3, r.height-5, true);
349 }
350 }
351
352 void setOrientation(int o) {
353 orientation = o;
354 }
355
356 public void swapOrientation() {
357 setOrientation(getOrientation()==SplitterLayout.HORIZONTAL ? SplitterLayout.VERTICAL : SplitterLayout.HORIZONTAL);
358 }
359
360
361
362
363 public void update(Graphics g) {
364 paint(g);
365 }
366
367 public void setTooltip(String s) {
368
369 }
370
371
372 }