OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / libjava / javax / swing / JScrollPane.java
1 /* JScrollPane.java -- 
2    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing;
40
41 import java.awt.Component;
42 import java.awt.ComponentOrientation;
43 import java.awt.Dimension;
44 import java.awt.LayoutManager;
45 import java.awt.Insets;
46 import java.awt.LayoutManager;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49
50 import javax.accessibility.Accessible;
51 import javax.swing.border.Border;
52 import javax.swing.event.ChangeEvent;
53 import javax.swing.event.ChangeListener;
54 import javax.swing.plaf.ScrollPaneUI;
55 import javax.swing.plaf.UIResource;
56
57 /**
58  * <table>
59  * <tr><th>Property                    </th><th>Stored in       </th><th>Bound?</th></tr>
60  * <tr><td>columnHeader                </td><td>scrollPane      </td><td>yes   </td></tr>
61  * <tr><td>columnHeaderView            </td><td>columnHeader    </td><td>no    </td></tr>
62  * <tr><td>componentOrientation        </td><td>scrollPane      </td><td>yes   </td></tr>
63  * <tr><td>horizontalScrollBar         </td><td>scrollPane      </td><td>yes   </td></tr>
64  * <tr><td>horizontalScrollBarPolicy   </td><td>scrollPane      </td><td>yes   </td></tr>
65  * <tr><td>layout                      </td><td>scrollPane      </td><td>yes   </td></tr>
66  * <tr><td>rowHeader                   </td><td>scrollPane      </td><td>yes   </td></tr>
67  * <tr><td>rowHeaderView               </td><td>rowHeader       </td><td>no    </td></tr>
68  * <tr><td>validateRoot                </td><td>scrollPane      </td><td>no    </td></tr>
69  * <tr><td>verticalScrollBar           </td><td>scrollPane      </td><td>yes   </td></tr>
70  * <tr><td>verticalScrollBarPolicy     </td><td>scrollPane      </td><td>yes   </td></tr>
71  * <tr><td>viewport                    </td><td>scrollPane      </td><td>yes   </td></tr>
72  * <tr><td>viewportBorder              </td><td>scrollPane      </td><td>yes   </td></tr>
73  * <tr><td>viewportBorderBounds        </td><td>scrollPane      </td><td>no    </td></tr>
74  * <tr><td>viewportView                </td><td>viewport        </td><td>no    </td></tr>
75  * <tr><td>wheelScrollingEnabled       </td><td>scrollPane      </td><td>yes   </td></tr>
76  * </table>
77  */
78 public class JScrollPane 
79   extends JComponent 
80   implements Accessible, ScrollPaneConstants
81 {
82   JViewport columnHeader;
83   JViewport rowHeader;
84
85   Component lowerLeft;
86   Component lowerRight;
87   Component upperLeft;
88   Component upperRight;
89
90   JScrollBar horizontalScrollBar;
91   int horizontalScrollBarPolicy;
92   JScrollBar verticalScrollBar;
93   int verticalScrollBarPolicy;
94
95   JViewport viewport;
96   Border viewportBorder;
97   boolean wheelScrollingEnabled;
98   ChangeListener scrollListener;  
99
100   public static final String COLUMN_HEADER_CHANGED_PROPERTY = "columnHeader";
101   public static final String COMPONENT_ORIENTATION_CHANGED_PROPERTY = "componentOrientation";
102   public static final String HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY = "horizontalScrollBar";
103   public static final String HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "horizontalScrollBarPolicy";
104   public static final String LAYOUT_CHANGED_PROPERTY = "layout";
105   public static final String ROW_HEADER_CHANGED_PROPERTY = "rowHeader";
106   public static final String VERTICAL_SCROLLBAR_CHANGED_PROPERTY = "verticalScrollBar";
107   public static final String VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "verticalScrollBarPolicy";
108   public static final String VIEWPORT_CHANGED_PROPERTY = "viewport";
109   public static final String VIEWPORT_BORDER_CHANGED_PROPERTY = "viewportBorder";
110   public static final String WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY = "wheelScrollingEnabled";
111
112   public JViewport getColumnHeader()
113   {
114     return columnHeader;
115   }
116
117   public Component getCorner(String key) {
118     if (getComponentOrientation() 
119         == ComponentOrientation.LEFT_TO_RIGHT)
120       {
121         if (key == LOWER_LEADING_CORNER)
122           key = LOWER_LEFT_CORNER;
123         else if (key == LOWER_TRAILING_CORNER)
124           key = LOWER_RIGHT_CORNER;
125         else if (key == UPPER_LEADING_CORNER)
126           key = UPPER_LEFT_CORNER;
127         else if (key == UPPER_TRAILING_CORNER)
128           key = UPPER_RIGHT_CORNER;
129       }
130     else if (getComponentOrientation() 
131              == ComponentOrientation.RIGHT_TO_LEFT)
132       {
133         if (key == LOWER_LEADING_CORNER)
134           key = LOWER_RIGHT_CORNER;
135         else if (key == LOWER_TRAILING_CORNER)
136           key = LOWER_LEFT_CORNER;
137         else if (key == UPPER_LEADING_CORNER)
138           key = UPPER_RIGHT_CORNER;
139         else if (key == UPPER_TRAILING_CORNER)
140           key = UPPER_LEFT_CORNER;
141       }
142
143     if (key == LOWER_RIGHT_CORNER)
144       return lowerRight;
145     else if (key == UPPER_RIGHT_CORNER)
146       return upperRight;
147     else if (key == LOWER_LEFT_CORNER)
148       return lowerLeft;
149     else if (key == UPPER_LEFT_CORNER)
150       return upperLeft;
151     return null;
152   }
153
154   public JScrollBar getHorizontalScrollBar()
155   {
156     return horizontalScrollBar;
157   }
158
159   public int getHorizontalScrollBarPolicy()
160   {
161     return horizontalScrollBarPolicy;
162   }
163
164   public JViewport getRowHeader()
165   {
166     return rowHeader;
167   }
168
169   public JScrollBar getVerticalScrollBar()
170   {
171     return verticalScrollBar;
172   }
173
174   public int getVerticalScrollBarPolicy()
175   {
176     return verticalScrollBarPolicy;
177   }
178
179   public JViewport getViewport()
180   {
181     return viewport;
182   }
183
184   public Border getViewportBorder()
185   {
186     return viewportBorder;
187   }
188
189   public Rectangle getViewportBorderBounds()
190   {
191     if (viewportBorder == null)
192       {
193         if (getViewport() == null)
194           return new Rectangle(0,0,0,0);
195         else
196           return getViewport().getBounds();
197       }
198     else
199       {
200         Insets i = viewportBorder.getBorderInsets(getViewport());
201         if (getViewport() == null)
202           return new Rectangle(0,0,
203                                i.left+i.right, i.top+i.bottom);
204         else
205           {
206             Rectangle b = getViewport().getBounds();
207             return new Rectangle(b.x - i.left, 
208                                  b.y - i.top,
209                                  b.width + i.left + i.right, 
210                                  b.height + i.top + i.bottom);
211           }
212       }
213   }
214   
215   public boolean isWheelScrollingEnabled()
216   {
217     return wheelScrollingEnabled;
218   }
219
220
221
222   private void sync()
223   {
224     LayoutManager m = super.getLayout();
225     if (m != null && m instanceof ScrollPaneLayout)
226       {
227         ScrollPaneLayout sl = (ScrollPaneLayout) m;
228         sl.syncWithScrollPane(this);
229       }
230   }
231
232   private void removeNonNull(Component c)
233   {
234     if (c != null)
235       remove(c);
236   }
237
238   private void addNonNull(Component c)
239   {
240     if (c != null)
241       add(c);
242   }
243
244   public void setComponentOrientation(ComponentOrientation co)
245   {
246     ComponentOrientation old = super.getComponentOrientation();
247     super.setComponentOrientation(co);
248     firePropertyChange(COMPONENT_ORIENTATION_CHANGED_PROPERTY, old, co);
249     sync();
250   }
251
252   public void setColumnHeader(JViewport h)
253   {
254     JViewport old = columnHeader;
255     removeNonNull(old);
256     columnHeader = h;
257     addNonNull(h);
258     firePropertyChange(COLUMN_HEADER_CHANGED_PROPERTY, old, h);
259     sync();
260   }
261
262   public void setColumnHeaderView(Component c)
263   {
264     if (columnHeader == null)
265       setColumnHeader(createViewport());
266     columnHeader.setView(c);
267     sync();
268   }
269
270   public void setCorner(String key, Component c)
271   {
272     if (getComponentOrientation() 
273         == ComponentOrientation.LEFT_TO_RIGHT)
274       {
275         if (key == LOWER_LEADING_CORNER)
276           key = LOWER_LEFT_CORNER;
277         else if (key == LOWER_TRAILING_CORNER)
278           key = LOWER_RIGHT_CORNER;
279         else if (key == UPPER_LEADING_CORNER)
280           key = UPPER_LEFT_CORNER;
281         else if (key == UPPER_TRAILING_CORNER)
282           key = UPPER_RIGHT_CORNER;
283       }
284     else if (getComponentOrientation() 
285              == ComponentOrientation.RIGHT_TO_LEFT)
286       {
287         if (key == LOWER_LEADING_CORNER)
288           key = LOWER_RIGHT_CORNER;
289         else if (key == LOWER_TRAILING_CORNER)
290           key = LOWER_LEFT_CORNER;
291         else if (key == UPPER_LEADING_CORNER)
292           key = UPPER_RIGHT_CORNER;
293         else if (key == UPPER_TRAILING_CORNER)
294           key = UPPER_LEFT_CORNER;
295       }
296
297     if (key == LOWER_RIGHT_CORNER)
298       {
299         removeNonNull(lowerRight);
300         lowerRight = c;
301         addNonNull(c);
302       }
303     else if (key == UPPER_RIGHT_CORNER)
304       {
305         removeNonNull(upperRight);
306         upperRight = c;
307         addNonNull(c);
308       }
309     else if (key == LOWER_LEFT_CORNER)
310       {
311         removeNonNull(lowerLeft);
312         lowerLeft = c;
313         addNonNull(c);
314       }
315     else if (key == UPPER_LEFT_CORNER)
316       {
317         removeNonNull(upperLeft);
318         upperLeft = c;
319         addNonNull(c);
320       }
321     else
322       throw new IllegalArgumentException("unknown corner " + key);
323     sync();
324   }
325
326   public void setHorizontalScrollBar(JScrollBar h)
327   {
328     JScrollBar old = horizontalScrollBar;
329     removeNonNull(old);
330     horizontalScrollBar = h;
331     addNonNull(h);
332     firePropertyChange(HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY, old, h);
333     sync();
334
335     if (old != null)
336       {
337         BoundedRangeModel model = old.getModel();
338         if (model != null)
339           model.removeChangeListener(scrollListener);
340       }
341     if (h != null)
342       {
343         BoundedRangeModel model = h.getModel();
344         if (model != null)
345           model.addChangeListener(scrollListener);
346       }
347   }
348
349   public void setHorizontalScrollBarPolicy(int h)
350   {    
351     if (h != HORIZONTAL_SCROLLBAR_AS_NEEDED
352         && h != HORIZONTAL_SCROLLBAR_NEVER
353         && h != HORIZONTAL_SCROLLBAR_ALWAYS)
354       throw new IllegalArgumentException("unknown horizontal scrollbar policy");    
355     int old = horizontalScrollBarPolicy;
356     horizontalScrollBarPolicy = h;
357     firePropertyChange(HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, h);
358     sync();
359   }
360
361   public void setLayout(LayoutManager l)
362   {
363     LayoutManager old = super.getLayout();
364     ScrollPaneLayout tmp = (ScrollPaneLayout) l;
365     super.setLayout(l);
366     tmp.syncWithScrollPane(this);
367     firePropertyChange(LAYOUT_CHANGED_PROPERTY, old, l);
368     sync();
369   }
370
371   public void setRowHeader(JViewport v)
372   {
373     JViewport old = rowHeader;
374     removeNonNull(old);
375     rowHeader = v;
376     addNonNull(v);
377     firePropertyChange(ROW_HEADER_CHANGED_PROPERTY, old, v);
378     sync();
379   }
380
381   public void setRowHeaderView(Component c)
382   {
383     if (rowHeader == null)
384       setRowHeader(createViewport());
385     rowHeader.setView(c);
386     sync();
387   }
388
389   public void setVerticalScrollBar(JScrollBar v)
390   {
391     JScrollBar old = verticalScrollBar;
392     removeNonNull(old);
393     verticalScrollBar = v;
394     addNonNull(v);
395     firePropertyChange(VERTICAL_SCROLLBAR_CHANGED_PROPERTY, old, v);
396     sync();
397
398     if (old != null)
399       {
400         BoundedRangeModel model = old.getModel();
401         if (model != null)
402           model.removeChangeListener(scrollListener);
403       }
404     if (v != null)
405       {
406         BoundedRangeModel model = v.getModel();
407         if (model != null)
408           model.addChangeListener(scrollListener);
409       }
410   }
411
412   public void setVerticalScrollBarPolicy(int v)
413   {
414     if (v != VERTICAL_SCROLLBAR_AS_NEEDED
415         && v != VERTICAL_SCROLLBAR_NEVER
416         && v != VERTICAL_SCROLLBAR_ALWAYS)
417       throw new IllegalArgumentException("unknown vertical scrollbar policy");    
418     int old = verticalScrollBarPolicy;
419     verticalScrollBarPolicy = v;
420     firePropertyChange(VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, v);
421     sync();
422   }
423
424   public void setWheelScrollingEnabled(boolean b)
425   {
426     boolean old = wheelScrollingEnabled;
427     wheelScrollingEnabled = b;
428     firePropertyChange(WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY, old, b);
429     sync();
430   }
431
432   public void setViewport(JViewport v)
433   {
434     JViewport old = viewport;
435     removeNonNull(old);
436     if (old != null)
437       old.removeChangeListener(scrollListener);
438     viewport = v;
439     if (v != null)
440       v.addChangeListener(scrollListener);
441     addNonNull(v);
442     revalidate();
443     repaint();
444     firePropertyChange(VIEWPORT_CHANGED_PROPERTY, old, v);
445     sync();
446   }
447
448   public void setViewportBorder(Border b)
449   {
450     Border old = viewportBorder;
451     viewportBorder = b;
452     firePropertyChange(VIEWPORT_BORDER_CHANGED_PROPERTY, old, b);
453     sync();
454   }
455     
456   public void setViewportView(Component view)
457   {
458     if (getViewport() == null)
459       {
460         setViewport(createViewport());
461       }
462         
463     if (view != null)
464       {
465         getViewport().setView(view);
466       }
467     sync();
468   }
469
470   public boolean isValidateRoot()
471   {
472     return true;
473   }
474
475   ChangeListener createScrollListener()
476   {
477     return new ChangeListener() 
478       {
479         
480         public void stateChanged(ChangeEvent event)
481         {
482           JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
483           JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
484           JViewport vp = JScrollPane.this.getViewport();
485
486           if (vp != null && event.getSource() == vp)
487             {
488               // if the viewport changed, we should update the VSB / HSB
489               // models according to the new vertical and horizontal sizes
490               Rectangle vr = vp.getViewRect();
491               Dimension vs = vp.getViewSize();
492               // System.err.println("got change from viewport, vr=" + vr + ", vs=" + vs);
493               if (vsb != null
494                   && (vsb.getMinimum() != 0
495                       || vsb.getMaximum() != vs.height
496                       || vsb.getValue() != vr.y
497                       || vsb.getVisibleAmount() != vr.height))
498                 {
499                   //                   System.err.println("setting vsb to "
500                   //                                      + "pos=" + vr.y 
501                   //                                      + ", ext=" + vr.height 
502                   //                                      + ", min=0"
503                   //                                      + ", max=" + vs.height);
504                   vsb.setValue(vr.y, vr.height, 0, vs.height);
505                 }
506
507               if (hsb != null
508                   && (hsb.getMinimum() != 0
509                       || hsb.getMaximum() != vs.width
510                       || hsb.getValue() != vr.width
511                       || hsb.getVisibleAmount() != vr.height))
512                 hsb.setValue(vr.x, vr.width, 0, vs.width);
513             }
514           else
515             {
516               // otherwise we got a change update from either the VSB or
517               // HSB model, and we need to update the viewport position to
518               // match.
519
520               int xpos = 0;
521               int ypos = 0;
522               
523               if (vsb != null)
524                 ypos = vsb.getValue();
525               
526               if (hsb != null)
527                 xpos = hsb.getValue();
528
529               Point pt = new Point(xpos, ypos);
530
531               if (vp != null
532                   && vp.getViewPosition() != pt)
533                 vp.setViewPosition(pt);
534             }
535         }
536       };
537   }
538
539
540   public JScrollPane() 
541   {
542     this(null);
543   }
544     
545   public JScrollPane(Component view) 
546   {
547     this(view, 
548          VERTICAL_SCROLLBAR_AS_NEEDED, 
549          HORIZONTAL_SCROLLBAR_AS_NEEDED);
550   }
551
552   public JScrollPane(int vsbPolicy, int hsbPolicy) 
553   {
554     this(null, vsbPolicy, hsbPolicy);
555   }
556
557   public JScrollPane(Component view, int vsbPolicy, int hsbPolicy) 
558   {
559     scrollListener = createScrollListener();
560     setVerticalScrollBarPolicy(vsbPolicy);
561     setVerticalScrollBar(createVerticalScrollBar());
562     setHorizontalScrollBarPolicy(hsbPolicy);
563     setHorizontalScrollBar(createHorizontalScrollBar());
564     setViewportView(view);
565     setLayout(new ScrollPaneLayout());
566     setOpaque(false);
567     updateUI();
568   }
569
570   
571   public JScrollBar createHorizontalScrollBar()
572   {
573     return new ScrollBar(SwingConstants.HORIZONTAL);
574   }
575
576   public JScrollBar createVerticalScrollBar()
577   {
578     return new ScrollBar(SwingConstants.VERTICAL);
579   }
580     
581   public JViewport createViewport()
582   {
583     return new JViewport();
584   }
585
586
587   public String getUIClassID()
588   {
589     return "ScrollPaneUI";
590   }
591   
592   public void updateUI()
593   {
594     ScrollPaneUI b = (ScrollPaneUI)UIManager.getUI(this);
595     setUI(b);
596   }  
597
598
599   class ScrollBar 
600     extends JScrollBar
601     implements UIResource
602   {
603     public ScrollBar(int orientation)
604     {
605       super(orientation);
606     }
607
608     public int getBlockIncrement(int direction)
609     {
610       Component view = JScrollPane.this.getViewport().getView();
611       if (view == null || (! (view instanceof Scrollable)))
612         return super.getBlockIncrement(direction);
613       else
614         {
615           Scrollable s = (Scrollable) view;
616           return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(), 
617                                                this.getOrientation(),
618                                                direction);
619         }
620     }
621
622     public int getUnitIncrement(int direction)
623     {
624       Component view = JScrollPane.this.getViewport().getView();
625       if (view == null || (! (view instanceof Scrollable)))
626         return super.getUnitIncrement(direction);
627       else
628         {
629           Scrollable s = (Scrollable) view;
630           return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(), 
631                                               this.getOrientation(),
632                                               direction);
633         }
634     }
635
636
637   }
638   
639 }