1 14 package org.compiere.grid.ed; 15 16 import java.awt.*; 17 import java.awt.event.*; 18 import javax.swing.*; 19 import javax.swing.event.*; 20 import java.util.*; 21 import java.text.*; 22 import java.sql.*; 23 24 import org.compiere.util.*; 25 import org.compiere.apps.*; 26 import org.compiere.plaf.*; 27 import org.compiere.swing.*; 28 29 35 public class Calendar extends JDialog 36 implements ActionListener, MouseListener, ChangeListener, KeyListener 37 { 38 42 public Calendar (Frame frame) 43 { 44 this (frame, Msg.getMsg(Env.getCtx(), "Calendar"), null, DisplayType.Date); 45 } 47 54 public Calendar (Frame frame, String title, Timestamp startTS, int displayType) 55 { 56 super (frame, title, true); 57 Log.trace(Log.l1_User, "Calendar", startTS==null ? "null" : startTS.toString() + " " + displayType); 58 m_displayType = displayType; 59 try 61 { 62 jbInit(); 63 setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 64 } 65 catch(Exception ex) 66 { 67 Log.error("Calendar", ex); 68 } 69 loadData(startTS); 71 } 73 74 private int m_displayType; 75 76 private GregorianCalendar m_calendar; 77 78 private boolean m_hasAM_PM = false; 79 private CButton[] m_days; 81 private CButton m_today; 82 83 private int m_firstDay; 84 private int m_currentDay; 86 private int m_currentMonth; 87 private int m_currentYear; 88 private int m_current24Hour = 0; 89 private int m_currentMinute = 0; 90 private boolean m_setting = true; 92 private boolean m_abort = true; 93 private long m_lastClick = System.currentTimeMillis(); 95 private int m_lastDay = -1; 96 private static final Insets ZERO_INSETS = new Insets(0,0,0,0); 98 private CPanel mainPanel = new CPanel(); 100 private CPanel monthPanel = new CPanel(); 101 private CComboBox cMonth = new CComboBox(); 102 private JSpinner cYear = new JSpinner(new SpinnerNumberModel(2000, 1900,2100,1)); 103 private BorderLayout mainLayout = new BorderLayout(); 104 private CPanel dayPanel = new CPanel(); 105 private GridLayout dayLayout = new GridLayout(); 106 private GridBagLayout monthLayout = new GridBagLayout(); 107 private CButton bNext = new CButton(); 108 private CButton bBack = new CButton(); 109 private CPanel timePanel = new CPanel(); 110 private CComboBox fHour = new CComboBox(getHours()); 111 private CLabel lTimeSep = new CLabel(); 112 private JSpinner fMinute = new JSpinner(new MinuteModel(5)); private JCheckBox cbPM = new JCheckBox(); 114 private JLabel lTZ = new JLabel(); 115 private CButton bOK = new CButton(); 116 private GridBagLayout timeLayout = new GridBagLayout(); 117 118 122 private void jbInit() throws Exception 123 { 124 CompiereColor.setBackground(this); 125 this.addKeyListener(this); 126 mainPanel.setLayout(mainLayout); 128 mainLayout.setHgap(2); 129 mainLayout.setVgap(2); 130 mainPanel.setBorder(BorderFactory.createLoweredBevelBorder()); 131 getContentPane().add(mainPanel); 132 133 monthPanel.setLayout(monthLayout); 135 monthPanel.add(bBack, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 136 ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 137 monthPanel.add(cYear, new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0 138 ,GridBagConstraints.SOUTHEAST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 0), 0, 0)); 139 monthPanel.add(bNext, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0 140 ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 141 monthPanel.add(cMonth, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0 142 ,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); 143 mainPanel.add(monthPanel, BorderLayout.NORTH); 144 cMonth.addActionListener(this); 145 cYear.addChangeListener(this); 146 bBack.setIcon(Env.getImageIcon("Parent16.gif")); bBack.setMargin(new Insets(0,0,0,0)); 148 bBack.addActionListener(this); 149 bNext.setIcon(Env.getImageIcon("Detail16.gif")); bNext.setMargin(new Insets(0,0,0,0)); 151 bNext.addActionListener(this); 152 153 dayPanel.setLayout(dayLayout); 155 dayLayout.setColumns(7); 156 dayLayout.setHgap(2); 157 dayLayout.setRows(7); 158 dayLayout.setVgap(2); 159 mainPanel.add(dayPanel, BorderLayout.CENTER); 160 161 timePanel.setLayout(timeLayout); 163 lTimeSep.setText(" : "); 164 timePanel.add(fHour, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 165 ,GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 6, 0, 0), 0, 0)); 166 timePanel.add(lTimeSep, new GridBagConstraints(1, 0, 1, 1, 0.0, 1.0 167 ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 168 timePanel.add(fMinute, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0 169 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); 170 timePanel.add(cbPM, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0 171 ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0)); 172 timePanel.add(lTZ, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0 173 ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0)); 174 timePanel.add(bOK, new GridBagConstraints(5, 0, 1, 1, 0.0, 0.0 175 ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 6, 0, 2), 0, 0)); 176 mainPanel.add(timePanel, BorderLayout.SOUTH); 177 fHour.addKeyListener(this); ((JSpinner.DefaultEditor)fMinute.getEditor()).getTextField().addKeyListener(this); 180 fMinute.addChangeListener(this); 181 cbPM.addActionListener(this); 182 cbPM.addKeyListener(this); 183 bOK.setIcon(Env.getImageIcon("Ok16.gif")); 184 bOK.setMargin(new Insets(0,1,0,1)); 185 bOK.addActionListener(this); 186 } 188 192 protected void processWindowEvent(WindowEvent e) 193 { 194 super.processWindowEvent(e); 196 if (e.getID() == WindowEvent.WINDOW_OPENED) 197 { 198 if (m_displayType == DisplayType.Time) 199 fHour.requestFocus(); 200 else if (m_today != null) 201 m_today.requestFocus(); 202 } 203 } 205 206 207 214 private void loadData (Timestamp startTS) 215 { 216 m_calendar = new GregorianCalendar(Language.getLanguage().getLocale()); 217 if (startTS == null) 218 m_calendar.setTimeInMillis(System.currentTimeMillis()); 219 else 220 m_calendar.setTime(startTS); 221 m_firstDay = m_calendar.getFirstDayOfWeek(); 222 Locale loc = Language.getLanguage().getLocale(); 224 SimpleDateFormat formatDate = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.LONG, loc); 225 SimpleDateFormat formatTime = (SimpleDateFormat)DateFormat.getTimeInstance(DateFormat.SHORT, loc); 227 m_hasAM_PM = formatTime.toPattern().indexOf('a') != -1; 228 if (m_hasAM_PM) 229 cbPM.setText(formatTime.getDateFormatSymbols().getAmPmStrings()[1]); 230 else 231 cbPM.setVisible(false); 232 233 m_currentYear = m_calendar.get(java.util.Calendar.YEAR); 235 cYear.setEditor(new JSpinner.NumberEditor(cYear, "0000")); 236 cYear.setValue(new Integer (m_currentYear)); 237 238 String [] months = formatDate.getDateFormatSymbols().getMonths(); 240 for (int i = 0; i < months.length; i++) 241 { 242 KeyNamePair p = new KeyNamePair(i+1, months[i]); 243 if (!months[i].equals("")) 244 cMonth.addItem(p); 245 } 246 m_currentMonth = m_calendar.get(java.util.Calendar.MONTH) + 1; cMonth.setSelectedIndex(m_currentMonth-1); 248 249 String [] days = formatDate.getDateFormatSymbols().getShortWeekdays(); for (int i = m_firstDay; i < 7 + m_firstDay; i++) 252 { 253 int index = i > 7 ? i -7 : i; 254 dayPanel.add(createWeekday(days[index]), null); 255 } 256 257 m_days = new CButton[6*7]; 259 m_currentDay = m_calendar.get(java.util.Calendar.DATE); 260 for (int i = 0; i < 6; i++) for (int j = 0; j < 7; j++) { 263 int index = i*7 + j; 264 m_days[index] = createDay(); 265 dayPanel.add(m_days[index], null); 266 } 267 268 m_days[m_days.length-1].setBackground(Color.green); 270 m_days[m_days.length-1].setText("*"); 271 m_days[m_days.length-1].setToolTipText(Msg.getMsg(Env.getCtx(), "Today")); 272 273 m_current24Hour = m_calendar.get(java.util.Calendar.HOUR_OF_DAY); 275 m_currentMinute = m_calendar.get(java.util.Calendar.MINUTE); 276 277 timePanel.setVisible(m_displayType == DisplayType.DateTime || m_displayType == DisplayType.Time); 279 monthPanel.setVisible(m_displayType != DisplayType.Time); 280 dayPanel.setVisible(m_displayType != DisplayType.Time); 281 282 m_setting = false; 284 setCalendar(); 285 } 287 292 private JLabel createWeekday (String title) 293 { 294 JLabel label = new JLabel(title); 295 label.setBorder(BorderFactory.createRaisedBevelBorder()); 296 label.setHorizontalAlignment(SwingConstants.CENTER); 297 label.setHorizontalTextPosition(SwingConstants.CENTER); 298 label.setRequestFocusEnabled(false); 299 return label; 300 } 302 306 private CButton createDay() 307 { 308 CButton button = new CButton(); 309 button.setBorder(BorderFactory.createLoweredBevelBorder()); 310 button.setHorizontalTextPosition(SwingConstants.CENTER); 311 button.setMargin(ZERO_INSETS); 312 button.addActionListener(this); 313 button.addMouseListener(this); 314 button.addKeyListener(this); 315 return button; 316 } 318 322 private Object [] getHours() 323 { 324 Locale loc = Language.getLanguage().getLocale(); 325 SimpleDateFormat formatTime = (SimpleDateFormat)DateFormat.getTimeInstance(DateFormat.SHORT, loc); 327 m_hasAM_PM = formatTime.toPattern().indexOf('a') != -1; 328 Object [] retValue = new Object [m_hasAM_PM ? 12 : 24]; 330 if (m_hasAM_PM) 331 { 332 retValue[0] = "12"; 333 for (int i = 1; i < 10; i++) 334 retValue[i] = " " + String.valueOf(i); 335 for (int i = 10; i < 12; i++) 336 retValue[i] = String.valueOf(i); 337 } 338 else 339 { 340 for (int i = 0; i < 10; i++) 341 retValue[i] = "0" + String.valueOf(i); 342 for (int i = 10; i < 24; i++) 343 retValue[i] = String.valueOf(i); 344 } 345 return retValue; 346 } 348 349 350 353 private void setCalendar() 354 { 355 if (m_setting) 356 return; 357 359 m_setting = true; 361 cMonth.setSelectedIndex(m_currentMonth-1); 362 cYear.setValue(new Integer (m_currentYear)); 363 m_setting = false; 364 365 m_calendar.set(m_currentYear, m_currentMonth-1, 1); int dayOne = m_calendar.get(java.util.Calendar.DAY_OF_WEEK); 369 int lastDate = m_calendar.getActualMaximum(java.util.Calendar.DATE); 370 371 dayOne -= m_firstDay; 373 if (dayOne < 0) 374 dayOne += 7; 375 lastDate += dayOne - 1; 376 377 int curDay = 1; 379 for (int i = 0; i < m_days.length-1; i++) 380 { 381 if (i >= dayOne && i <= lastDate) 382 { 383 if (m_currentDay == curDay) 384 { 385 m_days[i].setBackground(Color.blue); 386 m_days[i].setForeground(Color.yellow); 387 m_today = m_days[i]; 388 m_today.requestFocus(); 389 } 390 else 391 { 392 m_days[i].setBackground(Color.white); 393 m_days[i].setForeground(Color.black); 394 } 395 m_days[i].setText(String.valueOf(curDay++)); 396 m_days[i].setReadWrite(true); 397 } 398 else 399 { 400 m_days[i].setText(""); 401 m_days[i].setReadWrite(false); 402 m_days[i].setBackground(CompierePLAF.getFieldBackground_Inactive()); 403 } 404 } 405 406 boolean pm = m_current24Hour > 12; 408 int index = m_current24Hour; 409 if (pm && m_hasAM_PM) 410 index -= 12; 411 if (index < 0 || index >= fHour.getItemCount()) 412 index = 0; 413 fHour.setSelectedIndex(index); 414 int m = m_calendar.get(java.util.Calendar.MINUTE); 416 fMinute.setValue(new Integer (m)); 417 cbPM.setSelected(pm); 419 TimeZone tz = m_calendar.getTimeZone(); 421 lTZ.setText(tz.getDisplayName(tz.inDaylightTime(m_calendar.getTime()), TimeZone.SHORT)); 422 423 m_calendar.set(m_currentYear, m_currentMonth-1, m_currentDay, m_current24Hour, m_currentMinute, 0); 425 m_calendar.set(java.util.Calendar.MILLISECOND, 0); 426 } 428 432 private void setTime() 433 { 434 int h = fHour.getSelectedIndex(); 436 m_current24Hour = h; 437 if (m_hasAM_PM && cbPM.isSelected()) 438 m_current24Hour += 12; 439 if (m_current24Hour < 0 || m_current24Hour > 23) 440 m_current24Hour = 0; 441 442 Integer ii = (Integer )fMinute.getValue(); 444 m_currentMinute = ii.intValue(); 445 if (m_currentMinute < 0 || m_currentMinute > 59) 446 m_currentMinute = 0; 447 } 449 453 public Timestamp getTimestamp() 454 { 455 m_calendar.set(m_currentYear, m_currentMonth-1, m_currentDay, m_current24Hour, m_currentMinute, 0); 458 m_calendar.set(java.util.Calendar.MILLISECOND, 0); 459 460 if (m_abort) 462 return null; 463 long time = m_calendar.getTimeInMillis(); 464 if (m_displayType == DisplayType.Date) 465 time = new java.sql.Date (time).getTime(); 466 else if (m_displayType == DisplayType.Time) 467 time = new Time(time).getTime(); return new Timestamp(time); 469 } 471 472 473 479 public void actionPerformed (ActionEvent e) 480 { 481 if (m_setting) 482 return; 483 setTime(); 485 486 if (e.getSource() == bOK) 487 { 488 m_abort = false; 489 dispose(); 490 return; 491 } 492 else if (e.getSource() == bBack) 493 { 494 if (--m_currentMonth < 1) 495 { 496 m_currentMonth = 12; 497 m_currentYear--; 498 } 499 m_lastDay = -1; 500 } 501 else if (e.getSource() == bNext) 502 { 503 if (++m_currentMonth > 12) 504 { 505 m_currentMonth = 1; 506 m_currentYear++; 507 } 508 m_lastDay = -1; 509 } 510 else if (e.getSource() instanceof JButton) 511 { 512 JButton b = (JButton)e.getSource(); 513 String text = b.getText(); 514 if (text.equals("*")) 516 { 517 m_calendar.setTime(new Timestamp(System.currentTimeMillis())); 518 m_currentDay = m_calendar.get(java.util.Calendar.DATE); 519 m_currentMonth = m_calendar.get(java.util.Calendar.MONTH) + 1; 520 m_currentYear = m_calendar.get(java.util.Calendar.YEAR); 521 } 522 else if (text.length() > 0) 524 { 525 m_currentDay = Integer.parseInt(text); 526 long currentClick = System.currentTimeMillis(); 527 if (m_currentDay == m_lastDay 528 && currentClick-m_lastClick < 1000) { 530 m_abort = false; 531 dispose(); 532 return; 533 } 534 m_lastClick = currentClick; 535 m_lastDay = m_currentDay; 536 } 537 } 538 else if (e.getSource() == cbPM) 539 { 540 setTime(); 541 m_lastDay = -1; 542 } 543 else 544 { 545 m_currentMonth = cMonth.getSelectedIndex()+1; 547 m_lastDay = -1; 548 } 549 setCalendar(); 550 } 552 556 public void stateChanged(ChangeEvent e) 557 { 558 if (m_setting) 559 return; 560 561 if (e.getSource() == fMinute) 563 { 564 setTime(); 565 return; 566 } 567 m_currentYear = ((Integer )cYear.getValue()).intValue(); 569 m_lastDay = -1; 570 setCalendar(); 571 } 573 574 575 579 public void mouseClicked(MouseEvent e) 580 { 581 if (e.getClickCount() == 2) 582 { 583 m_abort = false; 584 dispose(); 585 } 586 } 588 public void mousePressed(MouseEvent e) {} 589 public void mouseEntered(MouseEvent e) {} 590 public void mouseExited(MouseEvent e) {} 591 public void mouseReleased(MouseEvent e) {} 592 593 594 595 599 public void keyReleased(KeyEvent e) 600 { 601 if (e.getSource() instanceof JButton) 604 { 605 if (e.getKeyCode() == KeyEvent.VK_PAGE_DOWN) 606 { 607 if (++m_currentMonth > 12) 608 { 609 m_currentMonth = 1; 610 m_currentYear++; 611 } 612 setCalendar(); 613 return; 614 } 615 if (e.getKeyCode() == KeyEvent.VK_PAGE_UP) 616 { 617 if (--m_currentMonth < 1) 618 { 619 m_currentMonth = 12; 620 m_currentYear--; 621 } 622 setCalendar(); 623 return; 624 } 625 626 int offset = 0; 628 if (e.getKeyCode() == KeyEvent.VK_RIGHT) 629 offset = 1; 630 else if (e.getKeyCode() == KeyEvent.VK_LEFT) 631 offset = -1; 632 else if (e.getKeyCode() == KeyEvent.VK_UP) 633 offset = -7; 634 else if (e.getKeyCode() == KeyEvent.VK_DOWN) 635 offset = 7; 636 if (offset != 0) 637 { 638 System.out.println(m_calendar.getTime() + " offset=" + offset); 639 m_calendar.add(java.util.Calendar.DAY_OF_YEAR, offset); 640 System.out.println(m_calendar.getTime()); 641 642 m_currentDay = m_calendar.get(java.util.Calendar.DAY_OF_MONTH); 643 m_currentMonth = m_calendar.get(java.util.Calendar.MONTH) + 1; 644 m_currentYear = m_calendar.get(java.util.Calendar.YEAR); 645 setCalendar(); 646 return; 647 } 648 actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "")); 650 } 651 652 if (e.getKeyCode() == KeyEvent.VK_ENTER) 654 { 655 m_abort = false; 656 setTime(); 657 dispose(); 658 return; 659 } 660 661 setTime(); 663 m_lastDay = -1; 664 } 666 public void keyTyped(KeyEvent e) 667 { 668 } 670 public void keyPressed(KeyEvent e) 671 { 672 } 674 675 } 677 686 class MinuteModel extends SpinnerNumberModel 687 { 688 693 public MinuteModel(int snapSize) 694 { 695 super(0,0,59, 1); m_snapSize = snapSize; 697 } 699 700 private int m_snapSize; 701 702 706 public Object getNextValue() 707 { 708 int minutes = ((Integer )getValue()).intValue(); 709 minutes += m_snapSize; 710 if (minutes >= 60) 711 minutes -= 60; 712 int steps = minutes / m_snapSize; 714 return new Integer (steps * m_snapSize); 715 } 717 718 722 public Object getPreviousValue() 723 { 724 int minutes = ((Integer )getValue()).intValue(); 725 minutes -= m_snapSize; 726 if (minutes < 0) 727 minutes += 60; 728 int steps = minutes / m_snapSize; 730 if (minutes % m_snapSize != 0) 731 steps++; 732 if (steps * m_snapSize > 59) 733 steps = 0; 734 return new Integer (steps * m_snapSize); 735 } 737 } | Popular Tags |