KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ixenon > free > swing > Pager


1 /* $Id$
2  *
3  * Copyright (c) 1998 Xenonsoft Limited. All Rights Reserved.
4  *
5  * This software is protected by copyright. You are hereby notified from
6  * now by reading this message. This software is also the confidential
7  * and proprietary information of Xenonsoft Limited. ("Confidential
8  * Information").
9  *
10  * This software is distributed under the Xenonsoft Public end user
11  * License ("XPeL"), where the machine-readable source code is provided
12  * under the "Open Source" model.
13  * For more information, please read the file "LICENSE-XPL.txt"
14  */

15
16 // Pager.java
17

18 // Description:
19
// Pager the JFC/Swing component
20
//
21
// Author:
22
// Peter Pilgrim
23
// Fri Jan 15 01:15:30 GMT 1999
24
//
25
// RCS HEADER
26
//
27
// $Author$
28
// $Date$
29
// $Source$
30
// $Revision$ $State$ $Locker$
31
//
32
// History
33
// ================================================================================
34
// $Log$
35

36 package ixenon.free.swing;
37
38 import java.awt.*;
39 import java.awt.event.*;
40 import java.util.*;
41 import java.io.*;
42 import java.beans.*; // for PropertyChangeEvent
43

44 import javax.swing.*; // for JPanel, JButton
45
import javax.swing.event.*; // for SwingPropertyChangeSupport
46
import javax.swing.border.*; // for BevelBorder
47

48 /**
49  *
50  * Implementation of a pager custom JFC/Swing pseudo component
51  *
52  * This components consist of button panel, a centre panel, and a
53  * pager panel. The button panel contain four buttons: namely
54  * <B>help</B>, <B>previous</B>, <B>next</B> and <B>approval</B>
55  * button. The centre panel is a middle panel which is used to contain
56  * the pager panel and any extra application defined surrounding
57  * components. The pager panel maintain a collection of pages, which
58  * can be any type of component. The pager panel forces all pages to a
59  * fixed size and display only one page (component) at time. The
60  * previous and next buttons flip backwards and forwards through the
61  * pages.
62  *
63  * The button panel can be place to the top, left, right, of bottom
64  * (@see java.awt.BorderLayout), but by default it is placed to the
65  * bottom of the container. The button cannot be placed in the center.
66  *
67  * Pages can be added and removed with addPage() and removePage()
68  * methods. The current display page can be programmatically changed
69  * with setPageIndex(), gotoNextPage(), and gotoPrevPage().
70  *
71  * To respond to events in the frame use
72  * @see #addPropertyChangeListener
73  * @see #removePropertyChangeListener
74  * @see #PREVIOUS_BUTTON_PRESSED_PROPERTY
75  * @see #NEXT_BUTTON_PRESSED_PROPERTY
76  * @see #HELP_BUTTON_PRESSED_PROPERTY
77  *
78  * @author Peter Pilgrim
79  * @version $Id$ */

