/** * Set up the calendar panel with the basic layout and components. These are not date specific. */ private void createCalendarComponents() { // The date panel will hold the calendar and/or the time spinner JPanel datePanel = new JPanel(new BorderLayout(2, 2)); // Create the calendar if we are displaying a calendar if ((selectedComponents & DISPLAY_DATE) > 0) { formatMonth = new SimpleDateFormat("MMM", locale); formatWeekDay = new SimpleDateFormat("EEE", locale); // Set up the shared keyboard bindings setInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap); setActionMap(actionMap); // Set up the decrement buttons yearDecrButton = new JButton( new ButtonAction( "YearDecrButton", "YearDecrButtonMnemonic", "YearDecrButtonAccelerator", "YearDecrButtonImage", "YearDecrButtonShort", "YearDecrButtonLong", YEAR_DECR_BUTTON)); monthDecrButton = new JButton( new ButtonAction( "MonthDecrButton", "MonthDecrButtonMnemonic", "MonthDecrButtonAccelerator", "MonthDecrButtonImage", "MonthDecrButtonShort", "MonthDecrButtonLong", MONTH_DECR_BUTTON)); JPanel decrPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)); decrPanel.add(yearDecrButton); decrPanel.add(monthDecrButton); // Set up the month/year label monthYearLabel = new JLabel(); monthYearLabel.setHorizontalAlignment(JLabel.CENTER); // Set up the increment buttons monthIncrButton = new JButton( new ButtonAction( "MonthIncrButton", "MonthIncrButtonMnemonic", "MonthIncrButtonAccelerator", "MonthIncrButtonImage", "MonthIncrButtonShort", "MonthIncrButtonLong", MONTH_INCR_BUTTON)); yearIncrButton = new JButton( new ButtonAction( "YearIncrButton", "YearIncrButtonMnemonic", "YearIncrButtonAccelerator", "YearIncrButtonImage", "YearIncrButtonShort", "YearIncrButtonLong", YEAR_INCR_BUTTON)); JPanel incrPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)); incrPanel.add(monthIncrButton); incrPanel.add(yearIncrButton); // Put them all together JPanel monthYearNavigator = new JPanel(new BorderLayout(2, 2)); monthYearNavigator.add(decrPanel, BorderLayout.WEST); monthYearNavigator.add(monthYearLabel); monthYearNavigator.add(incrPanel, BorderLayout.EAST); // Set up the day panel JPanel dayPanel = new JPanel(new GridLayout(7, 7)); int firstDay = displayCalendar.getFirstDayOfWeek(); // Get the week day labels. The following technique is used so // that we can start the calendar on the right day of the week and // we can get the week day labels properly localized Calendar temp = Calendar.getInstance(locale); temp.set(2000, Calendar.MARCH, 15); while (temp.get(Calendar.DAY_OF_WEEK) != firstDay) { temp.add(Calendar.DATE, 1); } dayOfWeekLabels = new JLabel[7]; for (int i = 0; i < 7; i++) { Date date = temp.getTime(); String dayOfWeek = formatWeekDay.format(date); dayOfWeekLabels[i] = new JLabel(dayOfWeek); dayOfWeekLabels[i].setHorizontalAlignment(JLabel.CENTER); dayPanel.add(dayOfWeekLabels[i]); temp.add(Calendar.DATE, 1); } // Add all the day buttons dayButtons = new JToggleButton[6][7]; dayGroup = new ButtonGroup(); DayListener dayListener = new DayListener(); for (int row = 0; row < 6; row++) { for (int day = 0; day < 7; day++) { dayButtons[row][day] = new JToggleButton(); dayButtons[row][day].addItemListener(dayListener); dayPanel.add(dayButtons[row][day]); dayGroup.add(dayButtons[row][day]); } } // We add this special button to the button group, so we have a // way of unselecting all the visible buttons offScreenButton = new JToggleButton("X"); dayGroup.add(offScreenButton); // Combine the navigators and days datePanel.add(monthYearNavigator, BorderLayout.NORTH); datePanel.add(dayPanel); } // Create the time spinner field if we are displaying the time if ((selectedComponents & DISPLAY_TIME) > 0) { // Create the time component spinnerDateModel = new SpinnerDateModel(); spinnerDateModel.addChangeListener(new TimeListener()); spinner = new JSpinner(spinnerDateModel); JSpinner.DateEditor dateEditor = new JSpinner.DateEditor(spinner, timePattern); dateEditor.getTextField().setEditable(false); dateEditor.getTextField().setHorizontalAlignment(JTextField.CENTER); spinner.setEditor(dateEditor); // Set the input/action maps for the spinner. (Only BACK_SPACE // seems to work!) InputMap sim = new InputMap(); sim.put(KeyStroke.getKeyStroke("BACK_SPACE"), "setNullDate"); sim.put(KeyStroke.getKeyStroke("DELETE"), "setNullDate"); sim.setParent(spinner.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)); ActionMap sam = new ActionMap(); sam.put( "setNullDate", new AbstractAction("setNullDate") { public void actionPerformed(ActionEvent e) { JCalendar.this.setDate(null); } }); sam.setParent(spinner.getActionMap()); spinner.setInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, sim); spinner.setActionMap(sam); // Create a special panel for the time display JPanel timePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2)); timePanel.add(spinner); // Now add it to the bottom datePanel.add(timePanel, BorderLayout.SOUTH); } setLayout(new BorderLayout(2, 2)); add(datePanel); // Add today's date at the bottom of the calendar/time, if needed if (isTodayDisplayed) { Object[] args = {new Date()}; String todaysDate = MessageFormat.format(bundle.getString("Today"), args); todaysLabel = new JLabel(todaysDate); todaysLabel.setHorizontalAlignment(JLabel.CENTER); // Add today's date at the very bottom add(todaysLabel, BorderLayout.SOUTH); } }
/** Update the calendar panel to display the currently selected date. */ private void updateCalendarComponents() { if ((selectedComponents & DISPLAY_DATE) > 0) { // Unselect all visible dates offScreenButton.setSelected(true); // Get the display date. We only need the month and year displayMonth = displayCalendar.get(Calendar.MONTH); displayYear = displayCalendar.get(Calendar.YEAR); // Get the localized display month name and year String month = formatMonth.format(displayCalendar.getTime()); String year = Integer.toString(displayYear); { Object[] args = {month, year}; monthYearLabel.setText(MessageFormat.format(bundle.getString("MonthYearTitle"), args)); } // If the month or year have changed, we need to re-lay out // the days. Otherwise, we don't if (!month.equals(lastMonth) || !year.equals(lastYear)) { // Create a temporary calendar that we will use to // determine where day 1 goes and how many days there are // in this month Calendar temp = (Calendar) displayCalendar.clone(); temp.set(Calendar.DATE, 1); int dayOfWeek = temp.get(Calendar.DAY_OF_WEEK); int firstDay = temp.getFirstDayOfWeek(); // Determine how many blank slots occur before day 1 of this // month int dayPtr; for (dayPtr = 0; dayPtr < 7; dayPtr++) { int curDay = ((firstDay - 1) + dayPtr) % 7 + 1; if (curDay != dayOfWeek) { dayButtons[0][dayPtr].setText(""); dayButtons[0][dayPtr].setEnabled(false); } else { break; } } // Determine the number of days in this month int maxDays = temp.getActualMaximum(Calendar.DATE); // Fill in the days int row = 0; for (int day = 1; day <= maxDays; day++) { dayButtons[row][dayPtr].setText(Integer.toString(day)); dayButtons[row][dayPtr].setEnabled(true); // If this is the selected date, select the button; // otherwise, deselect it if (day == selectedDay && displayMonth == selectedMonth && displayYear == selectedYear) { dayButtons[row][dayPtr].setSelected(true); } else { dayButtons[row][dayPtr].getModel().setSelected(false); } // Wrap as needed dayPtr = (dayPtr + 1) % 7; if (dayPtr == 0) row++; } // Set the blanks slots after the last day while (row < 6) { dayButtons[row][dayPtr].setText(""); dayButtons[row][dayPtr].setEnabled(false); dayButtons[row][dayPtr].getModel().setSelected(false); dayPtr = (dayPtr + 1) % 7; if (dayPtr == 0) row++; } } } // Update the time component, if displayed if ((selectedComponents & DISPLAY_TIME) > 0) { // If no date is selected, we set the date used by the time // field to today @ noon. We also make the field insensitive // -- the user must pick a non-null date before being able to // change the time (unless all we have is a time field) if (isNullDate) { Calendar temp = (Calendar) selectedCalendar.clone(); temp.setTime(new Date()); temp.set(Calendar.HOUR, 12); temp.set(Calendar.MINUTE, 0); temp.set(Calendar.SECOND, 0); spinnerDateModel.setValue(temp.getTime()); spinner.setEnabled((selectedComponents & DISPLAY_DATE) == 0); } // If a date is selected, use it else { spinner.setEnabled(JCalendar.this.isEnabled()); spinnerDateModel.setValue(selectedCalendar.getTime()); spinnerDateModel.setStart(null); spinnerDateModel.setEnd(null); spinner.revalidate(); } } }