001: package org.gui4j.core.swing.calendar;
002:
003: /*
004:
005: File: $Workfile: CalendarButton.java $
006:
007: Original Author: Michael Karneim
008:
009: Last modified on: $Modtime: $
010:
011: Last modified by: $Author: joachims $
012:
013:
014:
015: Maturity Level: DRAFT
016:
017: */
018:
019: import java.awt.Font;
020: import java.awt.event.ActionEvent;
021: import java.awt.event.ActionListener;
022: import java.beans.PropertyChangeEvent;
023: import java.beans.PropertyChangeListener;
024: import java.text.SimpleDateFormat;
025: import java.util.Calendar;
026: import java.util.Date;
027:
028: import javax.swing.JButton;
029: import javax.swing.JComboBox;
030: import javax.swing.JFrame;
031: import javax.swing.JPopupMenu;
032: import javax.swing.JTextField;
033: import javax.swing.SwingUtilities;
034:
035: /**
036: * CalendarButton provides a simple mechanism for the user to bind a
037: * date chooser popup to a text component. Whenever the button is pressed
038: * a popup appears below a specified text component, and displays a
039: * CalenderBean control.
040: * JTextField dateField = new JTextField("14.01.1971 ");
041: * CalendarButton dateButton = new CalendarButton();
042: * dateButton.setText( "...");
043: * dateButton.setTextComponent( dateField);
044: * dateButton.setPreferredSize( new Dimension( 20, dateField.getPreferredSize().height));
045: * JFrame frame = new JFrame();
046: * frame.getContentPane().setLayout( new FlowLayout(0));
047: * frame.getContentPane().add( dateField);
048: * frame.getContentPane().add( dateButton);
049: * frame.pack();
050: * frame.setVisible( true);
051: */
052: public class CalendarButton extends JButton implements ActionListener {
053:
054: javax.swing.text.JTextComponent textComponent;
055:
056: JPopupMenu popup = null;
057:
058: // SimpleDateFormat format = new SimpleDateFormat(FormatManager.getInstance().getDatePattern()); //[PENDING,mk,29.02.2000: Hier keine Abhängigkeit ins Restprojekt einbauen!]
059:
060: SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy");
061:
062: CalendarBean calendarBean;
063:
064: /**
065: * This method invokes a simple test program that demonstrates
066: * the calendar button.
067: * @param args
068: */
069: public static void main(String[] args) {
070: System.out.println("test program for CalendarButton");
071: JTextField dateField = new JTextField("14.01.1971 ");
072:
073: CalendarButton dateButton = new CalendarButton();
074:
075: dateButton.setText("...");
076:
077: dateButton.setTextComponent(dateField);
078:
079: dateButton.setPreferredSize(new java.awt.Dimension(20,
080: dateField.getPreferredSize().height));
081:
082: JFrame frame1 = new JFrame();
083:
084: frame1.getContentPane().setLayout(new java.awt.FlowLayout(0));
085:
086: frame1.getContentPane().add(dateField);
087:
088: frame1.getContentPane().add(dateButton);
089: JComboBox comboBox = new JComboBox(new String[] { "1", "2" });
090: frame1.getContentPane().add(comboBox);
091: frame1.pack();
092:
093: frame1.setVisible(true);
094:
095: }
096:
097: /**
098:
099: * Creates an instance of CalenderBean
100:
101: */
102:
103: public CalendarButton() {
104: this .addActionListener(this );
105: this .setEnabled(this .textComponent != null ? this .textComponent
106: .isEditable() : false);
107: }
108:
109: /**
110: * Implements the ActionListener interface. This method is called
111: * whenever the button is pressed.
112: * @param e
113: */
114:
115: public void actionPerformed(ActionEvent e) {
116: if (textComponent == null)
117: return;
118:
119: if (e.getSource() == this ) {
120: JPopupMenu p = this .getPopupMenu();
121: String dateString = this .textComponent.getText();
122:
123: try {
124: Date date = this .format.parse(dateString);
125: this .getCalendarBean().select(date);
126: } catch (Throwable t) {
127: this .getCalendarBean()
128: .showMonth(Calendar.getInstance());
129: this .getCalendarBean().select(new Date());
130:
131: }
132:
133: p.show(textComponent, 0, textComponent.getSize().height);
134:
135: } else {
136: if (e.getSource() == this .getCalendarBean()) {
137: this .textComponent.grabFocus();
138: JPopupMenu p = this .getPopupMenu();
139: p.setVisible(false);
140: Date date = this .getCalendarBean().getSelectedDate();
141: String dateString = format.format(date);
142: this .textComponent.setText(dateString);
143: SwingUtilities.invokeLater(new Runnable() {
144: public void run() {
145: grabFocus();
146: }
147: });
148: }
149: }
150:
151: }
152:
153: private transient PropertyChangeListener enableStateListener = new PropertyChangeListener() {
154: public void propertyChange(PropertyChangeEvent evt) {
155: if (!(evt.getSource() == textComponent)) {
156: return;
157: }
158: boolean newValue = ((Boolean) evt.getNewValue())
159: .booleanValue();
160: setEnabled(newValue);
161: }
162: };
163:
164: /**
165:
166: * Sets the reference to the text component, the calender button should work
167:
168: * with. From this text component the calendar button will get the date
169:
170: * string to put into the date chooser popup on button click. Below this
171:
172: * text component the date chooser popup will be displayed. Into this text component
173:
174: * the selected date will be inserted from the date chooser component.
175:
176: * @param newTextComponent the text component the button will work with
177:
178: */
179: public void setTextComponent(
180: javax.swing.text.JTextComponent newTextComponent) {
181:
182: javax.swing.text.JTextComponent oldTextComponent = textComponent;
183:
184: if (this .textComponent != null)
185: this .textComponent.removePropertyChangeListener("editable",
186: enableStateListener);
187:
188: textComponent = newTextComponent;
189:
190: if (this .textComponent != null) {
191: this .textComponent.addPropertyChangeListener("editable",
192: enableStateListener);
193: this .setEnabled(this .textComponent.isEditable());
194: }
195:
196: firePropertyChange("textComponent", oldTextComponent,
197: newTextComponent);
198:
199: }
200:
201: /**
202:
203: * Returns the text component that is bound to this button for displaying the
204:
205: * date.
206:
207: * @return the text component that is bound to this button for displaying the
208:
209: * date
210:
211: */
212:
213: public javax.swing.text.JTextComponent getTextComponent() {
214:
215: return textComponent;
216:
217: }
218:
219: /**
220:
221: * Returns the popup menu with the date chooser control.
222:
223: * @return the popup menu with the date chooser control
224:
225: */
226:
227: protected JPopupMenu getPopupMenu() {
228:
229: if (this .popup == null) {
230: this .popup = new JPopupMenu();
231: this .popup.add(this .getCalendarBean());
232: }
233:
234: return this .popup;
235:
236: }
237:
238: /**
239:
240: * Defines the pattern that has to be used to transform a String to
241:
242: * a Date instance and vice versa. The default is "dd.mm.yyyy".
243:
244: * @param pattern the format pattern
245:
246: */
247:
248: public void setDatePattern(String pattern) {
249:
250: String oldPattern = this .format.toPattern();
251:
252: this .format.applyPattern(pattern);
253:
254: firePropertyChange("datePattern", oldPattern, pattern);
255:
256: }
257:
258: /**
259:
260: * Returns the pattern that has to be used to transform a String to
261:
262: * a Date instance and vice versa.
263:
264: * @return the pattern that has to be used to transform a String to
265:
266: * a Date instance and vice versa
267:
268: */
269:
270: public String getDatePattern() {
271:
272: return this .format.toPattern();
273:
274: }
275:
276: /**
277:
278: * Sets the CalendarBean instance that has to be used in the popup.
279:
280: * <P>Note:<BR>
281:
282: * This method offers an easy way to customize the look and feel
283:
284: * of the date chooser popup. Be carefull not to use one single calendar
285:
286: * bean in more calendar buttons.
287:
288: * @param newCalendarBean the CalendarBean instance that has to be used in the popup
289:
290: */
291:
292: public void setCalendarBean(CalendarBean newCalendarBean) {
293:
294: CalendarBean oldCalendarBean = calendarBean;
295:
296: if (oldCalendarBean != null) {
297:
298: oldCalendarBean.removeActionListener(this );
299:
300: }
301:
302: this .calendarBean = newCalendarBean;
303:
304: this .calendarBean.addActionListener(this );
305:
306: firePropertyChange("calendarBean", oldCalendarBean,
307: newCalendarBean);
308:
309: }
310:
311: /**
312:
313: * Returns the CalendarBean instance that is used in the popup.
314:
315: * @return the CalendarBean instance that is used in the popup
316:
317: */
318:
319: public CalendarBean getCalendarBean() {
320:
321: if (this .calendarBean == null) {
322:
323: this .calendarBean = new CalendarBean();
324: Font f = textComponent.getFont(); // TODO: dynamisch
325: this.calendarBean.setDayFont(f);
326: this.calendarBean.setDateFont(f);
327: this.calendarBean.setHeaderFont(f);
328: this.calendarBean.setFont(f);
329: this.calendarBean.addActionListener(this);
330: }
331:
332: return this.calendarBean;
333:
334: }
335:
336: }
|