KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > swingwtx > swing > JScrollPane


1 /*
2    SwingWT
3    Copyright(c)2003-2004, R. Rawson-Tetley
4
5    For more information on distributing and using this program, please
6    see the accompanying "COPYING" file.
7
8    Contact me by electronic mail: bobintetley@users.sourceforge.net
9
10    $Log: JScrollPane.java,v $
11    Revision 1.30 2004/05/05 13:24:32 bobintetley
12    Bugfixes and Laurent's patch for binary compatibility on Container.add()
13
14    Revision 1.29 2004/04/30 16:52:17 bobintetley
15    MenuListener support, JViewport support, TreeSelectionModel stubs, additional JTree methods
16
17    Revision 1.28 2004/03/30 10:42:46 bobintetley
18    Many minor bug fixes, event improvements by Dan Naab. Full swing.Icon support
19
20    Revision 1.27 2004/02/27 16:52:58 bobintetley
21    Scrollpane activation fixes, modern tabbedpane usage for JClosableTabbedPane
22
23    Revision 1.26 2004/02/27 16:16:15 bobintetley
24    Threading fixes
25
26    Revision 1.25 2004/02/22 19:30:23 bobintetley
27    Horizontal fixes
28
29    Revision 1.24 2004/02/22 08:38:20 bobintetley
30    Fixed scrollbar interaction with JTextArea
31
32    Revision 1.23 2004/02/03 11:20:27 bobintetley
33    JList does not assign listener until data is generated now in default model
34    (prevents flickering)
35
36    Revision 1.22 2004/02/03 08:55:20 bobintetley
37    Corner/Row/Col support for JScrollPane
38
39    Revision 1.21 2004/02/02 14:11:50 bobintetley
40    Tweaks and refining of JScrollPane implementation
41
42    Revision 1.20 2004/02/02 12:36:37 bobintetley
43    Proper JScrollPane/ScrollBar implementation
44
45    Revision 1.19 2004/01/27 09:05:11 bobintetley
46    ListModel and List Selection implemented. ScrollPane fix so all components
47       scrollable
48
49    Revision 1.18 2004/01/26 08:11:00 bobintetley
50    Many bugfixes and addition of SwingSet
51
52    Revision 1.17 2004/01/16 09:35:47 bobintetley
53    Full event dispatch thread support!
54
55    Revision 1.16 2004/01/05 11:31:48 bobintetley
56    More layout fixes
57
58    Revision 1.15 2003/12/17 09:03:14 bobintetley
59    Closely matches Swing behaviour + JScrollPane support for Panels
60
61    Revision 1.14 2003/12/16 09:19:02 bobintetley
62    Various small fixes to match Swing more closely
63
64    Revision 1.13 2003/12/15 18:29:57 bobintetley
65    Changed setParent() method to setSwingWTParent() to avoid conflicts with applications
66
67    Revision 1.12 2003/12/15 16:40:04 bobintetley
68    Core methods + skeleton JTableHeader/JScrollBar support
69
70    Revision 1.11 2003/12/15 15:54:25 bobintetley
71    Additional core methods
72
73    Revision 1.10 2003/12/14 09:13:38 bobintetley
74    Added CVS log to source headers
75
76 */

77
78
79 package swingwtx.swing;
80
81 import swingwt.awt.BorderLayout;
82 import swingwt.awt.Component;
83 import swingwt.awt.Container;
84 import swingwt.awt.Dimension;
85 import swingwt.awt.event.AdjustmentEvent;
86 import swingwt.awt.event.AdjustmentListener;
87 import swingwt.awt.event.ComponentEvent;
88 import swingwt.awt.event.ComponentListener;
89 import swingwt.awt.event.ContainerEvent;
90 import swingwt.awt.event.ContainerListener;
91 import swingwtx.swing.border.Border;
92
93 public class JScrollPane extends JPanel implements AdjustmentListener {
94
95     public final static int VERTICAL_SCROLLBAR_ALWAYS = 0;
96     public final static int VERTICAL_SCROLLBAR_AS_NEEDED = 1;
97     public final static int VERTICAL_SCROLLBAR_NEVER = 2;
98     public final static int HORIZONTAL_SCROLLBAR_ALWAYS = 3;
99     public final static int HORIZONTAL_SCROLLBAR_AS_NEEDED = 4;
100     public final static int HORIZONTAL_SCROLLBAR_NEVER = 5;
101     
102     public final static String JavaDoc VIEWPORT = "VIEWPORT";
103     public final static String JavaDoc VERTICAL_SCROLLBAR = "VERTICAL_SCROLLBAR";
104     public final static String JavaDoc HORIZONTAL_SCROLLBAR = "HORIZONTAL_SCROLLBAR";
105     public final static String JavaDoc ROW_HEADER = "ROW_HEADER";
106     public final static String JavaDoc COLUMN_HEADER = "COLUMN_HEADER";
107     public final static String JavaDoc LOWER_LEFT_CORNER = "LOWER_LEFT_CORNER";
108     public final static String JavaDoc LOWER_RIGHT_CORNER = "LOWER_RIGHT_CORNER";
109     public final static String JavaDoc UPPER_LEFT_CORNER = "UPPER_LEFT_CORNER";
110     public final static String JavaDoc UPPER_RIGHT_CORNER = "UPPER_RIGHT_CORNER";
111     public final static String JavaDoc LOWER_LEADING_CORNER = "LOWER_LEADING_CORNER";
112     public final static String JavaDoc LOWER_TRAILING_CORNER = "LOWER_TRAILING_CORNER";
113     public final static String JavaDoc UPPER_LEADING_CORNER = "UPPER_LEADING_CORNER";
114     public final static String JavaDoc UPPER_TRAILING_CORNER = "UPPER_TRAILING_CORNER";
115     public final static String JavaDoc VERTICAL_SCROLLBAR_POLICY = "VERTICAL_SCROLLBAR_POLICY";
116     public final static String JavaDoc HORIZONTAL_SCROLLBAR_POLICY = "HORIZONTAL_SCROLLBAR_POLICY";
117     
118     protected final static int BAR_SCALE_FACTOR = 10; // The difference between the bar scale and pixels
119

120     protected int verticalPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
121     protected int horizontalPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
122     
123     protected JScrollBar hbar = new JScrollBar(JScrollBar.HORIZONTAL);
124     protected JScrollBar vbar = new JScrollBar(JScrollBar.VERTICAL);
125     
126     protected swingwt.awt.Component childComponent = null;
127     
128     protected JPanel northPanel = new JPanel();
129     protected JPanel westPanel = new JPanel();
130     protected JPanel southPanel = new JPanel();
131     
132     protected Component columnView = null;
133     protected Component rowView = null;
134     
135     protected int ypix = 0; // The number of vertical pixels down the scroller we are
136
protected int xpix = 0; // The number of horizontal pixels across the scroller we are
137

138     protected int showY = 0; // Visible pixel height
139
protected int realY = 0; // Workspace height
140
protected int diffY = 0; // Difference
141
protected int showX = 0; // Visible pixel width
142
protected int realX = 0; // Workspace width
143
protected int diffX = 0; // Difference
144

145     protected boolean deactivated = false; // Whether the scrollpane contains a component that can handle it's own
146
// scrollbars. This prevents flickers and strange behaviour later on
147

148
149     protected JViewport view = new JViewport(this);
150     
151     public JScrollPane() { this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); }
152     public JScrollPane(swingwt.awt.Component component) { this(component, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); }
153     public JScrollPane(int vsbPolicy, int hsbPolicy) { this(null, vsbPolicy, hsbPolicy);}
154     
155     public JScrollPane(swingwt.awt.Component component, int vsbPolicy, int hsbPolicy) {
156         
157         verticalPolicy = vsbPolicy;
158         horizontalPolicy = hsbPolicy;
159         
160         layoutScrollPane();
161         add(component);
162         
163         if (!deactivated) {
164             addComponentListener(new ComponentListener() {
165                 public void componentResized(ComponentEvent e) {
166                     calculateBarSize();
167                 }
168                 public void componentMoved(ComponentEvent e) {
169                     calculateBarSize();
170                 }
171                 public void componentShown(ComponentEvent e) {
172                     calculateBarSize();
173                 }
174                 public void componentHidden(ComponentEvent e) {
175                     calculateBarSize();
176                 }
177             });
178             addContainerListener(new ContainerListener() {
179                 public void componentAdded(ContainerEvent e) {calculateBarSize();}
180                 public void componentRemoved(ContainerEvent e) {calculateBarSize();}
181             });
182         }
183     }
184     
185     /**
186      * Lays out the scrollpane and puts the bars on
187      * where necessary.
188      */

