Source code: org/gui4j/core/swing/calendar/CalendarButton.java
1 package org.gui4j.core.swing.calendar;
2
3 /*
4
5 File: $Workfile: CalendarButton.java $
6
7 Original Author: Michael Karneim
8
9 Last modified on: $Modtime: $
10
11 Last modified by: $Author: joachims $
12
13
14
15 Maturity Level: DRAFT
16
17 */
18
19 import java.awt.Font;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.text.SimpleDateFormat;
25 import java.util.Calendar;
26 import java.util.Date;
27
28 import javax.swing.JButton;
29 import javax.swing.JComboBox;
30 import javax.swing.JFrame;
31 import javax.swing.JPopupMenu;
32 import javax.swing.JTextField;
33 import javax.swing.SwingUtilities;
34
35 /**
36 * CalendarButton provides a simple mechanism for the user to bind a
37 * date chooser popup to a text component. Whenever the button is pressed
38 * a popup appears below a specified text component, and displays a
39 * CalenderBean control.
40 * JTextField dateField = new JTextField("14.01.1971 ");
41 * CalendarButton dateButton = new CalendarButton();
42 * dateButton.setText( "...");
43 * dateButton.setTextComponent( dateField);
44 * dateButton.setPreferredSize( new Dimension( 20, dateField.getPreferredSize().height));
45 * JFrame frame = new JFrame();
46 * frame.getContentPane().setLayout( new FlowLayout(0));
47 * frame.getContentPane().add( dateField);
48 * frame.getContentPane().add( dateButton);
49 * frame.pack();
50 * frame.setVisible( true);
51 */
52 public class CalendarButton extends JButton implements ActionListener
53 {
54
55 javax.swing.text.JTextComponent textComponent;
56
57 JPopupMenu popup = null;
58
59 // SimpleDateFormat format = new SimpleDateFormat(FormatManager.getInstance().getDatePattern()); //[PENDING,mk,29.02.2000: Hier keine Abhängigkeit ins Restprojekt einbauen!]
60
61 SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy");
62
63 CalendarBean calendarBean;
64
65 /**
66 * This method invokes a simple test program that demonstrates
67 * the calendar button.
68 * @param args
69 */
70 public static void main(String[] args)
71 {
72 System.out.println("test program for CalendarButton");
73 JTextField dateField = new JTextField("14.01.1971 ");
74
75 CalendarButton dateButton = new CalendarButton();
76
77 dateButton.setText("...");
78
79 dateButton.setTextComponent(dateField);
80
81 dateButton.setPreferredSize(new java.awt.Dimension(20, dateField.getPreferredSize().height));
82
83 JFrame frame1 = new JFrame();
84
85 frame1.getContentPane().setLayout(new java.awt.FlowLayout(0));
86
87 frame1.getContentPane().add(dateField);
88
89 frame1.getContentPane().add(dateButton);
90 JComboBox comboBox = new JComboBox(new String[] {"1", "2" });
91 frame1.getContentPane().add(comboBox);
92 frame1.pack();
93
94 frame1.setVisible(true);
95
96 }
97
98 /**
99
100 * Creates an instance of CalenderBean
101
102 */
103
104 public CalendarButton()
105 {
106 this.addActionListener(this);
107 this.setEnabled(this.textComponent != null ? this.textComponent.isEditable() : false);
108 }
109
110 /**
111 * Implements the ActionListener interface. This method is called
112 * whenever the button is pressed.
113 * @param e
114 */
115
116 public void actionPerformed(ActionEvent e)
117 {
118 if (textComponent == null)
119 return;
120
121 if (e.getSource() == this)
122 {
123 JPopupMenu p = this.getPopupMenu();
124 String dateString = this.textComponent.getText();
125
126 try
127 {
128 Date date = this.format.parse(dateString);
129 this.getCalendarBean().select(date);
130 }
131 catch (Throwable t)
132 {
133 this.getCalendarBean().showMonth(Calendar.getInstance());
134 this.getCalendarBean().select(new Date());
135
136 }
137
138 p.show(textComponent, 0, textComponent.getSize().height);
139
140 }
141 else
142 {
143 if (e.getSource() == this.getCalendarBean())
144 {
145 this.textComponent.grabFocus();
146 JPopupMenu p = this.getPopupMenu();
147 p.setVisible(false);
148 Date date = this.getCalendarBean().getSelectedDate();
149 String dateString = format.format(date);
150 this.textComponent.setText(dateString);
151 SwingUtilities.invokeLater(new Runnable()
152 {
153 public void run()
154 {
155 grabFocus();
156 }
157 });
158 }
159 }
160
161 }
162
163 private transient PropertyChangeListener enableStateListener = new PropertyChangeListener()
164 {
165 public void propertyChange(PropertyChangeEvent evt)
166 {
167 if (!(evt.getSource() == textComponent))
168 {
169 return;
170 }
171 boolean newValue = ((Boolean) evt.getNewValue()).booleanValue();
172 setEnabled(newValue);
173 }
174 };
175 /**
176
177 * Sets the reference to the text component, the calender button should work
178
179 * with. From this text component the calendar button will get the date
180
181 * string to put into the date chooser popup on button click. Below this
182
183 * text component the date chooser popup will be displayed. Into this text component
184
185 * the selected date will be inserted from the date chooser component.
186
187 * @param newTextComponent the text component the button will work with
188
189 */
190 public void setTextComponent(javax.swing.text.JTextComponent newTextComponent)
191 {
192
193 javax.swing.text.JTextComponent oldTextComponent = textComponent;
194
195 if (this.textComponent != null)
196 this.textComponent.removePropertyChangeListener("editable", enableStateListener);
197
198 textComponent = newTextComponent;
199
200 if (this.textComponent != null)
201 {
202 this.textComponent.addPropertyChangeListener("editable", enableStateListener);
203 this.setEnabled(this.textComponent.isEditable());
204 }
205
206 firePropertyChange("textComponent", oldTextComponent, newTextComponent);
207
208 }
209
210 /**
211
212 * Returns the text component that is bound to this button for displaying the
213
214 * date.
215
216 * @return the text component that is bound to this button for displaying the
217
218 * date
219
220 */
221
222 public javax.swing.text.JTextComponent getTextComponent()
223 {
224
225 return textComponent;
226
227 }
228
229 /**
230
231 * Returns the popup menu with the date chooser control.
232
233 * @return the popup menu with the date chooser control
234
235 */
236
237 protected JPopupMenu getPopupMenu()
238 {
239
240 if (this.popup == null)
241 {
242 this.popup = new JPopupMenu();
243 this.popup.add(this.getCalendarBean());
244 }
245
246 return this.popup;
247
248 }
249
250 /**
251
252 * Defines the pattern that has to be used to transform a String to
253
254 * a Date instance and vice versa. The default is "dd.mm.yyyy".
255
256 * @param pattern the format pattern
257
258 */
259
260 public void setDatePattern(String pattern)
261 {
262
263 String oldPattern = this.format.toPattern();
264
265 this.format.applyPattern(pattern);
266
267 firePropertyChange("datePattern", oldPattern, pattern);
268
269 }
270
271 /**
272
273 * Returns the pattern that has to be used to transform a String to
274
275 * a Date instance and vice versa.
276
277 * @return the pattern that has to be used to transform a String to
278
279 * a Date instance and vice versa
280
281 */
282
283 public String getDatePattern()
284 {
285
286 return this.format.toPattern();
287
288 }
289
290 /**
291
292 * Sets the CalendarBean instance that has to be used in the popup.
293
294 * <P>Note:<BR>
295
296 * This method offers an easy way to customize the look and feel
297
298 * of the date chooser popup. Be carefull not to use one single calendar
299
300 * bean in more calendar buttons.
301
302 * @param newCalendarBean the CalendarBean instance that has to be used in the popup
303
304 */
305
306 public void setCalendarBean(CalendarBean newCalendarBean)
307 {
308
309 CalendarBean oldCalendarBean = calendarBean;
310
311 if (oldCalendarBean != null)
312 {
313
314 oldCalendarBean.removeActionListener(this);
315
316 }
317
318 this.calendarBean = newCalendarBean;
319
320 this.calendarBean.addActionListener(this);
321
322 firePropertyChange("calendarBean", oldCalendarBean, newCalendarBean);
323
324 }
325
326 /**
327
328 * Returns the CalendarBean instance that is used in the popup.
329
330 * @return the CalendarBean instance that is used in the popup
331
332 */
333
334 public CalendarBean getCalendarBean()
335 {
336
337 if (this.calendarBean == null)
338 {
339
340 this.calendarBean = new CalendarBean();
341 Font f = textComponent.getFont(); // TODO: dynamisch
342 this.calendarBean.setDayFont(f);
343 this.calendarBean.setDateFont(f);
344 this.calendarBean.setHeaderFont(f);
345 this.calendarBean.setFont(f);
346 this.calendarBean.addActionListener(this);
347 }
348
349 return this.calendarBean;
350
351 }
352
353 }