📄 jxmonthview.java
字号:
// If the calendar is traversable, check the icon heights and // adjust the month box height accordingly. _monthBoxHeight = _boxHeight; if (_traversable) { int newHeight = _monthDownImage.getIconHeight() + _arrowPaddingY + _arrowPaddingY; if (newHeight > _monthBoxHeight) { _monthBoxHeight = newHeight; } } // Modify _boxWidth if month string is longer _dim.width = (_boxWidth + (2 * _boxPaddingX)) * DAYS_IN_WEEK; if (_dim.width < longestMonthWidth) { double diff = longestMonthWidth - _dim.width; if (_traversable) { diff += _monthDownImage.getIconWidth() + _monthUpImage.getIconWidth() + (_arrowPaddingX * 4); } _boxWidth += Math.ceil(diff / (double)DAYS_IN_WEEK); _dim.width = (_boxWidth + (2 * _boxPaddingX)) * DAYS_IN_WEEK; } // Keep track of calendar width and height for use later. _calendarWidth = (_boxWidth + (2 * _boxPaddingX)) * DAYS_IN_WEEK; _calendarHeight = ((_boxPaddingY + _boxHeight + _boxPaddingY) * 7) + (_boxPaddingY + _monthBoxHeight + _boxPaddingY); // Calculate minimum width/height for the component. _dim.height = (_calendarHeight * _minCalRows) + (CALENDAR_SPACING * (_minCalRows - 1)); _dim.width = (_calendarWidth * _minCalCols) + (CALENDAR_SPACING * (_minCalCols - 1)); // Add insets to the dimensions. Insets insets = getInsets(); _dim.width += insets.left + insets.right; _dim.height += insets.top + insets.bottom; // Restore calendar. _cal.setTimeInMillis(_firstDisplayedDate); calculateNumDisplayedCals(); calculateStartPosition(); if (_startSelectedDate != -1 || _endSelectedDate != -1) { if (_startSelectedDate > _lastDisplayedDate || _startSelectedDate < _firstDisplayedDate) { // Already does the recalculation for the dirty rect. ensureDateVisible(_startSelectedDate); } else { calculateDirtyRectForSelection(); } } } private void updateToday() { // Update _today. _cal.setTimeInMillis(_today); _cal.add(Calendar.DAY_OF_MONTH, 1); _today = _cal.getTimeInMillis(); // Restore calendar. _cal.setTimeInMillis(_firstDisplayedDate); repaint(); } /** * Returns the minimum size needed to display this component. * * @return Dimension Minimum size. */ @Override public Dimension getMinimumSize() { return getPreferredSize(); } /** * Returns the preferred size of this component. * * @return Dimension Preferred size. */ @Override public Dimension getPreferredSize() { updateIfNecessary(); return new Dimension(_dim); } /** * Returns the maximum size of this component. * * @return Dimension Maximum size. */ @Override public Dimension getMaximumSize() { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } /** * Sets the border of this component. The Border object is responsible * for defining the insets for the component (overriding any insets set * directly on the component) and for optionally rendering any border * decorations within the bounds of those insets. Borders should be used * (rather than insets) for creating both decorative and non-decorative * (such as margins and padding) regions for a swing component. Compound * borders can be used to nest multiple borders within a single component. * <p> * As the border may modify the bounds of the component, setting the border * may result in a reduced number of displayed calendars. * * @param border Border. */ @Override public void setBorder(Border border) { super.setBorder(border); _dirty = true; } /** * Moves and resizes this component. The new location of the top-left * corner is specified by x and y, and the new size is specified by * width and height. * * @param x The new x-coordinate of this component * @param y The new y-coordinate of this component * @param width The new width of this component * @param height The new height of this component */ @Override public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); _dirty = true; } /** * Moves and resizes this component to conform to the new bounding * rectangle r. This component's new position is specified by r.x and * r.y, and its new size is specified by r.width and r.height * * @param r The new bounding rectangle for this component */ @Override public void setBounds(Rectangle r) { setBounds(r.x, r.y, r.width, r.height); } /** * Sets the language-sensitive orientation that is to be used to order * the elements or text within this component. Language-sensitive * LayoutManager and Component subclasses will use this property to * determine how to lay out and draw components. * <p> * At construction time, a component's orientation is set to * ComponentOrientation.UNKNOWN, indicating that it has not been * specified explicitly. The UNKNOWN orientation behaves the same as * ComponentOrientation.LEFT_TO_RIGHT. * * @param o The component orientation. */ @Override public void setComponentOrientation(ComponentOrientation o) { super.setComponentOrientation(o); _ltr = o.isLeftToRight(); calculateStartPosition(); calculateDirtyRectForSelection(); } /** * Sets the font of this component. * * @param font The font to become this component's font; if this parameter * is null then this component will inherit the font of its parent. */ @Override public void setFont(Font font) { super.setFont(font); _dirty = true; } /** * {@inheritDoc} */ @Override public void removeNotify() { _todayTimer.stop(); super.removeNotify(); } /** * {@inheritDoc} */ @Override public void addNotify() { super.addNotify(); // Setup timer to update the value of _today. int secondsTillTomorrow = 86400; if (_todayTimer == null) { _todayTimer = new Timer(secondsTillTomorrow * 1000, new ActionListener() { public void actionPerformed(ActionEvent e) { updateToday(); } }); } // Modify the initial delay by the current time. _cal.setTimeInMillis(System.currentTimeMillis()); secondsTillTomorrow = secondsTillTomorrow - (_cal.get(Calendar.HOUR_OF_DAY) * 3600) - (_cal.get(Calendar.MINUTE) * 60) - _cal.get(Calendar.SECOND); _todayTimer.setInitialDelay(secondsTillTomorrow * 1000); _todayTimer.start(); // Restore calendar _cal.setTimeInMillis(_firstDisplayedDate); } /** * {@inheritDoc} */ @Override protected void paintComponent(Graphics g) { Object oldAAValue = null; Graphics2D g2 = (g instanceof Graphics2D) ? (Graphics2D)g : null; if (g2 != null && _antiAlias) { oldAAValue = g2.getRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } Rectangle clip = g.getClipBounds(); updateIfNecessary(); if (isOpaque()) { g.setColor(getBackground()); g.fillRect(clip.x, clip.y, clip.width, clip.height); } g.setColor(getForeground()); Color shadowColor = g.getColor(); shadowColor = new Color(shadowColor.getRed(), shadowColor.getGreen(), shadowColor.getBlue(), (int)(.20 * 255)); FontMetrics fm = g.getFontMetrics(); // Reset the calendar. _cal.setTimeInMillis(_firstDisplayedDate); // Center the calendars vertically in the available space. int y = _startY; for (int row = 0; row < _numCalRows; row++) { // Center the calendars horizontally in the available space. int x = _startX; int tmpX, tmpY; // Check if this row falls in the clip region. _bounds.x = 0; _bounds.y = _startY + row * (_calendarHeight + CALENDAR_SPACING); _bounds.width = getWidth(); _bounds.height = _calendarHeight; if (!_bounds.intersects(clip)) { _cal.add(Calendar.MONTH, _numCalCols); y += _calendarHeight + CALENDAR_SPACING; continue; } for (int column = 0; column < _numCalCols; column++) { String monthName = _monthsOfTheYear[_cal.get(Calendar.MONTH)]; monthName = monthName + " " + _cal.get(Calendar.YEAR); _bounds.x = (_ltr ? x : x - _calendarWidth);// + 4; //4px of padding on the left _bounds.y = y + _boxPaddingY;// + 4; //4px of padding on the top _bounds.width = _calendarWidth;// - 8; //4px of padding on both sides _bounds.height = _monthBoxHeight; //4px of padding on top if (_bounds.intersects(clip)) { // Paint month name background. paintMonthStringBackground(g, _bounds.x, _bounds.y, _bounds.width, _bounds.height); // Paint arrow buttons for traversing months if enabled. if (_traversable) { tmpX = _bounds.x + _arrowPaddingX; tmpY = _bounds.y + (_bounds.height - _monthDownImage.getIconHeight()) / 2; g.drawImage(_monthDownImage.getImage(), tmpX, tmpY, null); tmpX = _bounds.x + _bounds.width - _arrowPaddingX - _monthUpImage.getIconWidth(); g.drawImage(_monthUpImage.getImage(), tmpX, tmpY, null); } // Paint month name. Font oldFont = getFont(); FontMetrics oldFM = fm; g.setFont(_derivedFont); fm = getFontMetrics(_derivedFont); g.setColor(_monthStringForeground); tmpX = _ltr ? x + (_calendarWidth / 2) - (fm.stringWidth(monthName) / 2) : x - (_calendarWidth / 2) - (fm.stringWidth(monthName) / 2) - 1; tmpY = _bounds.y + ((_monthBoxHeight - _boxHeight) / 2) + fm.getAscent(); if ((_dropShadowMask & MONTH_DROP_SHADOW) != 0) { g.setColor(shadowColor); g.drawString(monthName, tmpX + 1, tmpY + 1); g.setColor(_monthStringForeground); } g.drawString(monthName, tmpX, tmpY); g.setFont(oldFont); fm = oldFM; } g.setColor(getDaysOfTheWeekForeground()); _bounds.x = _ltr ? x : x - _calendarWidth; _bounds.y = y + _boxPaddingY + _monthBoxHeight + _boxPaddingY + _boxPaddingY; _bounds.width = _calendarWidth; _bounds.height = _boxHeight; if (_bounds.intersects(clip)) { _cal.set(Calendar.DAY_OF_MONTH, _cal.getActualMinimum(Calendar.DAY_OF_MONTH)); // Paint short representation of day of the week. int dayIndex = _firstDayOfWeek - 1; Font oldFont = g.getFont(); FontMetrics oldFM = fm; g.setFont(_derivedFont); fm = getFontMetrics(_derivedFont); for (int i = 0; i < DAYS_IN_WEEK; i++) { tmpX = _ltr ? x + (i * (_boxPaddingX + _boxWidth + _boxPaddingX)) + _boxPaddingX + (_boxWidth / 2) - (fm.stringWidth(_daysOfTheWeek[dayIndex]) / 2) : x - (i * (_boxPaddingX + _boxWidth + _boxPaddingX)) - _boxPaddingX - (_boxWidth / 2) - (fm.stringWidth(_daysOfTheWeek[dayIndex]) / 2); tmpY = _bounds.y + fm.getAscent();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -