View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Blacksmith, Inc.
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.ui.swing.components;
20  
21  import java.awt.BorderLayout;
22  import java.awt.Component;
23  import java.awt.GridBagConstraints;
24  import java.awt.GridBagLayout;
25  import java.awt.Insets;
26  import java.awt.event.ActionEvent;
27  import java.lang.reflect.Method;
28  
29  import javax.swing.JFrame;
30  import javax.swing.JPanel;
31  import javax.swing.JTextField;
32  import javax.swing.Timer;
33  import javax.swing.UIManager;
34  import javax.swing.border.EmptyBorder;
35  
36  /***
37  * StatusButtonPanel extends ButtonPanel to provide a space
38  * to display status messages in a consistent manner.<BR><BR>
39  * Messages are erased after a certain predefined interval,
40  * defaulting to 10 seconds.
41  *
42  * @author michael@mpowers.net
43  * @author $Author: cgruber $
44  * @version $Revision: 904 $
45  */
46  public class StatusButtonPanel extends ButtonPanel
47  {
48  /***
49  *   This is the action command to all listeners when the status text is changed.
50  */
51      public static final String STATUS_CHANGED = "STATUS_CHANGED";
52  
53      // note: weirdness happens if you initialize
54      //  this variable.  Because it is set by initLayout
55      //  and initLayout is called by the superclass constructor,
56      //  this variable would get initialized after initLayout
57      //  is called...
58      protected Component statusComponent; // = null;
59  
60      protected Timer timer = null;
61      protected int interval = 10000; // adjust as needed
62  
63  /***
64  * Constructs a StatusButtonPanel.  Three buttons are created
65  * so the panel is filled when used in a GUI-builder environment.
66  */
67      public StatusButtonPanel()
68      {
69          super();
70          setupTimer();
71      }
72  
73  /***
74  * Constructs a StatusButtonPanel using specified buttons.
75  * @param buttonList An array containing the strings to be used in labeling the buttons.
76  */
77      public StatusButtonPanel( String[] buttonList )
78      {
79          super( buttonList );
80          setupTimer();
81      }
82  
83  /***
84  * Initializes the timer instance variable.
85  */
86      protected void setupTimer()
87      {
88          timer = new Timer( interval, this );
89          timer.addActionListener( this );
90          timer.setRepeats( false );
91          timer.start();
92      }
93  
94  /***
95  * Returns the number of milliseconds before the status message is cleared.
96  * The default is 10000.
97  * @return The current delay interval in milliseconds.
98  */
99      public int getDelayInterval()
100     {
101         return interval;
102     }
103 
104 /***
105 * Sets the number of milliseconds before the status message is cleared.
106 * @param millis The new delay interval in milliseconds.
107 */
108     public void setDelayInterval( int millis )
109     {
110         interval = millis;
111         timer.setDelay( interval );
112     }
113 
114 /***
115 * Returns the visual component used to display the status.
116 * @return A component used for displaying status.
117 */
118     public Component getStatusComponent()
119     {
120         return statusComponent;
121 
122     }
123 /***
124 * Receives ActionEvents from the internal timer.
125 * @param e The action event in question.
126 */
127      public void actionPerformed(ActionEvent e)
128      {
129         if ( e.getSource() == timer )
130         {
131             setText( "" );
132             return;
133         }
134 
135         // otherwise continue with superclass implementation
136         super.actionPerformed( e );
137     }
138 
139 /***
140 * This method is responsible for the initial layout of the panel.
141 * Subclasses can implement different layouts, but this method
142 * is responsible for initializing buttonPanelLayout to a valid
143 * layout manager and setting this panel to use it.  This method
144 * must should initialize statusComponent to a component that ideally
145 * has get/setText methods, although this is not required.
146 */
147     protected void initLayout()
148     {
149 
150         statusComponent = new JTextField();
151         JTextField textField = (JTextField) statusComponent;
152         textField.setColumns( 20 );
153         textField.setBackground( getBackground() );
154         textField.setEditable( false );
155 
156 //        statusComponent = new PickListPanel(); // for testing
157 
158         this.setLayout( new GridBagLayout() );
159 
160         GridBagConstraints gbc =
161 		new GridBagConstraints();
162 	gbc.gridx = GridBagConstraints.RELATIVE;
163 	gbc.gridy = GridBagConstraints.RELATIVE;
164 	gbc.gridwidth = 1;
165 	gbc.gridheight = 1;
166 	gbc.weightx = 1.0;
167 	gbc.weighty = 0.0;
168 	gbc.anchor = GridBagConstraints.CENTER;
169 	gbc.fill = GridBagConstraints.HORIZONTAL;
170 	gbc.insets = new Insets(0, 5, 0, 10);
171 	gbc.ipadx = 0;
172 	gbc.ipady = 0;
173 
174 //1.2        new GridBagConstraints(GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0,
175 //1.2            GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 10), 0, 0 );
176 
177         this.add( statusComponent, gbc );
178 
179         buttonContainer = new JPanel();
180         buttonPanelLayout = new BetterFlowLayout();
181         buttonContainer.setLayout(buttonPanelLayout);
182         buttonPanelLayout.setAlignment( BetterFlowLayout.RIGHT );
183         ((BetterFlowLayout)buttonPanelLayout).setWidthUniform( true );
184         gbc.weightx = 0.0;
185         gbc.insets = new Insets( 0, 0, 0, 0 );
186         this.add( buttonContainer, gbc );
187     }
188 
189 /***
190 *   Sets the text to appear in the status area.
191 *   @param newText A string to appear in the status area.  Nulls are allowed.
192 */
193     public void setText(String newText)
194     {
195         // TODO: should use property introspection instead
196 
197         // use reflection to call the "setText" method, if any.
198         try
199         {
200             Class c = statusComponent.getClass();
201             Method m = c.getMethod( "setText", new Class[] { new String().getClass() } );
202             m.invoke( statusComponent, new Object[] { newText } );
203             broadcastEvent( new ActionEvent( this, ActionEvent.ACTION_PERFORMED, STATUS_CHANGED ) );
204             statusComponent.paint( statusComponent.getGraphics() );
205         }
206         catch ( Exception exc )
207         {
208             // "setText" method does not exist; do nothing.
209         }
210 
211         // if non-empty string, start the timer
212         if ( ! "".equals( newText ) )
213         {
214             timer.restart();
215         }
216     }
217 
218 /***
219 *   Gets the text in the status area.
220 *   @return The string being displayed in the status area.
221 */
222     public String getText()
223     {
224         // TODO: should use property introspection instead
225 
226         String value = "";
227         // use reflection to call the "setText" method, if any.
228         try
229         {
230             Class c = statusComponent.getClass();
231             Method m = c.getMethod( "getText", (Class[])null );
232             value = (String) m.invoke( statusComponent, (Object[])null );
233         }
234         catch ( Exception exc )
235         {
236             // "getText" method does not exist; do nothing.
237         }
238         return value;
239     }
240 
241     // for testing
242 
243     public static void main( String[] argv )
244     {
245         try
246         {
247             UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
248         }
249         catch (Exception exc)
250         {
251 
252         }
253 
254         JFrame dialog = new JFrame();
255         BorderLayout bl = new BorderLayout( 20, 20 );
256 
257 //        StatusButtonPanel panel = new StatusButtonPanel();
258 //        System.out.println( panel.statusComponent );
259         StatusButtonPanel panel = new StatusButtonPanel( new String[] { "Okay", "Cancel" } );
260 
261         dialog.getContentPane().setLayout( bl );
262         dialog.getContentPane().add( panel, BorderLayout.SOUTH );
263         dialog.setLocation( 50, 50 );
264         // dialog.setSize( 450, 150 );
265         dialog.pack();
266         dialog.setVisible( true );
267 
268         panel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) );
269         panel.setAlignment( BetterFlowLayout.RIGHT );
270 //        panel.getButton( "One" ).setEnabled( false );
271         panel.setText( "File saved." );
272         System.out.println( panel.getText() );
273     }
274 
275 }
276