1 package org.columba.core.gui.base; 17 18 import java.awt.BorderLayout ; 19 import java.awt.Color ; 20 import java.awt.Dimension ; 21 import java.awt.FontMetrics ; 22 import java.awt.Graphics ; 23 import java.awt.Insets ; 24 import java.awt.event.ActionEvent ; 25 import java.awt.event.ActionListener ; 26 import java.awt.event.MouseAdapter ; 27 import java.awt.event.MouseEvent ; 28 import java.text.DateFormatSymbols ; 29 import java.text.SimpleDateFormat ; 30 import java.util.Calendar ; 31 32 import javax.swing.BorderFactory ; 33 import javax.swing.JButton ; 34 import javax.swing.JComponent ; 35 import javax.swing.JLabel ; 36 import javax.swing.JPanel ; 37 import javax.swing.UIManager ; 38 39 44 45 public class DateChooser extends JPanel implements ActionListener { 46 private static final int cellSize = 22; 47 48 private static final int[] daysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 49 30, 31, 30, 31 }; 50 51 private static final int[] daysInMonthLeap = { 31, 29, 31, 30, 31, 30, 31, 52 31, 30, 31, 30, 31 }; 53 54 private static final Color weekendColor = Color.red.darker(); 55 56 58 59 public static final String DATE_CHANGE_CMD = "dateChanged"; 60 61 62 public static final String MONTH_CHANGE_CMD = "monthChanged"; 63 64 65 public static final String YEAR_CHANGE_CMD = "yearChanged"; 66 67 CalendarPane calendarPane; 68 69 private JLabel l_date; 71 72 private JLabel l_month; 74 75 private JButton b_lmonth; 77 78 private JButton b_rmonth; 80 81 private SimpleDateFormat datefmt = new SimpleDateFormat ("E d MMM yyyy"); 82 83 private Calendar selectedDate = null; 84 85 private Calendar minDate = null; 86 87 private Calendar maxDate = null; 88 89 private int selectedDay; 90 91 private int firstDay; 92 93 private int minDay = -1; 94 95 private int maxDay = -1; 96 97 private String [] months; 98 99 private String [] labels = new String [7]; 100 101 private Color highlightColor; 102 103 private Color disabledColor; 104 105 private boolean clipMin = false; 106 107 private boolean clipMax = false; 108 109 private boolean clipAllMin = false; 110 111 private boolean clipAllMax = false; 112 113 private int[] weekendCols = { 0, 0 }; 114 115 119 public DateChooser() { 120 this(Calendar.getInstance()); 121 } 122 123 129 public DateChooser(Calendar date) { 130 DateFormatSymbols sym = new DateFormatSymbols (); 132 133 months = sym.getShortMonths(); 134 135 String [] wkd = sym.getShortWeekdays(); 136 137 for (int i = 0; i < 7; i++) { 138 int l = Math.min(wkd[i + 1].length(), 2); 139 labels[i] = wkd[i + 1].substring(0, l); 140 } 141 142 highlightColor = UIManager.getColor("List.selectionBackground"); 145 disabledColor = Color.red; 146 147 setBorder(BorderFactory.createEtchedBorder()); 148 149 setLayout(new BorderLayout (5, 5)); 150 151 JPanel top = new JPanel (); 152 top.setLayout(new BorderLayout (0, 0)); 153 top.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); 154 155 JPanel p1 = new JPanel (); 157 p1.setLayout(new BorderLayout ()); 158 top.add(p1, BorderLayout.CENTER); 159 160 b_lmonth = new JButton ("<"); 161 b_lmonth.addActionListener(this); 162 b_lmonth.setMargin(new Insets (0, 0, 0, 0)); 163 164 p1.add(b_lmonth, BorderLayout.WEST); 168 169 l_month = new JLabel (); 170 171 175 l_date = new JLabel ("Date"); 176 l_date.setAlignmentX(0); 177 p1.add(l_date, BorderLayout.CENTER); 178 179 b_rmonth = new JButton (">"); 180 b_rmonth.addActionListener(this); 181 b_rmonth.setMargin(new Insets (0, 0, 0, 0)); 182 183 p1.add(b_rmonth, BorderLayout.EAST); 187 188 204 add("North", top); 205 206 calendarPane = new CalendarPane(); 207 calendarPane.setOpaque(false); 208 add("Center", calendarPane); 209 210 214 int fd = date.getFirstDayOfWeek(); 215 weekendCols[0] = (Calendar.SUNDAY - fd + 7) % 7; 216 weekendCols[1] = (Calendar.SATURDAY - fd + 7) % 7; 217 218 setSelectedDate(date); 219 } 220 221 public static boolean isLeapYear(int year) { 222 return ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)); 223 } 224 225 226 private Calendar copyDate(Calendar source, Calendar dest) { 227 if (dest == null) { 228 dest = Calendar.getInstance(); 229 } 230 231 dest.set(Calendar.YEAR, source.get(Calendar.YEAR)); 232 dest.set(Calendar.MONTH, source.get(Calendar.MONTH)); 233 dest.set(Calendar.DATE, source.get(Calendar.DATE)); 234 235 return (dest); 236 } 237 238 245 public void addActionListener(ActionListener listener) { 246 } 248 249 256 public void removeActionListener(ActionListener listener) { 257 } 259 260 266 public void setHighlightColor(Color color) { 267 highlightColor = color; 268 } 269 270 275 public Color getHighlightColor() { 276 return (highlightColor); 277 } 278 279 285 public Calendar getSelectedDate() { 286 return ((Calendar ) selectedDate.clone()); 287 } 288 289 295 public void setSelectedDate(Calendar date) { 296 selectedDate = copyDate(date, selectedDate); 297 selectedDay = selectedDate.get(Calendar.DAY_OF_MONTH); 298 299 _refresh(); 300 } 301 302 308 public void setMinimumDate(Calendar date) { 309 minDate = ((date == null) ? null : copyDate(date, minDate)); 310 minDay = ((date == null) ? (-1) : minDate.get(Calendar.DATE)); 311 312 _refresh(); 313 } 314 315 321 public Calendar getMinimumDate() { 322 return (minDate); 323 } 324 325 331 public void setMaximumDate(Calendar date) { 332 maxDate = ((date == null) ? null : copyDate(date, maxDate)); 333 maxDay = ((date == null) ? (-1) : maxDate.get(Calendar.DATE)); 334 335 _refresh(); 336 } 337 338 344 public Calendar getMaximumDate() { 345 return (maxDate); 346 } 347 348 354 public void setDateFormat(SimpleDateFormat format) { 355 datefmt = format; 356 357 _refresh(); 358 } 359 360 361 public void actionPerformed(ActionEvent evt) { 362 Object o = evt.getSource(); 363 364 if (o == b_lmonth) { 365 selectedDate.add(Calendar.MONTH, -1); 366 } else if (o == b_rmonth) { 367 selectedDate.add(Calendar.MONTH, 1); 368 } 369 370 381 selectedDay = 1; 382 selectedDate.set(Calendar.DATE, selectedDay); 383 384 _refresh(); 385 386 390 } 391 392 397 private void _computeFirstDay() { 398 int d = selectedDate.get(Calendar.DAY_OF_MONTH); 399 selectedDate.set(Calendar.DAY_OF_MONTH, 1); 400 firstDay = selectedDate.get(Calendar.DAY_OF_WEEK); 401 selectedDate.set(Calendar.DAY_OF_MONTH, d); 402 } 403 404 409 private void _refresh() { 410 l_date.setText(datefmt.format(selectedDate.getTime())); 411 412 l_month.setText(months[selectedDate.get(Calendar.MONTH)]); 414 415 _computeFirstDay(); 416 clipMin = clipMax = clipAllMin = clipAllMax = false; 417 418 b_lmonth.setEnabled(true); 421 b_rmonth.setEnabled(true); 422 423 if (minDate != null) { 427 int y = selectedDate.get(Calendar.YEAR); 428 int y0 = minDate.get(Calendar.YEAR); 429 int m = selectedDate.get(Calendar.MONTH); 430 int m0 = minDate.get(Calendar.MONTH); 431 432 if (y == y0) { 434 b_lmonth.setEnabled(m > m0); 435 436 if (m == m0) { 437 clipMin = true; 438 439 int d0 = minDate.get(Calendar.DATE); 440 441 if (selectedDay < d0) { 442 selectedDate.set(Calendar.DATE, selectedDay = d0); 443 } 444 445 } 448 } 449 450 clipAllMin = ((m < m0) || (y < y0)); 451 } 452 453 if (maxDate != null) { 454 int y = selectedDate.get(Calendar.YEAR); 455 int y1 = maxDate.get(Calendar.YEAR); 456 int m = selectedDate.get(Calendar.MONTH); 457 int m1 = maxDate.get(Calendar.MONTH); 458 459 if (y == y1) { 461 b_rmonth.setEnabled(m < m1); 462 463 if (m == m1) { 464 clipMax = true; 465 466 int d1 = maxDate.get(Calendar.DATE); 467 468 if (selectedDay > d1) { 469 selectedDate.set(Calendar.DATE, selectedDay = d1); 470 } 471 472 } 475 } 476 477 clipAllMax = ((m > m1) || (y > y1)); 478 } 479 480 calendarPane.repaint(); 482 } 483 484 485 private class CalendarPane extends JComponent { 486 487 private int dp = 0; 488 489 private int x0 = 0; 490 491 private int y0 = 0; 492 493 494 CalendarPane() { 495 addMouseListener(new _MouseListener2()); 496 } 497 498 499 public void paint(Graphics gc) { 500 gc.setFont(UIManager.getFont("Label.font")); 501 502 FontMetrics fm = gc.getFontMetrics(); 503 Insets ins = getInsets(); 504 int h = fm.getMaxAscent(); 505 506 gc.setColor(Color.white); 507 gc.fillRect(0, 0, getSize().width, getSize().height); 508 509 dp = ((firstDay - selectedDate.getFirstDayOfWeek() + 7) % 7); 513 514 int x = dp; 515 int y = 0; 516 y0 = ((getSize().height - getPreferredSize().height) / 2); 517 518 int yp = y0; 519 x0 = ((getSize().width - getPreferredSize().width) / 2); 520 521 int xp = x0; 522 523 paintBorder(gc); 525 526 gc.setColor(Color.black); 528 gc.clipRect(ins.left, ins.top, 529 (getSize().width - ins.left - ins.right), (getSize().height 530 - ins.top - ins.bottom)); 531 gc.translate(ins.left, ins.top); 532 533 for (int i = 0, ii = selectedDate.getFirstDayOfWeek() - 1; i < 7; i++) { 535 gc 536 .drawString(labels[ii], xp + 5 + (i * (cellSize + 2)), 537 yp + h); 538 539 if (++ii == 7) { 540 ii = 0; 541 } 542 } 543 544 yp += 20; 545 xp += (dp * (cellSize + 2)); 546 547 int month = DateChooser.this.selectedDate.get(Calendar.MONTH); 549 int dmax = (isLeapYear(DateChooser.this.selectedDate 550 .get(Calendar.YEAR)) ? daysInMonthLeap[month] 551 : daysInMonth[month]); 552 553 for (int d = 1; d <= dmax; d++) { 555 gc.setColor(Color.gray); 558 559 if (d == selectedDay) { 562 gc.setColor(highlightColor); 563 gc.fillRect(xp + 1, yp + 1, cellSize - 2, cellSize - 2); 564 } 565 566 if ((clipMin && (d < minDay)) || (clipMax && (d > maxDay)) 570 || clipAllMin || clipAllMax) { 571 gc.setColor(disabledColor); 572 } else { 573 gc 574 .setColor(((weekendCols[0] == x) || (weekendCols[1] == x)) ? weekendColor 575 : Color.black); 576 } 577 578 String ss = String.valueOf(d); 579 int sw = fm.stringWidth(ss); 580 581 if (d == selectedDay) { 582 gc.setColor(UIManager.getColor("List.selectionForeground")); 583 } 584 585 gc.drawString(ss, xp - 3 + (cellSize - sw), yp + 3 + h); 586 587 if (++x == 7) { 589 x = 0; 590 xp = x0; 591 y++; 592 yp += (cellSize + 2); 593 } else { 594 xp += (cellSize + 2); 595 } 596 } 597 } 598 599 600 public Dimension getPreferredSize() { 601 Insets ins = getInsets(); 602 603 return (new Dimension ( 604 (((cellSize + 2) * 7) + ins.left + ins.right), 605 (((cellSize + 2) * 6) + 20) + ins.top + ins.bottom)); 606 } 607 608 609 public Dimension getMinimumSize() { 610 return (getPreferredSize()); 611 } 612 613 614 private int getDay(MouseEvent evt) { 615 Insets ins = getInsets(); 616 617 int x = evt.getX() - ins.left - x0; 618 int y = evt.getY() - ins.top - 20 - y0; 619 int maxw = (cellSize + 2) * 7; 620 int maxh = (cellSize + 2) * 6; 621 622 if ((x < 0) || (x > maxw) || (y < 0) || (y > maxh)) { 624 return (-1); 625 } 626 627 y /= (cellSize + 2); 628 x /= (cellSize + 2); 629 630 int d = ((7 * y) + x) - (dp - 1); 631 632 if ((d < 1) || (d > selectedDate.getMaximum(Calendar.DAY_OF_MONTH))) { 633 return (-1); 634 } 635 636 if ((clipMin && (d < minDay)) || (clipMax && (d > maxDay))) { 637 return (-1); 638 } 639 640 return (d); 641 } 642 643 644 private class _MouseListener2 extends MouseAdapter { 645 public void mouseReleased(MouseEvent evt) { 646 int d = getDay(evt); 647 648 if (d < 0) { 649 return; 650 } 651 652 selectedDay = d; 653 654 selectedDate.set(Calendar.DAY_OF_MONTH, selectedDay); 655 _refresh(); 656 657 } 659 } 660 } 661 } 662 | Popular Tags |