80 public class Pager extends JPanel
81 implements ActionListener
82 {
83     /** The help button pressed property */
84     public final static String JavaDoc HELP_BUTTON_PRESSED_PROPERTY="help_button_pressed_property";
85     /** The back button pressed property */
86     public final static String JavaDoc PREVIOUS_BUTTON_PRESSED_PROPERTY="back_button_pressed_property";
87     /** The next button pressed property */
88     public final static String JavaDoc NEXT_BUTTON_PRESSED_PROPERTY="next_button_pressed_property";
89
90     /** Default help button text */
91     public final static String JavaDoc DEFAULT_HELP_TEXT="Help";
92     /** Default previous button text */
93     public final static String JavaDoc DEFAULT_PREVIOUS_TEXT="<Back";
94     /** Default next button text */
95     public final static String JavaDoc DEFAULT_NEXT_TEXT="Next>";
96     
97     /** help button */
98     protected JButton bt_help;
99     /** previous button */
100     protected JButton bt_prev;
101     /** next button */
102     protected JButton bt_next;
103
104     /** button geometry of the container panel */
105     protected String JavaDoc buttonGeometry;
106     
107     protected Container buttonBox;
108     protected JPanel centrePanel;
109     protected JPanel pagerPanel;
110
111     // page index
112
protected int pageIndex = -1;
113     // a vector hold page components
114
protected Vector pages = new Vector();
115
116     private SwingPropertyChangeSupport propertyListeners;
117     
118     /**
119      * Create a pager with default configuration
120      * default button container panel geometry is "South"
121      * (@see java.awt.BorderLayout)
122      *
123      * @see #DEFAULT_HELP_TEXT
124      * @see #DEFAULT_PREVIOUS_TEXT
125      * @see #DEFAULT_NEXT_TEXT
126      */

127     Pager()
128     {
129     this(BorderLayout.SOUTH,
130          DEFAULT_HELP_TEXT, DEFAULT_PREVIOUS_TEXT, DEFAULT_NEXT_TEXT );
131     }
132     
133     /**
134      * Create a pager with button text configuration
135      * default button container panel geometry is "South"
136      * (@see java.awt.BorderLayout)
137      *
138      * Create a pager with complete configuration
139      *
140      * @param buttonGeometry the location of the button panel
141      * @param helpText the help button text
142      * @param previousText the previous button text
143      * @param nextText the next button text
144      *
145      * (@see java.awt.BorderLayout#NORTH)
146      * (@see java.awt.BorderLayout#EAST)
147      * (@see java.awt.BorderLayout#SOUTH)
148      * (@see java.awt.BorderLayout#WEST)
149      *
150      * @exception runtime exception is thrown if the button panel
151      * geometry is java.awt.BorderLayout.CENTER
152      *
153      */

154     Pager(
155     String JavaDoc buttonGeometry, String JavaDoc helpText,
156     String JavaDoc previousText, String JavaDoc nextText )
157     {
158     this.buttonGeometry = buttonGeometry;
159     
160     setLayout( new BorderLayout( 2,2 ));
161
162     // ======================================================================
163
// Create the button box panel
164
// ======================================================================
165
int axis;
166     if ( buttonGeometry.equals( BorderLayout.NORTH ) ||
167          buttonGeometry.equals( BorderLayout.SOUTH ) ) {
168         axis = BoxLayout.X_AXIS;
169         buttonBox = Box.createHorizontalBox();
170         buttonBox.add( Box.createHorizontalStrut(5) );
171     }
172     else if ( buttonGeometry.equals( BorderLayout.EAST ) ||
173           buttonGeometry.equals( BorderLayout.WEST ) ) {
174         axis = BoxLayout.Y_AXIS;
175         buttonBox = Box.createVerticalBox();
176         buttonBox.add( Box.createVerticalStrut(5) );
177     }
178     else
179         throw new RuntimeException JavaDoc(
180         "Pager cannot have button geometry of border layout:"+BorderLayout.CENTER );
181
182     if ( buttonGeometry.equals( BorderLayout.CENTER ))
183         throw new RuntimeException JavaDoc(
184         "Pager cannot have button geometry of border layout:"+BorderLayout.CENTER );
185
186     bt_help = new JButton( helpText );
187     buttonBox.add(bt_help);
188
189     if (axis == BoxLayout.X_AXIS)
190         buttonBox.add( Box.createHorizontalGlue() );
191     else
192         buttonBox.add( Box.createVerticalGlue() );
193
194     bt_prev = new JButton( previousText );
195     bt_prev.addActionListener( this );
196     buttonBox.add(bt_prev);
197     
198     if (axis == BoxLayout.X_AXIS)
199         buttonBox.add( Box.createHorizontalStrut(5) );
200     else
201         buttonBox.add( Box.createVerticalStrut(5) );
202
203     bt_next = new JButton( nextText );
204     bt_next.addActionListener( this );
205     buttonBox.add(bt_next);
206
207     if (axis == BoxLayout.X_AXIS)
208         buttonBox.add( Box.createHorizontalStrut(50) );
209     else
210         buttonBox.add( Box.createVerticalStrut(50) );
211
212     add( buttonBox, buttonGeometry );
213
214     // ======================================================================
215
// Create the central pager work area panel
216
// ======================================================================
217
pagerPanel = new JPanel();
218     pagerPanel.setLayout( new FixedSizeLayout() );
219
220     centrePanel = new JPanel();
221     CompoundBorder border = new CompoundBorder(
222         new BevelBorder( BevelBorder.RAISED ),
223         new BevelBorder( BevelBorder.LOWERED ));
224     centrePanel.setBorder( border );
225     centrePanel.setLayout( new BorderLayout(5,5 ));
226     centrePanel.add( pagerPanel, BorderLayout.CENTER );
227     
228     add( centrePanel, BorderLayout.CENTER );
229     }
230
231     /** adds another component, which for example could be another JButton,
232      * to the Pager's button container.
233      * @param kid the extra component
234      */

235     public void addExtraComponent( Component kid )
236     {
237     buttonBox.add( kid );
238     if ( buttonGeometry.equals( BorderLayout.NORTH ) ||
239          buttonGeometry.equals( BorderLayout.SOUTH ) )
240         buttonBox.add( Box.createHorizontalStrut(5) );
241     else
242         buttonBox.add( Box.createVerticalStrut(5) );
243     }
244
245     /** adds another component to the centre panel of the pager
246      * add a certain geometry. The geometry cannot be BorderLayout.CENTER
247      * otherwise an exception is thrown.
248      *
249      * @param kid the extra component
250      * @param geometry the layout geometry see @see java.awt.BorderLayout
251      *
252      * @exception an illegal argument exception is thrown if the geometry
253      * is BorderLayout.CENTER
254      */

255     public void addCenterSideComponent( Component kid, String JavaDoc geometry )
256     {
257     if (geometry == BorderLayout.CENTER )
258         throw new IllegalArgumentException JavaDoc(
259         "Cannot add side component with geometry BorderLayout.CENTER" );
260     centrePanel.add( kid, geometry );
261     }
262     
263     // ======================================================================
264
// ACCESSORS & MODIFIERS
265
// ======================================================================
266

267     /** gets the number of pages in the pager */
268     public int getNumPages()
269     {
270     return pages.size();
271     }
272     
273     /** gets the pager's page index */
274     public int getPageIndex()
275     {
276     return (pageIndex);
277     }
278     
279     /**
280      * sets the pager's page index
281      * @see #getNumPages
282      * @exception Illegal argument exception if the page limits exceeded
283      */

284     public void setPageIndex( int newIndex )
285     {
286     if ( newIndex < 0 )
287         throw new IllegalArgumentException JavaDoc("page index can be negative.");
288     if ( newIndex >= pages.size() )
289         throw new IllegalArgumentException JavaDoc(
290         "page index exceeds number of pages in pager:"+pages.size() );
291     pageIndex = newIndex;
292     showPage( pageIndex );
293     }
294
295     /** convenience method to get the next button */
296     public JButton getNextButton()
297     {
298     return (bt_next);
299     }
300
301     /** convenience method to get next button text */
302     public String JavaDoc getNextButtonText()
303     {
304     return bt_next.getText();
305     }
306
307     /** convenience method to set next button text */
308     public void setNextButtonText( String JavaDoc text )
309     {
310     bt_next.setText(text);
311     }
312
313     /** convenience method to get next button tool tip text */
314     public String JavaDoc getNextButtonToolTipText()
315     {
316     return bt_next.getToolTipText();
317     }
318
319     /** convenience method to set next button tool tip text */
320     public void setNextButtonToolTipText( String JavaDoc tooltip_text )
321     {
322     bt_next.setToolTipText(tooltip_text);
323     }
324     
325
326     /** convenience method to get the prev button */
327     public JButton getPrevButton()
328     {
329     return (bt_prev);
330     }
331
332     /** convenience method to get prev button text */
333     public String JavaDoc getPrevButtonText()
334     {
335     return bt_prev.getText();
336     }
337
338     /** convenience method to set prev button text */
339     public void setPrevButtonText( String JavaDoc text )
340     {
341     bt_prev.setText(text);
342     }
343
344     /** convenience method to get prev button tool tip text */
345     public String JavaDoc getPrevButtonToolTipText()
346     {
347     return bt_prev.getToolTipText();
348     }
349
350     /** convenience method to set prev button tool tip text */
351     public void setPrevButtonToolTipText( String JavaDoc tooltip_text )
352     {
353     bt_prev.setToolTipText(tooltip_text);
354     }
355     
356
357     /** convenience method to get the prev button */
358     public JButton getHelpButton()
359     {
360     return (bt_help);
361     }
362
363     /** convenience method to get help button text */
364     public String JavaDoc getHelpButtonText()
365     {
366     return bt_help.getText();
367     }
368
369     /** convenience method to set help button text */
370     public void setHelpButtonText( String JavaDoc text )
371     {
372     bt_help.setText(text);
373     }
374
375     /** convenience method to get help button tool tip text */
376     public String JavaDoc getHelpButtonToolTipText()
377     {
378     return bt_help.getToolTipText();
379     }
380
381     /** convenience method to set help button tool tip text */
382     public void setHelpButtonToolTipText( String JavaDoc tooltip_text )
383     {
384     bt_help.setToolTipText(tooltip_text);
385     }
386     
387
388     // TODO: Fri Jan 15 01:13:23 GMT 1999
389
// implement add and remove page methods
390
// redirect in to add or remove components to the centre pager Panel
391
//
392
// Required fixed size layout manager to force centre page Panel's
393
// kids to fixed size of the panel. Need to get the greatest
394
// geometry for all good kid
395
//
396
// Add action listener to `prev' and `next' buttons to literally
397
// flick the pages
398
//
399

400     // ======================================================================
401
// GENERAL METHODS
402
// ======================================================================
403

404     /** Causes the pager to goto the previous page if available */
405     public void gotoPrevPage()
406     {
407     if (pageIndex > 0 ) {
408         --pageIndex;
409         showPage();
410     }
411     }
412     
413     /** Causes the pager to goto the next page if available */
414     public void gotoNextPage()
415     {
416     if (pageIndex < pages.size()-1 ) {
417         ++pageIndex;
418         showPage();
419     }
420     }
421
422     /** adds a component as a new page */
423     public Component addPage( Component page )
424     {
425     if (pages == null)
426         pages = new Vector();
427     pagerPanel.add(page);
428     pages.addElement(page);
429     if ( pages.size() == 1 ) {
430         // The first page added, by default show it
431
pageIndex = 0;
432         showPage();
433     }
434     else {
435         // Otherwise, set all pages to be invisible by default
436
page.setVisible(false);
437         updatePrevNextButtons();
438     }
439     
440     return (page);
441     }
442
443     /** removes a page component by index */
444     public void removePageAt( int index )
445     {
446     if (index >=0 && index < pages.size() ) {
447         Component page = (Component)pages.elementAt(index);
448         page.setVisible(false);
449         if (pageIndex == index )
450         // If the current page is being removed,
451
// then `back' if at all possible.
452
gotoPrevPage();
453         pages.removeElementAt( index );
454         if (pages.size() < 1)
455         pageIndex = -1;
456         pagerPanel.remove(index);
457     }
458     }
459     
460     /** removes a page component */
461     public void removePage( Component page )
462     {
463     int index = pages.indexOf(page);
464     if (index != -1 )
465         removePageAt(index);
466     }
467
468     /** remove remove all page components */
469     public void removeAllPages()
470     {
471     pageIndex = -1; /*1*/
472     showPage(-1); /*2*/
473     pages.removeAllElements(); /*3*/
474     pagerPanel.removeAll(); /*4*/
475     }
476
477     /** force update of the previous and next button:
478      * Enable or disable the control button
479      */

480     protected void updatePrevNextButtons()
481     {
482     // when the pageIndex hits the first and last page
483
int numPages = pages.size();
484     bt_prev.setEnabled( pageIndex > 0 );
485     bt_next.setEnabled( pageIndex < numPages - 1);
486     }
487
488     /** Show the current page and force update */
489     public void showPage()
490     {
491     showPage( pageIndex );
492     }
493
494
495     /** Show the current page at the requested index */
496     protected void showPage( int showIndex )
497     {
498     // Force set invisible page except the one we want
499
int numKids = pagerPanel.getComponentCount();
500     if (numKids > 0 ) {
501         Component kids[] = pagerPanel.getComponents();
502         for (int k=0; k<kids.length; ++k) {
503         kids[k].setVisible( k == showIndex ? true : false );
504         }
505
506         updatePrevNextButtons();
507     }
508     }
509
510
511     // ======================================================================
512
// INNER CLASSES
513
// ======================================================================
514

515     protected class FixedSizeLayout implements LayoutManager {
516
517     Dimension preferredSize = new Dimension();
518
519     public void addLayoutComponent( String JavaDoc name, Component comp )
520     { /* do nothing */ }
521
522     public void removeLayoutComponent( Component comp )
523     { /* do nothing */ }
524
525     public Dimension preferredLayoutSize( Container parent )
526     {
527         preferredSize = recomputeSize( parent );
528         return preferredSize;
529     }
530     
531     public Dimension minimumLayoutSize( Container parent )
532     {
533         // Ad hoc 1/8 of preferred size
534
preferredSize = recomputeSize( parent );
535         return new Dimension( preferredSize.width/8,
536                   preferredSize.height/8 );
537     }
538     
539     public void layoutContainer( Container parent )
540     {
541         // layout fixed size
542
int k;
543         int numKids = pagerPanel.getComponentCount();
544         Component kids[] = pagerPanel.getComponents();
545
546         Dimension parentSize = parent.getSize();
547         Insets insets = parent.getInsets();
548         Dimension fixedSize =
549         new Dimension( parentSize.width-4-insets.left-insets.right,
550                    parentSize.height-4-insets.top-insets.bottom );
551         
552         for (k=0; k<numKids; ++k) {
553         Component kid = kids[k];
554         kid.setBounds( 2+insets.left, 2+insets.top,
555                    fixedSize.width, fixedSize.height );
556         }
557     }
558
559     public Dimension recomputeSize( Container parent )
560     {
561         Dimension prefSize;
562         Dimension greatestSize = new Dimension(0,0);
563
564         // Ask the kids for their preferred size.
565
int k;
566         int numKids = pagerPanel.getComponentCount();
567         Component kids[] = pagerPanel.getComponents();
568
569         for (k=0; k<numKids; ++k) {
570         Component kid = kids[k];
571         
572         prefSize = kid.getPreferredSize();
573         if ( greatestSize.width < prefSize.width )
574             greatestSize.width = prefSize.width ;
575         if ( greatestSize.height < prefSize.height )
576             greatestSize.height = prefSize.height ;
577         }
578         
579         return greatestSize;
580     }
581     
582
583     }
584     
585
586     // ======================================================================
587
// EVENT HANDLING
588
// ======================================================================
589

590     /** Add <I>PropertyChangeListener</I> obejcts interested in receiving
591      * property change events.
592      * @param listener the property change listener
593      */

594     public void addPropertyChangeListener( PropertyChangeListener listener )
595     {
596     if (propertyListeners == null)
597         propertyListeners = new SwingPropertyChangeSupport( this );
598     propertyListeners.addPropertyChangeListener( listener );
599     }
600     
601     /** Remove <I>PropertyChangeListener</I> obejcts interested in receiving
602      * property change events.
603      * @param listener the property change listener
604      */

605     public void removePropertyChangeListener( PropertyChangeListener listener )
606     {
607     if (propertyListeners != null)
608         propertyListeners.removePropertyChangeListener( listener );
609     }
610     
611     /** Remove <I>PropertyChangeListener</I> obejcts interested in receiving
612      * property change events.
613      * @param propertyName the property name
614      * @param oldValue the old property value
615      * @param newValue the new property value
616      */

617     public void firePropertyChange( String JavaDoc propertyName, Object JavaDoc oldValue, Object JavaDoc newValue )
618     {
619     if (propertyListeners != null)
620         propertyListeners.firePropertyChange( propertyName, oldValue, newValue );
621     }
622
623     public void actionPerformed( ActionEvent evt )
624     {
625     Object JavaDoc src = evt.getSource();
626     if ( bt_prev == src ) {
627         // Previous button was pressed/depressed
628
gotoPrevPage();
629         firePropertyChange( PREVIOUS_BUTTON_PRESSED_PROPERTY, null, evt );
630     }
631     else if ( bt_next == src ) {
632         // Next button was pressed/depressed
633
gotoNextPage();
634         firePropertyChange( NEXT_BUTTON_PRESSED_PROPERTY, null, evt );
635     }
636     else if ( bt_help == src ) {
637         // Help button was pressed/depressed
638
firePropertyChange( HELP_BUTTON_PRESSED_PROPERTY, null, evt );
639     }
640     }
641     
642     public static void main( String JavaDoc [] args )
643     {
644     JFrame frame = new JFrame("Pager Demonstration");
645     frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
646     
647     Pager pager = new Pager();
648     pager.setPrevButtonToolTipText("go to previous item");
649     pager.setNextButtonToolTipText("go to next item");
650     pager.setHelpButtonToolTipText("call the lifeguard");
651
652     Font font = new Font( "Dialog", Font.BOLD, 24 );
653     for (int q=0; q<10; ++q ) {
654         JPanel panel = new JPanel();
655         panel.setLayout( new BorderLayout() );
656         panel.setPreferredSize( new Dimension( 325, 200 ));
657         JButton button = new JButton("Page #"+q );
658         panel.add(button, BorderLayout.CENTER );
659         pager.addPage(panel);
660     }
661     
662     frame.getContentPane().add( pager, BorderLayout.CENTER );
663     frame.pack();
664     frame.setVisible(true);
665     }
666
667 }
668
669 // fini
670
Popular Tags