KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > scrollbars > api > ScrollbarFactory


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 /*
20  * ScrollbarFactory.java
21  *
22  * Created on May 9, 2004, 7:19 PM
23  */

24
25 package org.netbeans.swing.scrollbars.api;
26
27 import java.awt.Color JavaDoc;
28 import java.awt.Dimension JavaDoc;
29 import java.awt.Graphics JavaDoc;
30 import java.awt.Point JavaDoc;
31 import java.awt.Rectangle JavaDoc;
32 import java.awt.event.AdjustmentEvent JavaDoc;
33 import java.awt.event.AdjustmentListener JavaDoc;
34 import java.awt.event.MouseAdapter JavaDoc;
35 import java.awt.event.MouseEvent JavaDoc;
36 import java.beans.PropertyChangeEvent JavaDoc;
37 import java.beans.PropertyChangeListener JavaDoc;
38 import org.netbeans.swing.scrollbars.impl.MetalMarkedScrollBarUI;
39 import org.netbeans.swing.scrollbars.impl.WindowsMarkedScrollBarUI;
40 import org.netbeans.swing.scrollbars.impl.GenericScrollbarUI;
41 import org.netbeans.swing.scrollbars.spi.MarkingModel;
42
43 import javax.swing.*;
44 import javax.swing.event.ChangeEvent JavaDoc;
45 import javax.swing.event.ChangeListener JavaDoc;
46 import javax.swing.plaf.ScrollBarUI JavaDoc;
47 import org.netbeans.swing.scrollbars.spi.Mark;
48
49 /**
50  * Factory that will produce an appropriate scrollbar for a marking model.
51  *
52  * @author Tim Boudreau
53  */