189     protected void layoutScrollPane() {
190         
191         setLayout(new swingwt.awt.BorderLayout());
192
193         // Setup bars
194
hbar.setUnitIncrement(1);
195         vbar.setUnitIncrement(1);
196         hbar.setBlockIncrement(5);
197         vbar.setBlockIncrement(5);
198
199         // Bordered panels
200
northPanel.setLayout(new BorderLayout());
201         westPanel.setLayout(new BorderLayout());
202
203         super.add(northPanel, BorderLayout.NORTH);
204         super.add(westPanel, BorderLayout.WEST);
205
206         super.add(hbar, swingwt.awt.BorderLayout.SOUTH);
207         super.add(vbar, swingwt.awt.BorderLayout.EAST);
208
209         handleBarVisibility();
210         hbar.addAdjustmentListener(this);
211         vbar.addAdjustmentListener(this);
212
213     }
214     
215     protected void handleBarVisibility() {
216         
217         // If we aren't dealing with a subclass of JPanel or a JLabel,
218
// don't use the scrollbars. This is because SWT widgets handle
219
// their own.
220
if (deactivated) {
221             vbar.setVisible(false);
222             hbar.setVisible(false);
223             return;
224         }
225         
226         if (verticalPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
227             vbar.setVisible(true);
228         }
229         else if (verticalPolicy == VERTICAL_SCROLLBAR_NEVER) {
230             vbar.setVisible(false);
231         }
232         else if (diffY > 0) {
233             vbar.setVisible(true);
234         }
235         else {
236             vbar.setVisible(false);
237         }
238             
239         if (horizontalPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
240             hbar.setVisible(true);
241         }
242         else if (horizontalPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
243             hbar.setVisible(false);
244         }
245         else if (diffX > 0) {
246             hbar.setVisible(true);
247         }
248         else {
249             hbar.setVisible(false);
250         }
251         
252         invalidate();
253         repaint();
254         
255     }
256     
257     protected void calculateBarSize() {
258         
259         // Do nothing if we have no component or we're deactivated
260
if (childComponent == null || deactivated) return;
261         
262         // Get the vertical height of the actual pane, less any
263
// decorations
264
showY = this.getSize().height - hbar.getPeerSize().height;
265         if (columnView != null) showY -= columnView.getPeerSize().height;
266         
267         // Get the height of the contents
268
realY = childComponent.getSize().height;
269         diffY = realY - showY;
270         
271         vbar.setMinimum(0);
272         vbar.setMaximum(diffY / BAR_SCALE_FACTOR);
273         vbar.setValue(0);
274         
275         // Get the horizontal width of the actual pane
276
showX = this.getSize().width - vbar.getPeerSize().width;
277         if (rowView != null) showX -= rowView.getPeerSize().width;
278         
279         // Get the width of the contents
280
realX = childComponent.getSize().width;
281         diffX = realX - showX;
282         
283         hbar.setMinimum(0);
284         hbar.setMaximum(diffX / BAR_SCALE_FACTOR);
285         hbar.setValue(0);
286         
287         // Do we need to show/hide those bars?
288
handleBarVisibility();
289         
290     }
291     
292     public JViewport getViewport() { return view; }
293     
294     public void setViewportBorder(Border b) { setBorder(b); }
295     public Border getViewportBorder() { return getBorder(); }
296     
297     public Component add(Component c) {
298
299         if (c == null) return null;
300
301     // Check if the component can do its own scrollbars
302
checkIfComponentCanHandleItself(c);
303     
304         // Tie this component up to the scrollpane so we can
305
// manipulate scrollbars on components where we are using
306
// this class to wrap them.
307
childComponent = (swingwt.awt.Component) c;
308         JSWTScrollable s = (JSWTScrollable) childComponent;
309         s.setHorizontalScrollPane( horizontalPolicy == HORIZONTAL_SCROLLBAR_ALWAYS || horizontalPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED );
310         s.setVerticalScrollPane( verticalPolicy == VERTICAL_SCROLLBAR_ALWAYS || verticalPolicy == VERTICAL_SCROLLBAR_AS_NEEDED );
311         s.setScrollPane(this);
312         
313         // Do what the superclass normally does
314
return doAdd(c);
315     }
316     
317     public void add(Component c, Object JavaDoc layoutmodifier) {
318         add(c);
319     }
320     
321     public void setViewportView(Component component) {
322         removeAll();
323         add(component);
324     }
325     
326     public int getHorizontalScrollBarPolicy() { return horizontalPolicy; }
327     public void setHorizontalScrollBarPolicy(int policy) { horizontalPolicy = policy; calculateBarSize(); }
328     public int getVerticalScrollBarPolicy() { return verticalPolicy; }
329     public void setVerticalScrollBarPolicy(int policy) { verticalPolicy = policy; calculateBarSize();; }
330     public void setHorizontalScrollBar(JScrollBar bar) { hbar = bar; layoutScrollPane(); calculateBarSize(); }
331     public void setVerticalScrollBar(JScrollBar bar) { vbar = bar; layoutScrollPane(); calculateBarSize(); }
332     public JScrollBar getHorizontalScrollBar() { return hbar; }
333     public JScrollBar getVerticalScrollBar() { return vbar; }
334     
335     public swingwt.awt.Component[] getComponents() { return new swingwt.awt.Component[] { childComponent }; }
336     
337     public void setCorner(String JavaDoc key, Component corner) {
338         if (key.equals(JScrollPane.UPPER_LEFT_CORNER) || key.equals(JScrollPane.UPPER_LEADING_CORNER))
339             northPanel.add(corner, BorderLayout.WEST);
340         if (key.equals(JScrollPane.UPPER_RIGHT_CORNER) || key.equals(JScrollPane.UPPER_TRAILING_CORNER))
341             northPanel.add(corner, BorderLayout.EAST);
342     }
343     public void setColumnHeaderView(Component view) { columnView = view; northPanel.add(view, BorderLayout.CENTER); }
344     public void setRowHeaderView(Component view) { rowView = view; westPanel.add(view, BorderLayout.CENTER); }
345     
346     public void setSwingWTParent(swingwt.awt.Container parent) throws Exception JavaDoc {
347         
348         // Create the peer as usual
349
super.setSwingWTParent(parent);
350         
351         // Do we need to show/hide those bars in light
352
// of child component?
353
handleBarVisibility();
354         
355         // Make sure we are all set up
356
if (!deactivated)
357             SwingUtilities.invokeIn(new Runnable JavaDoc() {
358                 public void run() {
359                     calculateBarSize();
360                     adjustmentValueChanged(null);
361                 }
362             }, 500);
363     }
364     
365     /**
366      * Sets the deactivated flag if the contained component is not
367      * a JPanel or JLabel (the only things you'd want to scroll around
368      * really).
369      */

370     protected void checkIfComponentCanHandleItself(Component c) {
371         deactivated = !(c instanceof JPanel) && !(c instanceof JLabel);
372     }
373     
374     /** Called when the scrollbar is dragged. We simply move the container
375      * holding the components around, relying on the platform widgets/SWT
376      * to handle clipping. I really wouldn't want it any other way :-)
377      */

378     public void adjustmentValueChanged(AdjustmentEvent e) {
379         if (e != null)
380             if (e.getSource() == vbar) {
381                 // Calculate pixel offset from bar pos
382
ypix = e.getValue() * BAR_SCALE_FACTOR;
383             }
384             else {
385                 // Calculate pixel offset from bar pos
386
xpix = e.getValue() * BAR_SCALE_FACTOR;
387             }
388         
389         Dimension d = childComponent.getSize(); // will return desired size
390
childComponent.setBounds(xpix * -1, ypix * -1, d.width, d.height);
391         
392         // Update the child component
393
if (childComponent instanceof Container)
394             ((Container) childComponent).invalidate();
395         else
396             childComponent.repaint();
397     }
398
399     
400 }
401
Popular Tags