1 package org.mc4j.console.swing.editor; 2 3 33 34 import java.awt.BorderLayout ; 35 import java.awt.Dimension ; 36 import java.awt.Font ; 37 import java.awt.Point ; 38 import java.awt.event.ActionEvent ; 39 import java.awt.event.ActionListener ; 40 import java.awt.event.KeyAdapter ; 41 import java.awt.event.KeyEvent ; 42 import java.awt.event.WindowAdapter ; 43 import java.awt.event.WindowEvent ; 44 import java.text.DateFormat ; 45 import java.text.DateFormatSymbols ; 46 import java.text.ParseException ; 47 import java.util.Calendar ; 48 import java.util.Date ; 49 import java.util.GregorianCalendar ; 50 51 import javax.swing.BorderFactory ; 52 import javax.swing.BoxLayout ; 53 import javax.swing.JFormattedTextField ; 54 import javax.swing.JFrame ; 55 import javax.swing.JPanel ; 56 import javax.swing.JPopupMenu ; 57 import javax.swing.JTable ; 58 import javax.swing.JTextField ; 59 import javax.swing.ListSelectionModel ; 60 import javax.swing.SwingConstants ; 61 import javax.swing.event.ListSelectionEvent ; 62 import javax.swing.event.ListSelectionListener ; 63 import javax.swing.plaf.basic.BasicArrowButton ; 64 import javax.swing.table.DefaultTableModel ; 65 import javax.swing.table.JTableHeader ; 66 import javax.swing.table.TableColumn ; 67 68 75 public class CalendarComboBox extends JPanel { 76 77 private static final DateFormatSymbols dfs = new DateFormatSymbols (); 79 private static final String [] months = dfs.getMonths(); 80 private static final String [] dayNames = new String [7]; 81 82 private final JPanel inputPanel = new JPanel (); 84 85 private final JFormattedTextField input = new JFormattedTextField (new Date ()); 86 private final BasicArrowButton comboBtn = new BasicArrowButton (SwingConstants.SOUTH); 87 88 protected final JPanel calPanel = new JPanel (); 90 private final JTextField calLabel = new JTextField (11); 91 private final Calendar current = new GregorianCalendar (); 92 private final CalendarModel display = new CalendarModel(6, 6); 93 private final JTable table = new JTable (display); 94 95 private final BasicArrowButton nextBtn = new BasicArrowButton (SwingConstants.EAST); 96 private final BasicArrowButton prevBtn = new BasicArrowButton (SwingConstants.WEST); 97 private final BasicArrowButton closeCalendarBtn = new BasicArrowButton (SwingConstants.NORTH); 98 99 private JPopupMenu popup; 100 101 104 public CalendarComboBox() { 105 this(new GregorianCalendar (), false); 106 } 107 108 117 public CalendarComboBox(boolean fillComponent) { 118 this(new GregorianCalendar (), fillComponent); 119 } 120 121 127 public CalendarComboBox(final Calendar cal, boolean fillComponent) { 128 super(); 129 130 Date date = cal.getTime(); 132 current.setTime(date); 133 input.setValue(date); 134 135 buildInputPanel(); 137 138 139 if (fillComponent) { 141 setLayout(new BorderLayout ()); 142 add(inputPanel, BorderLayout.CENTER); 143 } else { 144 add(inputPanel); 145 } 146 147 buildCalendarDisplay(); 148 registerListeners(); 149 } 150 151 155 private void buildInputPanel() { 156 inputPanel.setLayout(new BoxLayout (inputPanel, BoxLayout.X_AXIS)); 157 158 input.setColumns(12); 159 inputPanel.add(input); 160 161 comboBtn.setActionCommand("combo"); 162 inputPanel.add(comboBtn); 163 } 164 165 168 private void buildCalendarDisplay() { 169 170 table.setCellSelectionEnabled(true); 173 table.getTableHeader().setResizingAllowed(false); 174 table.getTableHeader().setReorderingAllowed(false); 175 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 176 table.setShowGrid(false); 177 178 String [] names = dfs.getShortWeekdays(); 186 187 for (int i = 1; i < names.length; i++) { 188 dayNames[i - 1] = "" + names[i].charAt(0); 189 } 190 191 display.setColumnIdentifiers(dayNames); 192 table.setModel(display); 193 194 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 197 int count = table.getColumnCount(); 198 199 for (int i = 0; i < count; i++) { 200 TableColumn col = table.getColumnModel().getColumn(i); 201 col.setPreferredWidth(20); 202 } 203 204 JTableHeader header = table.getTableHeader(); 209 header.setFont(header.getFont().deriveFont(Font.BOLD)); 210 211 JPanel panel = new JPanel (); 212 panel.setLayout(new BoxLayout (panel, BoxLayout.Y_AXIS)); 213 panel.add(header); 214 panel.add(table); 215 216 calPanel.setLayout(new BorderLayout ()); 218 calPanel.add(buildCalendarNavigationPanel(), BorderLayout.NORTH); 219 calPanel.add(panel); 220 } 221 222 227 private JPanel buildCalendarNavigationPanel() { 228 JPanel panel = new JPanel () { 229 230 }; 231 panel.setLayout(new BorderLayout ()); 233 234 calLabel.setEditable(false); 239 calLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); 240 int fontSize = calLabel.getFont().getSize(); 241 calLabel.setFont(calLabel.getFont().deriveFont(Font.PLAIN, fontSize - 1)); 242 panel.add(calLabel, BorderLayout.CENTER); 243 244 prevBtn.setActionCommand("prevBtn"); 246 nextBtn.setActionCommand("nextBtn"); 247 closeCalendarBtn.setActionCommand("close"); 248 249 panel.add(prevBtn, BorderLayout.WEST); 250 panel.add(nextBtn, BorderLayout.EAST); 251 253 return panel; 254 } 255 256 260 private void registerListeners() { 261 262 ButtonActionListener btnListener = new ButtonActionListener(); 263 264 input.addKeyListener(new InputListener()); 266 comboBtn.addActionListener(btnListener); 267 268 CalendarSelectionListener listener = new CalendarSelectionListener(); 273 table.getSelectionModel().addListSelectionListener(listener); 274 table.getColumnModel().getSelectionModel() 275 .addListSelectionListener(listener); 276 277 prevBtn.addActionListener(btnListener); 279 nextBtn.addActionListener(btnListener); 280 closeCalendarBtn.addActionListener(btnListener); 281 282 } 283 284 296 private void updateTable(Calendar cal) { 297 298 Calendar dayOne = new GregorianCalendar (cal.get(Calendar.YEAR), 299 cal.get(Calendar.MONTH), 300 1); 301 302 int actualDays = cal.getActualMaximum(Calendar.DATE); 305 int startIndex = dayOne.get(Calendar.DAY_OF_WEEK) - 1; 306 307 int day = 1; 309 for (int row = 0; row < 6; row++) { 310 for (int col = 0; col < 7; col++) { 311 if ((col < startIndex && row == 0) || day > actualDays) { 312 display.setValueAt("", row, col); 314 } else { 315 display.setValueAt(new Integer (day), row, col); 316 day++; 317 } 318 } 319 } 320 321 calLabel.setText(months[cal.get(Calendar.MONTH)] + 323 ", " + cal.get(Calendar.YEAR)); 324 325 table.changeSelection(cal.get(Calendar.WEEK_OF_MONTH) - 1, 327 cal.get(Calendar.DAY_OF_WEEK) - 1, 328 false, false); 329 } 330 331 335 private JPopupMenu getPopup() { 336 Point p = input.getLocationOnScreen(); 337 Dimension inputSize = input.getPreferredSize(); 338 Dimension calendarSize = calPanel.getPreferredSize(); 339 340 351 352 JPopupMenu menu = new JPopupMenu (); 355 menu.add(calPanel); 356 357 return menu; 358 } 359 360 365 public Calendar getDate() { 366 return current; 367 } 368 369 376 public void setDate(Date newDate) { 377 current.setTime(newDate); 378 input.setValue(current.getTime()); 379 } 380 381 384 private class CalendarModel extends DefaultTableModel { 385 386 public CalendarModel(int row, int col) { 387 super(row, col); 388 } 389 390 396 public Class getColumnClass(int column) { 397 return Integer .class; 398 } 399 400 404 public boolean isCellEditable(int row, int col) { 405 return false; 406 } 407 } 408 409 419 private class ButtonActionListener implements ActionListener { 420 public void actionPerformed(ActionEvent e) { 421 String cmd = e.getActionCommand(); 422 423 if (cmd.equals("prevBtn")) { 424 current.add(Calendar.MONTH, -1); 425 input.setValue(current.getTime()); 426 } else if (cmd.equals("nextBtn")) { 427 current.add(Calendar.MONTH, 1); 428 input.setValue(current.getTime()); 429 } else if (cmd.equals("close")) { 430 popup.hide(); 431 comboBtn.setEnabled(true); 432 } else { 433 popup = getPopup(); 435 calPanel.setPreferredSize(new Dimension ((int) inputPanel.getPreferredSize().getWidth(), (int) calPanel.getPreferredSize().getHeight())); 436 popup.show(inputPanel, 0, inputPanel.getHeight()); 437 } 438 439 updateTable(current); 440 } 441 } 442 443 448 private class CalendarSelectionListener implements ListSelectionListener { 449 450 public void valueChanged(ListSelectionEvent e) { 451 if (!e.getValueIsAdjusting()) { 452 int row = table.getSelectedRow(); 453 int col = table.getSelectedColumn(); 454 455 Object value = null; 456 try { 457 value = display.getValueAt(row, col); 458 } catch (ArrayIndexOutOfBoundsException ex) { 459 } 462 463 if (value instanceof Integer ) { 464 int day = ((Integer ) value).intValue(); 465 current.set(Calendar.DATE, day); 466 input.setValue(current.getTime()); 467 } 468 } 469 } 470 } 471 472 477 private class InputListener extends KeyAdapter { 478 public void keyTyped(KeyEvent e) { 479 480 DateFormat df = DateFormat.getDateInstance(); 481 Date date = null; 482 483 try { 484 date = df.parse(input.getText()); 485 } catch (ParseException ex) { 486 } 488 489 char c = e.getKeyChar(); 492 if (date != null && 493 (c == KeyEvent.VK_ENTER || c == KeyEvent.VK_TAB)) { 494 current.setTime(date); 495 updateTable(current); 496 } 497 } 498 } 499 500 public static void main(String [] args) { 501 JFrame frame = new JFrame ("Calendar combo box test"); 502 frame.getContentPane().add(new CalendarComboBox(true)); 503 504 frame.setVisible(true); 505 frame.addWindowListener(new WindowAdapter () { 506 public void windowClosing(WindowEvent e) { 507 System.exit(0); 508 } 509 }); 510 } 511 } | Popular Tags |