001: package com.xoetrope.swing.date;
002:
003: import com.xoetrope.carousel.build.BuildProperties;
004: import java.awt.Color;
005: import java.awt.Component;
006: import java.awt.Font;
007: import java.text.ParseException;
008: import java.text.SimpleDateFormat;
009: import java.util.Date;
010: import javax.swing.ComboBoxEditor;
011: import javax.swing.JComboBox;
012: import javax.swing.JFormattedTextField;
013: import javax.swing.ListCellRenderer;
014: import javax.swing.border.EmptyBorder;
015: import javax.swing.text.DateFormatter;
016: import javax.swing.text.DefaultFormatterFactory;
017: import net.xoetrope.debug.DebugLogger;
018: import net.xoetrope.xui.XAttributedComponent;
019: import net.xoetrope.xui.XTextHolder;
020:
021: /**
022: * A control for choosing the time-of-day
023: *
024: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
025: * the GNU Public License (GPL), please see license.txt for more details. If
026: * you make commercial use of this software you must purchase a commercial
027: * license from Xoetrope.</p>
028: * <p> $Revision: 1.2 $</p>
029: */
030: public class XTimeChooser extends JComboBox implements
031: XAttributedComponent, XTextHolder {
032: /**
033: * Pick a time of day
034: */
035: public static final int TIME_MODE = 0;
036:
037: /**
038: * Pick a time for ending an event, after a spoecified start date
039: */
040: public static final int END_TIME_MODE = 1;
041:
042: /**
043: * Pick a length of time
044: */
045: public static final int DURATION_MODE = 2;
046:
047: public static final int STEP_HOURS = 0;
048: public static final int STEP_HALF_HOURS = 1;
049: public static final int STEP_QUATER_HOURS = 2;
050:
051: private boolean use24Clock;
052: private int mode;
053: private int step = STEP_HALF_HOURS;
054: private ComboDateEditor editor;
055: private Date startDate;
056:
057: protected SimpleDateFormat dateFormat;
058: protected SimpleDateFormat parseFormat;
059:
060: /**
061: * Creates a new time chooser
062: */
063: public XTimeChooser() {
064: setEditable(true);
065: getEditor();
066: }
067:
068: public ComboBoxEditor getEditor() {
069: if (editor == null) {
070: if (startDate == null)
071: startDate = new Date();
072:
073: dateFormat = new SimpleDateFormat("HH:mm");
074: editor = new ComboDateEditor(dateFormat);
075:
076: String os = System.getProperty("os.name");
077: if (os.toLowerCase().indexOf("windows") >= 0)
078: editor.setBorder(new EmptyBorder(0, 6, 0, 0));
079:
080: fillList();
081: setEditor(editor);
082: }
083:
084: return editor;
085: }
086:
087: private void fillList() {
088: removeAllItems();
089: int offset = startDate.getHours();
090: int selectedHour = startDate.getHours();
091: int selectedMin = startDate.getMinutes();
092: for (int i = 0; i < 24; i++) {
093: int ihr = i;
094: if (mode == END_TIME_MODE)
095: ihr += offset;
096: String hr = new Integer(ihr % 24).toString();
097: addItem(hr + ":00");
098: if (step == STEP_HALF_HOURS) {
099: if ((i == selectedHour) && (selectedMin != 0)
100: && (selectedMin < 30))
101: addItem(hr + ":" + selectedMin);
102: addItem(hr + ":30");
103: if ((i == selectedHour) && (selectedMin != 0)
104: && (selectedMin > 30))
105: addItem(hr + ":" + selectedMin);
106: } else if (step == STEP_QUATER_HOURS) {
107: if ((i == selectedHour) && (selectedMin != 0)
108: && (selectedMin < 15))
109: addItem(hr + ":" + selectedMin);
110:
111: addItem(hr + ":15");
112: if ((i == selectedHour) && (selectedMin != 0)
113: && (selectedMin > 15) && (selectedMin < 30))
114: addItem(hr + ":" + selectedMin);
115:
116: addItem(hr + ":30");
117: if ((i == selectedHour) && (selectedMin != 0)
118: && (selectedMin > 30) && (selectedMin < 45))
119: addItem(hr + ":" + selectedMin);
120:
121: addItem(hr + ":45");
122: if ((i == selectedHour) && (selectedMin != 0)
123: && (selectedMin > 45))
124: addItem(hr + ":" + selectedMin);
125: } else {
126: if ((i == selectedHour) && (selectedMin != 0))
127: addItem(hr + ":" + selectedMin);
128: }
129: }
130:
131: String s = dateFormat.format(startDate);
132: setSelectedItem(s);
133: }
134:
135: /**
136: * Sets the content of the edit field
137: * @param s the new date string
138: */
139: public void setText(String s) {
140: if ((s != null) && (s.length() > 0)) {
141: try {
142: if (parseFormat != null)
143: startDate = parseFormat.parse(s);
144: else
145: startDate = new Date(s);
146: editor.setText(dateFormat.format(startDate));
147: } catch (ParseException ex) {
148: ex.printStackTrace();
149: startDate = new Date(s);
150: }
151: }
152: fillList();
153: }
154:
155: /**
156: * Gets the content of the edit field
157: * @return the date string
158: */
159: public String getText() {
160: return editor.getText();
161: }
162:
163: /**
164: * Set the background color for the edit field
165: * @param c the color
166: */
167: public void setBackground(Color c) {
168: getEditor().getEditorComponent().setBackground(c);
169: super .setBackground(c);
170: }
171:
172: /**
173: * Set the foreground color for the edit field
174: * @param c the color
175: */
176: public void setForeground(Color c) {
177: getEditor().getEditorComponent().setForeground(c);
178: super .setForeground(c);
179: }
180:
181: /**
182: * Set the font
183: * @param f the font
184: */
185: public void setFont(Font f) {
186: getEditor().getEditorComponent().setFont(f);
187: super .setFont(f);
188: }
189:
190: /**
191: * Set the list cell renderer, preserving the foreground and background
192: * colors in the process
193: * @param renderer the new renderer.
194: */
195: public void setRenderer(ListCellRenderer renderer) {
196: Color frgdColor = getForeground();
197: Color bkgdColor = getBackground();
198: super .setRenderer(renderer);
199: setForeground(frgdColor);
200: setBackground(bkgdColor);
201: }
202:
203: /**
204: * Set the format of the edit field. The format is used in the construction of
205: * a java.text.SimpleDateFormat instance.
206: * @param format the new date format
207: */
208: public void setFormat(String format) {
209: dateFormat = new SimpleDateFormat(format);
210: editor.setFormatterFactory(new DefaultFormatterFactory(
211: new DateFormatter(dateFormat)));
212: }
213:
214: /**
215: * Set the format of the edit field data as it is parsed from the data model
216: * or when the setText method is invoked. The format is used in the construction of
217: * a java.text.SimpleDateFormat instance.
218: * @param format the incoming date
219: */
220: public void setParseFormat(String format) {
221: parseFormat = new SimpleDateFormat(format);
222: }
223:
224: /**
225: * Set one or more attributes of the component.
226: * <OL>
227: * <LI>format, value=SimpleDateFormat the presentation format of the date</LI>
228: * <LI>parseformat, value=SimpleDateFormat the format of the incoming date</LI>
229: * <LI>starttime, value=date start date whose time component will be displayed</LI>
230: * <LI>editable, value=true to allow edits</LI>
231: * </OL>
232: * @param attribName the name of the attribute
233: * @param attribValue the value of the attribute
234: * @return 0 for success, non zero for failure or to require some further action
235: */
236: public int setAttribute(String attribName, Object attribValue) {
237: String attribNameLwr = attribName.toLowerCase();
238: String attribValueStr = (String) attribValue;
239: String attribValueLwr = null;
240: if (attribValue != null)
241: attribValueLwr = attribValueStr.toLowerCase();
242:
243: if (attribNameLwr.equals("format"))
244: setFormat(attribValueStr);
245: else if (attribNameLwr.equals("parseformat"))
246: setParseFormat(attribValueStr);
247: else if (attribNameLwr.equals("mode"))
248: mode = new Integer(attribValueStr).intValue();
249: else if (attribNameLwr.equals("step"))
250: step = new Integer(attribValueStr).intValue();
251: else if (attribNameLwr.equals("starttime")) {
252: try {
253: startDate = dateFormat.parse(attribValueStr);
254: } catch (ParseException ex) {
255: if (BuildProperties.DEBUG)
256: DebugLogger.logError("Invalid date: "
257: + attribValueStr);
258: }
259: fillList();
260: }
261: return 0;
262: }
263: }
264:
265: class ComboDateEditor extends JFormattedTextField implements
266: ComboBoxEditor {
267: public ComboDateEditor(SimpleDateFormat df) {
268: super (df);
269: }
270:
271: /** Return the component that should be added to the tree hierarchy for
272: * this editor
273: */
274: public Component getEditorComponent() {
275: return this ;
276: }
277:
278: /** Set the item that should be edited. Cancel any editing if necessary **/
279: public void setItem(Object anObject) {
280: if (anObject != null)
281: setText(anObject.toString());
282: else
283: setText("");
284: }
285:
286: /** Return the edited item **/
287: public Object getItem() {
288: return getText();
289: }
290: }
|