54 public class ScrollbarFactory {
55     /** Creates a new instance of ScrollbarFactory */
56     private ScrollbarFactory() {
57     }
58     
59     private static MarkingModel currMdl = null;
60     public static JScrollPane createScrollPane (MarkingModel mdl) {
61         currMdl = mdl;
62         JScrollPane result = new Pane(mdl);
63         currMdl = null;
64         return result;
65     }
66     
67     private static final class Pane extends JScrollPane {
68         private final MarkingModel mdl;
69         
70         Pane (MarkingModel mdl) {
71             this.mdl = mdl;
72         }
73         
74         public JScrollBar createVerticalScrollBar() {
75             MarkingModel mdl = this.mdl;
76             if (mdl == null) {
77                 //Unfortunately, this method is called in the superclass
78
//constructor, and can't return null
79
mdl = currMdl;
80             }
81             String JavaDoc id = UIManager.getLookAndFeel().getID();
82             JScrollBar result;
83             if ("Windows".equals(id)) {
84                 result = new ScrollBar(JScrollBar.VERTICAL);
85                 result.setUI (new WindowsMarkedScrollBarUI (mdl));
86             } else if ("Metal".equals(id)) {
87                 result = new ScrollBar(JScrollBar.VERTICAL);
88                 result.setUI (new MetalMarkedScrollBarUI (mdl));
89             } else {
90                 result = new GenericMarkedScrollbar(
91                     super.createVerticalScrollBar(), mdl);
92             }
93             return result;
94         }
95         
96         private class GenericMarkedScrollbar extends JScrollBar implements
97             PropertyChangeListener JavaDoc, AdjustmentListener JavaDoc, ChangeListener JavaDoc {
98             
99             private final MarkingModel mdl;
100             private JScrollBar delegate;
101             public GenericMarkedScrollbar (JScrollBar delegate, MarkingModel mdl) {
102                 this.mdl = mdl;
103                 init(delegate);
104             }
105
106             public void addNotify() {
107                 super.addNotify();
108                 System.err.println("ADD NOTIFY - MODEL IS " + mdl);
109                 mdl.addChangeListener (this);
110                 ToolTipManager.sharedInstance().registerComponent(this);
111             }
112
113             public void removeNotify () {
114                 mdl.removeChangeListener (this);
115                 ToolTipManager.sharedInstance().unregisterComponent(this);
116                 super.removeNotify();
117             }
118
119             private void init(JScrollBar delegate) {
120                 this.delegate = delegate;
121                 delegate.addPropertyChangeListener(this);
122                 delegate.addAdjustmentListener(this);
123                 add (delegate);
124                 addMouseListener (new MarkAndTrackListener());
125             }
126
127             private int getGap() {
128                 return 8;
129             }
130
131             private int getMargin() {
132                 return 2;
133             }
134
135             public String JavaDoc getToolTipText (MouseEvent JavaDoc me) {
136                 Rectangle JavaDoc r = getMarksRect();
137                 Point JavaDoc p = me.getPoint();
138                 if (r.contains (p)) {
139                     Mark m = markAtPoint (p);
140                     if (m != null) {
141                         return m.getText();
142                     }
143                 }
144                 return null;
145             }
146
147             public void paintComponent (Graphics JavaDoc g) {
148                 super.paintComponent (g);
149                 paintMarks(g);
150             }
151
152             /** Get the rectangle within which marks can be displayed.
153              * @return The rectangle
154              */

155             protected final Rectangle JavaDoc getMarksRect () {
156                 Rectangle JavaDoc r = new Rectangle JavaDoc (0, 0, getWidth(), getHeight());
157                 if (getOrientation() == HORIZONTAL) {
158                     r.y = r.height - getGap();
159                     r.height -= getGap();
160                 } else {
161                     r.x = r.width - getGap();
162                     r.width -= getGap();
163                 }
164                 return r;
165             }
166
167             /** Get the total number of possible thumb positions on the resizable axis of the
168              * scrollbar - the track height or width, depending on the scrollbar's
169              * orientation
170              * @return The total
171              */

172             protected final int getVisibleRange () {
173                 Rectangle JavaDoc mrect = getMarksRect();
174                 return (getOrientation() == JScrollBar.VERTICAL) ?
175                     mrect.height : mrect.width;
176             }
177
178             /** Translate a location as given by a call to <code>someMark.getStart()</code>
179              * into the coordinate space of the scrollbar.
180              * @param loc The location given by the Mark object
181              * @param max The maximum, given by the model
182              * @return The coordinate in the space of the scrollbar, as a position along the
183              * scrollbar's resizable axis.
184              */

185             protected final int translate (int loc, int max) {
186                 int range = getVisibleRange();
187                 double factor = range / max;
188                 double pos = factor * loc;
189                 return Math.round(Math.round(pos));
190             }
191
192             private java.util.HashMap JavaDoc marksRects = new java.util.HashMap JavaDoc();
193             /** Find the mark at a given point in the component's coordinate space
194              * @return The Mark object at that point, or null
195              * @param p A point in the scrollbar's coordinate space
196              */

197             public Mark markAtPoint (Point JavaDoc p) {
198                 Rectangle JavaDoc rect = getMarksRect();
199                 if (!(rect.contains(p))) return null;
200                 java.util.Iterator JavaDoc i = marksRects.keySet().iterator();
201                 while (i.hasNext()) {
202                     Rectangle JavaDoc r = (Rectangle JavaDoc) i.next();
203                     if (r.contains(p)) return (Mark) marksRects.get(r);
204                 }
205                 return null;
206             }
207
208             /** Paint the marks displayed by this component. Calculates the rectangle of the
209              * mark and calls <code>paintMark()</code> with it.
210              * @param g The Graphics object passed to the paint method
211              */

212             public void paintMarks (Graphics JavaDoc g) {
213                 boolean vertical = getOrientation() == JScrollBar.VERTICAL;
214
215                 Rectangle JavaDoc r = getMarksRect();
216                 if (mdl.size() == 0) return;
217
218                 int markRange = mdl.getMaxMarkLocation();
219                 java.util.Enumeration JavaDoc e = mdl.getMarks();
220
221                 while (e.hasMoreElements()) {
222                     Mark m = (Mark) e.nextElement();
223                     Rectangle JavaDoc curr;
224                     if (vertical) {
225                         r.y = translate (m.getStart(), markRange);
226                         r.height = Math.max(getGap(), translate (m.getLength(), markRange));
227                         r.width = getGap();
228                         curr = new Rectangle JavaDoc(r.x-2, r.y, r.width+2, r.height);
229                         marksRects.put (curr, m);
230                     } else {
231                         r.x = translate (m.getStart(), markRange);
232                         r.width = Math.max(getGap(), translate (m.getLength(), markRange));
233                         r.height = getGap();
234                         curr = new Rectangle JavaDoc(r.x, r.y, r.width, r.height);
235                         marksRects.put (curr, m);
236                     }
237                     Color JavaDoc color = (Color JavaDoc) m.get ("color"); //NOI18N
238
if (color == null) {
239                         color = UIManager.getColor("windowText"); //NOI18N
240
}
241         // System.err.println ("Mark " + m + " rect " + r);
242
g.setColor (color);
243                     g.fillRect (r.x + getMargin(), r.y, r.width-getMargin()-1, r.height);
244                     g.setColor (color.darker());
245                     g.drawRect (r.x + getMargin(), r.y, r.width-getMargin()-1, r.height);
246                 }
247             }
248
249             public void updateUI() {
250                 if (getUI() == null) {
251                     setUI ((ScrollBarUI) GenericScrollbarUI.createUI(this));
252                 }
253             }
254
255             public void doLayout() {
256                 delegate.setBounds (0, 0, getWidth() - getGap(), getHeight());
257             }
258
259             public BoundedRangeModel getModel() {
260                 return delegate.getModel();
261             }
262
263             public void setModel (BoundedRangeModel mdl) {
264                 delegate.setModel (mdl);
265             }
266
267
268             public int getMaximum() {
269                 return delegate.getMaximum();
270             }
271
272             public int getMinimum() {
273                 return delegate.getMinimum();
274             }
275
276             public int getOrientation() {
277                 return delegate.getOrientation();
278             }
279
280             public void setOrientation (int o) {
281                 delegate.setOrientation(o);
282             }
283
284             public int getBlockIncrement() {
285                 return delegate.getBlockIncrement();
286             }
287
288             public int getUnitIncrement() {
289                 return delegate.getUnitIncrement();
290             }
291
292             public int getUnitIncrement(int dir) {
293                 return delegate.getUnitIncrement(dir);
294             }
295
296             public int getVisibleAmount() {
297                 return delegate.getVisibleAmount();
298             }
299
300             public void setEnabled (boolean val) {
301                 super.setEnabled(val);
302                 delegate.setEnabled(val);
303             }
304
305             public void setBlockIncrement (int val) {
306                 delegate.setBlockIncrement(val);
307             }
308
309             public void setValueIsAdjusting (boolean val) {
310                 delegate.setValueIsAdjusting(val);
311             }
312
313             public void setValues (int newValue, int newExtent, int newMin, int newMax) {
314                 delegate.setValues (newValue, newExtent, newMin, newMax);
315             }
316
317             public void setVisibleAmount (int val) {
318                 delegate.setVisibleAmount(val);
319             }
320
321             public boolean getValueIsAdjusting() {
322                 return delegate.getValueIsAdjusting();
323             }
324
325             public int getValue() {
326                 return delegate.getValue();
327             }
328
329             public void setValue (int i) {
330                 delegate.setValue(i);
331             }
332
333             public Dimension JavaDoc getPreferredSize() {
334                 Dimension JavaDoc result = new Dimension JavaDoc (delegate.getPreferredSize());
335                 if (getOrientation() == HORIZONTAL) {
336                     result.height += getGap();
337                 } else {
338                     result.width += getGap();
339                 }
340                 return result;
341             }
342
343             public Dimension JavaDoc getMaximumSize() {
344                 Dimension JavaDoc result = new Dimension JavaDoc (delegate.getMaximumSize());
345                 if (getOrientation() == HORIZONTAL) {
346                     result.height += getGap();
347                 } else {
348                     result.width += getGap();
349                 }
350                 return result;
351             }
352
353             public Dimension JavaDoc getMinimumSize() {
354                 Dimension JavaDoc result = new Dimension JavaDoc (delegate.getMaximumSize());
355                 if (getOrientation() == HORIZONTAL) {
356                     result.height += getGap();
357                 } else {
358                     result.width += getGap();
359                 }
360                 return result;
361             }
362
363             /**
364              * This method gets called when a bound property is changed.
365              *
366              * @param evt A PropertyChangeEvent object describing the event source
367              * and the property that has changed.
368              */

369             public void propertyChange(PropertyChangeEvent JavaDoc evt) {
370                 String JavaDoc name = evt.getPropertyName();
371                 Object JavaDoc newValue = evt.getNewValue();
372                 Object JavaDoc oldValue = evt.getOldValue();
373                 if ("preferredSize".equals(name) || "minimumSize".equals(name) || "maximumSize".equals(name)) { //NOI18N
374
newValue = new Dimension JavaDoc ((Dimension JavaDoc) newValue);
375                     oldValue = new Dimension JavaDoc ((Dimension JavaDoc) oldValue);
376                     if (getOrientation() == JScrollBar.VERTICAL) {
377                         ((Dimension JavaDoc) newValue).width += getGap();
378                         ((Dimension JavaDoc) oldValue).width += getGap();
379                     } else {
380                         ((Dimension JavaDoc) newValue).height += getGap();
381                         ((Dimension JavaDoc) oldValue).height += getGap();
382                     }
383                 }
384                 firePropertyChange (evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
385             }
386
387             /**
388              * Invoked when the value of the adjustable has changed.
389              */

390             public void adjustmentValueChanged(AdjustmentEvent JavaDoc e) {
391                 fireAdjustmentValueChanged(e.getID(), e.getAdjustmentType(), e.getValue());
392             }
393
394             private void goToMark (Mark m) {
395                 Rectangle JavaDoc r = getMarksRect();
396                 int loc = translate (m.getStart(), r.height);
397                 setValue(translateToScrollbarModel (loc));
398                 m.select();
399             }
400
401             private int translateToScrollbarModel (int i) {
402                 BoundedRangeModel mod = getModel();
403                 int min = mod.getMinimum();
404                 int max = mod.getMaximum();
405                 int mrange = max - min;
406
407                 double factor = mrange / mdl.getMaxMarkLocation();
408                 double pos = (i * factor) + min;
409                 return Math.round(Math.round(pos));
410             }
411
412             /**
413              * Invoked when the target of the listener has changed its state.
414              *
415              * @param e a ChangeEvent object
416              */

417             public void stateChanged(ChangeEvent JavaDoc e) {
418                 Rectangle JavaDoc r = getMarksRect();
419                 repaint(r.x, r.y, r.width, r.height);
420             }
421
422             protected class MarkAndTrackListener extends MouseAdapter JavaDoc {
423                 public void mousePressed (MouseEvent JavaDoc e) {
424                     if (getValueIsAdjusting ()) {
425                         super.mousePressed (e);
426                         return;
427                     }
428                     if (SwingUtilities.isRightMouseButton(e) ||
429                      SwingUtilities.isMiddleMouseButton(e) || !isEnabled()) {
430                         return;
431                     }
432
433                     Point JavaDoc p = e.getPoint();
434                     Rectangle JavaDoc r = getMarksRect();
435
436                     if (r.contains (p)) {
437                         Mark m = markAtPoint (p);
438                         if (m != null) {
439                             goToMark (m);
440                         }
441                     } else {
442                         super.mousePressed(e);
443                     }
444                 }
445             }
446         }
447     }
448 }
449
Popular Tags