Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// The MIT License (MIT)
//
// Copyright (c) 2017 Timothy D. Jones
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package io.github.jonestimd.swing.component;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import io.github.jonestimd.swing.ComponentResources;
/**
* A panel that displays a calendar for selecting a date. The calendar shows a single month and indicates the current
* date and the currently selected date. The panel also includes controls for selecting the month and year to display
* in the calendar. Property change events are fired when the selected date changes.
*/
public class CalendarPanel extends Box {
private static final String SELECTION_COMPLETE = "selectionComplete";
private static final String CANCEL_SELECTION = "cancelSelection";
private static final String NEXT_MONTH = "navigateToNextMonth";
private static final String PREVIOUS_MONTH = "navigateToPreviousMonth";
/** The property name used for change events. */
public static final String DATE_PROPERTY = "date";
private Calendar navigationCalendar = Calendar.getInstance();
private Date selectedDate;
private final Color monthForeground;
private final Color monthBackground;
private final Color adjacentForeground;
private final Color adjacentBackground;
private final Border selectedBorder;
private JLabel yearLabel = createYearLabel();
private JComboBox monthComboBox = createMonthComboBox();
private final Action selectAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
setDate(tableModel.getSelectedDate());
}
};
private final Action cancelAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
setDate(selectedDate);
}
};
private final Action nextMonthAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
navigationCalendar.add(Calendar.MONTH, 1);
updateCalendar();
}
};
private final Action previousMonthAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
navigationCalendar.add(Calendar.MONTH, -1);
updateCalendar();
}
};
private CalendarTableModel tableModel;
private JTable calendarTable;
public CalendarPanel(Date initialValue) {
this(ComponentResources.BUNDLE, initialValue);
}
public CalendarPanel(ResourceBundle bundle, Date initialValue) {
super(BoxLayout.Y_AXIS);
monthForeground = (Color) bundle.getObject("calendarPanel.month.foreground");
monthBackground = (Color) bundle.getObject("calendarPanel.month.background");
adjacentForeground = (Color) bundle.getObject("calendarPanel.month.adjacent.foreground");
adjacentBackground = (Color) bundle.getObject("calendarPanel.month.adjacent.background");
selectedBorder = BorderFactory.createLineBorder((Color) bundle.getObject("calendarPanel.selected.border"));
setBackground(monthBackground);
setOpaque(true);
Box navigationPanel = Box.createHorizontalBox();
add(navigationPanel);
navigationPanel.add(createPreviousNextPanel(bundle, monthComboBox, new MonthHandler(), "calendar.tooltip.month"));
navigationPanel.add(createPreviousNextPanel(bundle, yearLabel, new YearHandler(), "calendar.tooltip.year"));
createTable(bundle);
add(calendarTable.getTableHeader());
add(calendarTable);
setDate(initialValue);
}
/**
* Overridden to set focus to the calendar contained in this panel.
*/
@Override
public void requestFocus() {
super.requestFocus();
calendarTable.requestFocus();
}
private PreviousNextPanel createPreviousNextPanel(ResourceBundle bundle, Component valueComponent,
PreviousNextListener handler, String resourcePrefix) {
PreviousNextPanel previousNextPanel = new PreviousNextPanel(valueComponent,
bundle.getString(resourcePrefix + ".previous"), bundle.getString(resourcePrefix + ".next"));
previousNextPanel.addPreviousNextListener(handler);
return previousNextPanel;
}
private JLabel createYearLabel() {
JLabel label = new JLabel(String.format("%tY", navigationCalendar.getTime()));
label.setBorder(new EmptyBorder(0, 2, 0, 2));
return label;
}
private JComboBox createMonthComboBox() {
String[] months = DateFormatSymbols.getInstance().getMonths();
months = Arrays.copyOfRange(months,
navigationCalendar.getMinimum(Calendar.MONTH), navigationCalendar.getMaximum(Calendar.MONTH)+1);
JComboBox comboBox = new JComboBox<>(months);
comboBox.addItemListener(new MonthChangeListener());
return comboBox;
}
private void createTable(ResourceBundle bundle) {
tableModel = new CalendarTableModel();
calendarTable = new JTable(tableModel);
calendarTable.getTableHeader().setReorderingAllowed(false);
calendarTable.getTableHeader().setResizingAllowed(false);
calendarTable.setCellSelectionEnabled(true);
calendarTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
calendarTable.setDefaultRenderer(Date.class, new CellRenderer());
calendarTable.setToolTipText(bundle.getString("calendar.tooltip"));
calendarTable.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
setDate(tableModel.getSelectedDate());
}
});
ActionMap actionMap = new ActionMap();
actionMap.setParent(calendarTable.getActionMap());
actionMap.put(SELECTION_COMPLETE, selectAction);
actionMap.put(CANCEL_SELECTION, cancelAction);
actionMap.put(NEXT_MONTH, nextMonthAction);
actionMap.put(PREVIOUS_MONTH, previousMonthAction);
calendarTable.setActionMap(actionMap);
InputMap inputMap = new InputMap();
inputMap.setParent(calendarTable.getInputMap());
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), SELECTION_COMPLETE);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), CANCEL_SELECTION);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), NEXT_MONTH);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), PREVIOUS_MONTH);
calendarTable.setInputMap(WHEN_FOCUSED, inputMap);
setPreferredWidth();
}
private void setPreferredWidth() {
int max = 0;
for (int i=0; i Calendar.SATURDAY) j = Calendar.SUNDAY;
}
int rowCount = (Calendar.getInstance().getMaximum(Calendar.DATE) / weekdays.length) + 2;
dates = new Date[rowCount][weekdays.length];
for (int i = 0; i < dates.length; i++) {
dates[i] = new Date[weekdays.length];
}
}
public Class> getColumnClass(int columnIndex) {
return Date.class;
}
public String getColumnName(int column) {
return column < weekdays.length ? weekdays[column] : null;
}
public int getColumnCount() {
return weekdays.length;
}
public int getRowCount() {
return dates.length;
}
public void populateTable() {
calendarTable.clearSelection();
Calendar calendar = (Calendar) navigationCalendar.clone();
calendar.add(Calendar.DATE, -(calendar.get(Calendar.DAY_OF_WEEK) - calendar.getFirstDayOfWeek()));
for (int week = 0; week < dates.length; week++) {
for (int dow = 0; dow < dates[week].length; dow++) {
Date date = calendar.getTime();
dates[week][dow] = date;
if (date.equals(selectedDate)) {
calendarTable.setColumnSelectionInterval(dow, dow);
calendarTable.setRowSelectionInterval(week, week);
}
calendar.add(Calendar.DATE, 1);
}
}
fireTableRowsUpdated(0, dates.length-1);
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex < dates.length && columnIndex < weekdays.length) {
return dates[rowIndex][columnIndex];
}
return null;
}
public Date getSelectedDate() {
if (calendarTable.getSelectedRowCount() == 0 || calendarTable.getSelectedColumnCount() == 0) {
return null;
}
return dates[calendarTable.getSelectedRow()][calendarTable.getSelectedColumn()];
}
}
}