001: /*--------------------------------------------------------------------------*
002: | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas |
003: | |
004: | This program is free software; you can redistribute it and/or modify |
005: | it under the terms of the GNU General Public License as published by the |
006: | Free Software Foundation. A copy of the license has been included with |
007: | these distribution in the COPYING file, if not go to www.fsf.org |
008: | |
009: | As a special exception, you are granted the permissions to link this |
010: | program with every library, which license fulfills the Open Source |
011: | Definition as published by the Open Source Initiative (OSI). |
012: *--------------------------------------------------------------------------*/
013: package org.rapla.components.calendarview.swing;
014:
015: import java.awt.Color;
016: import java.awt.Dimension;
017: import java.awt.Font;
018: import java.awt.Point;
019: import java.util.ArrayList;
020: import java.util.Calendar;
021: import java.util.Collection;
022: import java.util.Collections;
023: import java.util.Date;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import javax.swing.JComponent;
028: import javax.swing.JLabel;
029:
030: import org.rapla.components.calendarview.Block;
031: import org.rapla.components.calendarview.Builder;
032: import org.rapla.components.layout.TableLayout;
033:
034: /** Graphical component for displaying a calendar like weekview.
035: * This view doesn't show the times and arragenes the different slots
036: * verticaly.
037: * @version CVS $Revision: 1.4 $ $Date: 2006/08/15 16:14:47 $
038: */
039: public class SwingCompactWeekView extends AbstractSwingCalendar {
040: private static final long serialVersionUID = 1L;
041:
042: public final static int COLUMNS = 7;
043: private SmallDaySlot[] slots = new SmallDaySlot[0];
044: private ArrayList rows = new ArrayList();
045: DraggingHandler draggingHandler = new DraggingHandler(this , false);
046: SelectionHandler selectionHandler = new SelectionHandler(this );
047: String[] slotNames = new String[] {};
048: private boolean[] excluded = new boolean[COLUMNS];
049:
050: public SwingCompactWeekView() {
051: this (true);
052: }
053:
054: public SwingCompactWeekView(boolean showScrollPane) {
055: super (showScrollPane);
056: }
057:
058: void calcMinMaxDates(Date date) {
059: Calendar calendar = createCalendar();
060: calendar.setTime(date);
061: calendar.set(Calendar.MINUTE, 0);
062: calendar.set(Calendar.HOUR_OF_DAY, 0);
063: calendar.set(Calendar.SECOND, 0);
064: calendar.set(Calendar.MILLISECOND, 0);
065: calendar
066: .set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
067: this .setStartDate(null);
068: this .setEndDate(null);
069: for (int i = 0; i < COLUMNS; i++) {
070: if (this .getStartDate() == null) {
071: this .setStartDate(calendar.getTime());
072: }
073: calendar.add(Calendar.DATE, 1);
074: this .setEndDate(calendar.getTime());
075: }
076: }
077:
078: /** must be called after the slots are filled*/
079: private boolean isExcluded(int column) {
080: return excluded[column];
081: }
082:
083: public Collection getBlocks() {
084: ArrayList list = new ArrayList();
085: for (int i = 0; i < slots.length; i++) {
086: list.addAll(slots[i].getBlocks());
087: }
088: return Collections.unmodifiableCollection(list);
089: }
090:
091: public void setEditable(boolean b) {
092: super .setEditable(b);
093: if (slots == null)
094: return;
095: // Hide the rest
096: for (int i = 0; i < slots.length; i++) {
097: SmallDaySlot slot = slots[i];
098: if (slot == null)
099: continue;
100: slot.setEditable(b);
101: }
102: }
103:
104: public void setSlots(String[] slotNames) {
105: this .slotNames = slotNames;
106: }
107:
108: public void rebuild() {
109: rows.clear();
110: for (int i = 0; i < slotNames.length; i++) {
111: addRow();
112: }
113: for (int i = 0; i < COLUMNS; i++) {
114: int weekday = weekdayMapper.dayForIndex(i);
115: if (excludeDays.contains(new Integer(weekday))) {
116: excluded[i] = true;
117: } else {
118: excluded[i] = false;
119: }
120: }
121: // calculate the blocks
122: Iterator it = builders.iterator();
123: while (it.hasNext()) {
124: Builder b = (Builder) it.next();
125: b.prepareBuild(getStartDate(), getEndDate());
126: }
127:
128: // clear everything
129: jHeader.removeAll();
130: jCenter.removeAll();
131: // build Blocks
132: it = builders.iterator();
133: while (it.hasNext()) {
134: Builder b = (Builder) it.next();
135: if (b.isEnabled()) {
136: b.build(this );
137: }
138: }
139: TableLayout tableLayout = new TableLayout();
140: jCenter.setLayout(tableLayout);
141:
142: Calendar calendar = createCalendar();
143: calendar.setTime(getStartDate());
144: calendar
145: .set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
146:
147: if (slotNames.length > 0) {
148: tableLayout.insertColumn(0, slotSize);
149: jHeader.add(createSlotHeader(null), "0,0,l,t");
150: } else {
151: tableLayout.insertColumn(0, 0);
152: }
153:
154: // add headers
155: for (int column = 0; column < COLUMNS; column++) {
156: if (!isExcluded(column)) {
157: tableLayout.insertColumn(column + 1, slotSize);
158: jHeader.add(createSlotHeader(calendar.getTime()));
159: } else {
160: tableLayout.insertColumn(column + 1, 0);
161: }
162: calendar.add(Calendar.DATE, 1);
163: }
164:
165: int rowsize = rows.size();
166:
167: slots = new SmallDaySlot[rowsize * COLUMNS];
168: for (int row = 0; row < rowsize; row++) {
169: tableLayout.insertRow(row, TableLayout.PREFERRED);
170: jCenter.add(createSlotLabel(row), "" + 0 + "," + row
171: + ",f,t");
172: for (int column = 0; column < COLUMNS; column++) {
173: List blocks = (List) rows.get(row);
174: int fieldNumber = row * COLUMNS + column;
175: slots[fieldNumber] = createField(blocks, column);
176: if (!isExcluded(column)) {
177: jCenter.add(slots[fieldNumber], "" + (column + 1)
178: + "," + row);
179: }
180: }
181: }
182: for (int i = 0; i < slots.length; i++) {
183: slots[i].sort();
184: }
185: jCenter.validate();
186: jHeader.validate();
187: revalidate();
188: repaint();
189: }
190:
191: protected JComponent createSlotLabel(int slot) {
192: JLabel label = new JLabel();
193: if (slot < slotNames.length) {
194: label.setText(slotNames[slot]);
195: }
196: return label;
197: }
198:
199: /** override this method, if you want to create your own slot header. */
200: protected JComponent createSlotHeader(Date date) {
201: JLabel jLabel = new JLabel();
202: jLabel.setFont(new Font("SansSerif", Font.PLAIN, 13));
203: jLabel.setHorizontalAlignment(JLabel.CENTER);
204: jLabel.setOpaque(false);
205: jLabel.setForeground(Color.black);
206: if (date != null) {
207: jLabel.setText(formatDayOfWeekDateMonth(date, locale,
208: getTimeZone()));
209: jLabel.setBorder(isEditable() ? SLOTHEADER_BORDER : null);
210: }
211: Dimension dim = new Dimension(this .slotSize, 20);
212: jLabel.setPreferredSize(dim);
213: jLabel.setMinimumSize(dim);
214: jLabel.setMaximumSize(dim);
215: return jLabel;
216: }
217:
218: private SmallDaySlot createField(List blocks, int column) {
219: SmallDaySlot c = new SmallDaySlot("", slotSize, Color.BLACK);
220: c.setEditable(isEditable());
221: c.setDraggingHandler(draggingHandler);
222: c.addMouseListener(selectionHandler);
223: c.addMouseMotionListener(selectionHandler);
224: if (blocks != null) {
225: Iterator it = blocks.iterator();
226: while (it.hasNext()) {
227: SwingBlock block = (SwingBlock) it.next();
228: blockCalendar.setTime(block.getStart());
229: int weekday = blockCalendar.get(Calendar.DAY_OF_WEEK);
230: if (weekdayMapper.indexForDay(weekday) == column) {
231: c.putBlock(block);
232: }
233: }
234: }
235: return c;
236: };
237:
238: public void addBlock(Block block, int slot) {
239: checkBlock(block);
240: while (rows.size() <= slot) {
241: addRow();
242: }
243: ArrayList blocks = (ArrayList) rows.get(slot);
244: blocks.add(block);
245:
246: blockCalendar.setTime(block.getStart());
247: int weekday = blockCalendar.get(Calendar.DAY_OF_WEEK);
248: excluded[weekdayMapper.indexForDay(weekday)] = false;
249: }
250:
251: private void addRow() {
252: rows.add(rows.size(), new ArrayList());
253: }
254:
255: public int getSlotNr(DaySlot slot) {
256: for (int i = 0; i < slots.length; i++)
257: if (slots[i] == slot)
258: return i;
259: throw new IllegalStateException("Slot not found in List");
260: }
261:
262: private int getDayOfWeek(DaySlot slot) {
263: return weekdayMapper.dayForIndex(getSlotNr(slot) % COLUMNS);
264: }
265:
266: int getRowsPerDay() {
267: return 1;
268: }
269:
270: DaySlot getDay(int nr) {
271: if (nr >= 0 && nr < slots.length)
272: return slots[nr];
273: else
274: return null;
275: }
276:
277: int getDayCount() {
278: return slots.length;
279: }
280:
281: int calcSlotNr(int x, int y) {
282: for (int i = 0; i < slots.length; i++) {
283: if (slots[i] == null)
284: continue;
285: Point p = slots[i].getLocation();
286: if ((p.x <= x) && (x <= p.x + slots[i].getWidth())
287: && (p.y <= y) && (y <= p.y + slots[i].getHeight())) {
288: return i;
289: }
290: }
291: return -1;
292: }
293:
294: SmallDaySlot calcSlot(int x, int y) {
295: int nr = calcSlotNr(x, y);
296: if (nr == -1) {
297: return null;
298: } else {
299: return slots[nr];
300: }
301: }
302:
303: Date createDate(DaySlot slot, int row, boolean startOfRow) {
304: Calendar calendar = createCalendar();
305: calendar.setTime(getStartDate());
306: calendar.set(Calendar.DAY_OF_WEEK, getDayOfWeek(slot));
307: if (!startOfRow) {
308: calendar.add(Calendar.DATE, 1);
309: }
310: calendar.set(Calendar.HOUR_OF_DAY, 0);
311: calendar.set(Calendar.MINUTE, 0);
312: calendar.set(Calendar.SECOND, 0);
313: calendar.set(Calendar.MILLISECOND, 0);
314: return calendar.getTime();
315: }
316:
317: }
|