Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/trapezium/chisel/gui/ScrollablePane.java


1   /*  ScrollablePane
2    *
3    */
4   
5   package com.trapezium.chisel.gui;
6   
7   import java.awt.*;
8   import java.awt.event.*;
9   import java.io.*;
10  import java.net.URL;
11  import java.util.*;
12  
13  //import com.trapezium.chisel.*;
14  
15  /** The base container for our own gui implementation.  This class includes
16      commonly needed functionality such as double buffering, background texture
17      and border.
18   */
19  public class ScrollablePane extends ChiselAWTPane implements AdjustmentListener {
20  
21      // if the mode is DYNAMIC, the scroll bars disappear when not needed.
22      public static final int STATIC = 0;
23      public static final int DYNAMIC = 1;
24  
25      HolderPane holder;                      // owns the reference plane
26      Component hScrollComponent;
27      Component vScrollComponent;
28      int mode = STATIC;
29  
30      private ComponentAdapter tracker;       // tracks position of children
31      private Rectangle fullRect;             // the bounds of all children
32  
33      public ScrollablePane() {
34          this(NO_BORDER);
35      }
36  
37      public ScrollablePane(int border) {
38          this(border, false);
39      }
40  
41      public ScrollablePane(int border, boolean opaque) {
42          super(border);
43  
44          tracker = new ComponentTracker(this);
45  
46          createScrollers(opaque);
47  
48          holder = new HolderPane();
49          holder.setLayout(null);
50          add(holder);
51  
52          fullRect = new Rectangle(0, 0, 0, 0);
53          setScrollValues();
54      }
55  
56      public void setScrollMode(int mode) {
57          this.mode = mode;
58      }
59  
60      private boolean hEnabled = true;
61      private boolean vEnabled = true;
62  
63      public void enableScroll(boolean horiz, boolean vert) {
64          hEnabled = horiz;
65          hScrollComponent.setVisible(horiz);
66          vEnabled = vert;
67          vScrollComponent.setVisible(vert);
68      }
69  
70      public void setErrorMarks( BitSet errorMarks, BitSet warningMarks, BitSet nonconformanceMarks ) {
71          Slider s = (Slider)vScrollComponent;
72          s.setErrorMarks( errorMarks, warningMarks, nonconformanceMarks );
73      }
74  
75      public void setScrollIncrements(int hUnit, int vUnit, int hBlock, int vBlock) {
76  //        System.out.println(getClass().getName() + " scroll units " + hUnit + "," + vUnit + " blocks " + hBlock + "," + vBlock);
77  
78          Adjustable hScroller = (Adjustable) hScrollComponent;
79          hScroller.setUnitIncrement(hUnit);
80          hScroller.setBlockIncrement(hBlock);
81  
82          Adjustable vScroller = (Adjustable) vScrollComponent;
83          vScroller.setUnitIncrement(vUnit);
84          vScroller.setBlockIncrement(vBlock);
85      }
86  
87      final public Component getHScrollComponent() {
88          return hScrollComponent;
89      }
90      final public Component getVScrollComponent() {
91          return vScrollComponent;
92      }
93  
94      void createScrollers(boolean opaque) {
95          hScrollComponent = new Slider(Adjustable.HORIZONTAL, 0, 100);
96          ((Slider) hScrollComponent).setOpaque(opaque);
97          add(hScrollComponent);
98  
99          vScrollComponent = new Slider(Adjustable.VERTICAL, 0, 100);
100         ((Slider) vScrollComponent).setOpaque(opaque);
101         add(vScrollComponent);
102     }
103 
104     class ComponentTracker extends ComponentAdapter {
105 
106         ScrollablePane pane;
107 
108         public ComponentTracker(ScrollablePane pane) {
109             super();
110             this.pane = pane;
111         }
112 
113         public void componentMoved(ComponentEvent evt) {
114             setScrollValues(evt);
115         }
116         public void componentResized(ComponentEvent evt) {
117             setScrollValues(evt);
118         }
119         public void componentHidden(ComponentEvent evt) {
120             setScrollValues(evt);
121         }
122         public void componentShown(ComponentEvent evt) {
123             setScrollValues(evt);
124         }
125         void setScrollValues(ComponentEvent evt) {
126             pane.setScrollValues();
127             /****
128             Container granny = evt.getComponent().getParent().getParent();
129             if (granny instanceof ScrollablePane) {
130                 ScrollablePane pane = (ScrollablePane) granny;
131                 pane.calibrateComponents();
132                 //System.out.println("Setting scroll values in response to " + evt.getComponent());
133                 pane.setScrollValues();
134             } *****/
135         }
136     }
137 
138     public void adjustmentValueChanged(AdjustmentEvent evt) {
139 
140         if (!isEnabled()) {
141             return;
142         }
143 
144         Adjustable hscroller = (Adjustable) hScrollComponent;
145         int xnew = hscroller.getValue() - hscroller.getMinimum();
146         Adjustable vscroller = (Adjustable) vScrollComponent;
147         int ynew = vscroller.getValue() - vscroller.getMinimum();
148         Point pt = holder.getLocation();
149 
150         //System.out.println("adjValChgd xnew,ynew " + xnew + "," + ynew + "  holder.getLocation " + pt);
151 
152         if (xnew != pt.x || ynew != pt.y) {
153             Dimension size = getSize();
154             Insets insets = getInsets();
155             size.width -= insets.left + insets.right;
156             size.height -= insets.top + insets.bottom;
157             if (xnew + fullRect.width < size.width) {
158                 fullRect.width = size.width - xnew;
159             }
160             if (ynew + fullRect.height < size.height) {
161                 fullRect.height = size.height - ynew;
162             }
163             holder.setBounds(-xnew, -ynew, fullRect.width - fullRect.x, fullRect.height - fullRect.y);
164             repaint();
165         }
166     }
167 
168     /** move the holder without changing the apparent position of its children */
169 /***
170     void calibrateComponents() {
171         computeFullRect();
172 
173         int x = fullRect.x;
174         int y = fullRect.y;
175 
176         System.out.println( "*** calibrate: Set holder x,y to " + x + "," + y );
177 
178         Point pt = holder.getLocation();
179         int dx = x - pt.x;
180         int dy = (y - pt.y); ///15;
181 
182         holder.setBounds(x, y, fullRect.width, fullRect.height);
183 
184         if (dx != 0 || dy != 0) {
185 
186             int count = holder.getComponentCount();
187             for (int i = 0; i < count; i++) {
188                 Component c = holder.getComponent(i);
189                 Point cpt = c.getLocation();
190                 c.setLocation(cpt.x - dx, cpt.y - dy);
191             }
192 
193             int xval = ((Adjustable) hScrollComponent).getValue();
194             ((Adjustable) hScrollComponent).setValue(xval - dx);
195 
196             int yval = ((Adjustable) vScrollComponent).getValue();
197             ((Adjustable) vScrollComponent).setValue(yval - dy);
198 
199         }
200         repaint();
201     }
202 ****/
203 
204 
205     void computeFullRect() {
206         Rectangle rect = getBounds();
207         Insets insets = getInsets();
208         rect.width -= insets.left + insets.right;
209         rect.height -= insets.top + insets.bottom;
210         rect.x = 0;
211         rect.y = 0;
212 
213         int count = holder.getComponentCount();
214         for (int i = 0; i < count; i++) {
215             Component c = holder.getComponent(i);
216             Rectangle bounds = c.getBounds();
217             //System.out.println("computeFullRect comp " + i + " has bounds " + bounds);
218             if (bounds.x < rect.x) {
219                 rect.width += rect.x - bounds.x;
220                 rect.x = bounds.x;
221             }
222             if (bounds.y < rect.y) {
223                 rect.height += rect.y - bounds.y;
224                 rect.y = bounds.y;
225             }
226             if (bounds.x + bounds.width > rect.x + rect.width) {
227                 rect.width = bounds.x + bounds.width - rect.x;
228             }
229             if (bounds.y + bounds.height > rect.y + rect.height) {
230                 rect.height = bounds.y + bounds.height - rect.y;
231             }
232         }
233         fullRect = rect;
234     }
235 
236 
237     /** set the horizontal and vertical scroll values.  The default is to
238         set the min and max values equal to the furthest extents of all
239         child components and the visibleAmount values to the ScrollablePane's
240         bounds on the screen. */
241 
242     public void setScrollValues() {
243 
244         if (!isEnabled()) {
245         //    System.out.println("ScrollablePane not enabled; setScrollValues bailing out");
246             return;
247         }
248         //System.out.print("setScrollValues: ");
249         //Throwable t = new Throwable();
250         //t.printStackTrace();
251 
252         Dimension size = getSize();
253         Insets insets = getInsets();
254         size.width -= insets.left + insets.right;
255         size.height -= insets.top + insets.bottom;
256 
257         computeFullRect();
258 
259         Adjustable hScroller = (Adjustable) hScrollComponent;
260         int hval = hScroller.getValue();
261         hScroller.setVisibleAmount(size.width);
262         hScroller.setMinimum(fullRect.x);
263         int hmax = fullRect.x + fullRect.width;
264         hScroller.setMaximum(hmax);
265         if (hval < fullRect.x) {
266             hval = fullRect.x;
267         } else if (hval >= hmax) {
268             hval = hmax;
269         }
270         hScroller.setValue(hval);
271 
272         Adjustable vScroller = (Adjustable) vScrollComponent;
273         int vval = vScroller.getValue();
274         vScroller.setVisibleAmount(size.height);
275         vScroller.setMinimum(fullRect.y);
276         int vmax = fullRect.y + fullRect.height;
277         vScroller.setMaximum(vmax);
278         if (vval < fullRect.y) {
279             vval = fullRect.y;
280         } else if (vval >= vmax) {
281             vval = vmax;
282         }
283         vScroller.setValue(vval);
284 
285         int x = fullRect.x - hval;
286         int y = fullRect.y - vval;
287         int width = fullRect.width - fullRect.x;
288         int height = fullRect.height - fullRect.y;
289         holder.setBounds( -hval, -vval, width, height );
290         if (mode == DYNAMIC) {
291             if (hval <= 0 && width <= size.width) {
292                 hScrollComponent.setVisible(false);
293             } else if (hEnabled && !hScrollComponent.isVisible()) {
294                 hScrollComponent.setVisible(true);
295             }
296             if (vval <= 0 && height <= size.height) {
297                 vScrollComponent.setVisible(false);
298             } else if (vEnabled && !vScrollComponent.isVisible()) {
299                 vScrollComponent.setVisible(true);
300             }
301         }
302     }
303 
304     /** this lets an outside component own the scrollers */
305     public void hookScrollersTo(Container c) {
306         remove(hScrollComponent);
307         c.add(hScrollComponent, 0);
308         remove(vScrollComponent);
309         c.add(vScrollComponent, 1);
310     }
311 
312 
313     /** the scrollers should always be in front */
314     public void moveToFront(Component c) {
315         if (c == hScrollComponent || c == vScrollComponent || c == holder) {
316             return;
317         } else if (c != holder.getComponent(0)) {
318             holder.remove(c);
319             holder.add(c, 0);
320             holder.repaint();
321         }
322     }
323 
324     /**  move to back */
325     public void moveToBack(Component c) {
326         if (c == hScrollComponent || c == vScrollComponent || c == holder) {
327             return;
328         } else {
329             holder.remove(c);
330             holder.add(c);
331             holder.repaint();
332         }
333     }
334 
335     protected void addImpl(Component c, Object constraints, int index) {
336         if (c == hScrollComponent) {
337             ((Adjustable)c).addAdjustmentListener(this);
338             super.addImpl(c, constraints, index);
339         } else if (c == vScrollComponent) {
340             ((Adjustable)c).addAdjustmentListener(this);
341             super.addImpl(c, constraints, index);
342         } else if (c == holder) {
343             super.addImpl(c, constraints, index);
344         } else {
345             c.addComponentListener(tracker);
346             holder.add(c, constraints, index);
347             computeFullRect();
348         }
349     }
350 
351     public void remove(Component comp) {
352         if (comp != hScrollComponent && comp != vScrollComponent && comp != holder) {
353             holder.remove(comp);
354         } //else {
355             super.remove(comp);
356         //}
357     }
358 
359     public int getComponentCount() {
360         return holder.getComponentCount();
361     }
362 
363     public Component getComponent(int n) {
364         return holder.getComponent(n);
365     }
366 
367     public void addContainerListener(ContainerListener listener) {
368         holder.addContainerListener(listener);
369     }
370 
371     /** determine the minimum size */
372     public Dimension getMinimumSize() {
373         Dimension min = hScrollComponent.getMinimumSize();
374         Dimension minv = vScrollComponent.getMinimumSize();
375         min.width += minv.width;
376         min.height += minv.height;
377         return min;
378     }
379 
380 
381     /** determine the preferred size */
382     public Dimension getPreferredSize() {
383         computeFullRect();
384         Insets insets = getInsets();
385         Dimension dim = new Dimension(fullRect.width + insets.left + insets.right, fullRect.height + insets.top + insets.bottom);
386         return dim;
387     }
388 
389 
390     /** lay out the pane.  Only the scrollers are positioned; other
391         components remain where they are. */
392     public void doLayout() {
393 
394         Dimension size = getSize();
395         Dimension minh = hScrollComponent.getMinimumSize();
396         Dimension minv = vScrollComponent.getMinimumSize();
397         Container owner = hScrollComponent.getParent();
398         if (owner == this) {
399             Insets insets = getInsets();
400             int top = insets.top;
401             int bottom = size.height - insets.bottom;
402             int left = insets.left;
403             int right = size.width - insets.right;
404 
405             hScrollComponent.setBounds(left, bottom - minh.height, right - left - minv.width, minh.height);
406             vScrollComponent.setBounds(right - minv.width, top, minv.width, bottom - top - minh.height);
407         } else {
408             Point pt;
409             // getLocationOnScreen() bombs when the frame hasn't been shown yet
410             try {
411                 pt = getLocationOnScreen();
412                 Point ownerscreenpt = owner.getLocationOnScreen();
413                 pt.x -= ownerscreenpt.x;
414                 pt.y -= ownerscreenpt.y;
415             } catch (Exception e) {
416                 pt = getLocation();
417             }
418             
419             hScrollComponent.setBounds(pt.x, pt.y + size.height, size.width, minh.height);
420             vScrollComponent.setBounds(pt.x + size.width, pt.y, minv.width, size.height);
421         }
422 
423         setScrollValues();
424 
425       /****
426         computeFullRect();
427         Adjustable hscroller = (Adjustable) hScrollComponent;
428         Adjustable vscroller = (Adjustable) vScrollComponent;
429 
430         int dx = 0;
431         int dy = 0;
432         if (hScrollComponent.isVisible() && ((Slider)hScrollComponent).isOpaque()) {
433             dy = minh.height;
434         }
435         if (vScrollComponent.isVisible() && ((Slider)vScrollComponent).isOpaque()) {
436             dx = minv.width;
437         }
438         holder.setBounds(-hscroller.getValue(), -vscroller.getValue(), fullRect.width, fullRect.height);
439         ****/
440     }
441 
442     /** overrides paint in order to paint the holder separately, otherwise
443         it might be excessively clipped */
444     public void paint(Graphics g) {
445 
446         Dimension size = getSize();
447         Insets insets = getInsets();
448 
449         paintBackground(g);
450 
451         // for the holder, translate the graphics and expand the clip rect to compensate
452         Rectangle hrect = holder.getBounds();
453         Rectangle clip = g.getClipBounds();
454         g.translate(hrect.x, hrect.y);
455         holder.paint(g);
456         g.translate(-hrect.x, -hrect.y);
457 
458         Graphics gcomp;
459         Rectangle r;
460     if (hScrollComponent.isVisible()) {
461         r = hScrollComponent.getBounds();
462       gcomp = g.create(r.x, r.y, r.width, r.height);
463       try {
464           hScrollComponent.paint(gcomp);
465       } finally {
466           gcomp.dispose();
467       }
468     }
469     if (vScrollComponent.isVisible()) {
470         r = vScrollComponent.getBounds();
471       gcomp = g.create(r.x, r.y, r.width, r.height);
472       try {
473           vScrollComponent.paint(gcomp);
474       } finally {
475           gcomp.dispose();
476       }
477     }
478     }
479 }
480