📄 swtdaychooser.java
字号:
/*
* SWTDayChooser.java - A day chooser component for SWT
* Author: Mark Bryan Yu
* Modified by: Sergey Prigogin
* swtcalendar.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package net.sf.component.calendar;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;
public class SWTDayChooser extends Composite implements MouseListener, FocusListener, TraverseListener, KeyListener {
/**
* Style constant for making Sundays red.
*/
public static final int RED_SUNDAY = 1 << 24; // == SWT.EMBEDDED
/**
* Style constant for making Saturdays red.
*/
public static final int RED_SATURDAY = 1 << 28; // == SWT.VIRTUAL
//是否使用农历
public static final int CHINESE = 1 << 29;
/**
* Style constant for making weekends red.
*/
public static final int RED_WEEKEND = RED_SATURDAY | RED_SUNDAY;
private Label[] dayTitles;
private DayControl[] days;
private int dayOffset;
private Color activeSelectionBackground;
private Color inactiveSelectionBackground;
private Color activeSelectionForeground;
private Color inactiveSelectionForeground;
private Color otherMonthColor;
private Calendar calendar;
private Calendar today;
private Locale locale;
private List listeners;
private int style;
//自定义的阳历节日
private Map<String,String> gregorianHoliday;
//自定义的阴历节日
private Map<String,String> chineseHoliday;
//中文数字
private static String[] numberGB=new String[]{"","1","2","3","4","5","6","7","8","9","10",
"11","12","13","14","15","16","17","18","19","20",
"21","22","23","24","25","26","27","28","29","30","31"
};
public SWTDayChooser(Composite parent, int style) {
super(parent, style & ~ (RED_WEEKEND | CHINESE));
this.style = style;
listeners = new ArrayList(3);
setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
otherMonthColor = new Color(getDisplay(), 128, 128, 128);
activeSelectionBackground = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
inactiveSelectionBackground = getDisplay().getSystemColor(SWT.COLOR_GRAY);
activeSelectionForeground = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
inactiveSelectionForeground = getForeground();
locale = Locale.getDefault();
GridLayout gridLayout = new GridLayout();
gridLayout.makeColumnsEqualWidth = true;
gridLayout.numColumns = 7;
gridLayout.marginHeight = 0;
gridLayout.marginWidth = 0;
gridLayout.horizontalSpacing = 0;
gridLayout.verticalSpacing = 0;
setLayout(gridLayout);
dayTitles = new Label[7];
for (int i = 0; i < dayTitles.length; i++) {
Label label = new Label(this, SWT.CENTER);
dayTitles[i] = label;
label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
label.addMouseListener(this);
}
{
final Composite spacer = new Composite(this, SWT.NO_FOCUS);
spacer.setBackground(getBackground());
final GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.heightHint = 2;
gridData.horizontalSpan = 7;
spacer.setLayoutData(gridData);
spacer.setLayout(new GridLayout());
spacer.addMouseListener(this);
}
{
final Label label = new Label(this, SWT.HORIZONTAL | SWT.SEPARATOR);
final GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 7;
label.setLayoutData(gridData);
}
days = new DayControl[42];
for (int i = 0; i < days.length; i++) {
DayControl day = new DayControl(this,style & CHINESE);
days[i] = day;
day.setLayoutData(new GridData(GridData.FILL_BOTH));
day.addMouseListener(this);
}
setTabList(new Control[0]);
setFont(parent.getFont());
init();
addMouseListener(this);
addFocusListener(this);
addTraverseListener(this);
addKeyListener(this);
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
otherMonthColor.dispose();
}
});
}
protected void init() {
calendar = Calendar.getInstance(locale);
calendar.setLenient(true);
today = (Calendar) calendar.clone();
int firstDayOfWeek = calendar.getFirstDayOfWeek();
DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale);
String[] dayNames = dateFormatSymbols.getShortWeekdays();
int minLength = Integer.MAX_VALUE;
for (int i = 0; i < dayNames.length; i++) {
int len = dayNames[i].length();
if (len > 0 && len < minLength) {
minLength = len;
}
}
if (minLength > 2) {
for (int i = 0; i < dayNames.length; i++) {
if (dayNames[i].length() > 0) {
//中文反向截取
if(locale.equals(Locale.CHINESE) || locale.equals(Locale.CHINA))
dayNames[i] = dayNames[i].substring(dayNames[i].length()-1);
else
dayNames[i] = dayNames[i].substring(0, 1);
}
}
}
int d = firstDayOfWeek;
for (int i = 0; i < dayTitles.length; i++) {
Label label = dayTitles[i];
label.setText(dayNames[d]);
label.setBackground(getBackground());
if (d == Calendar.SUNDAY && (style & RED_SUNDAY) != 0 || d == Calendar.SATURDAY
&& (style & RED_SATURDAY) != 0) {
label.setForeground(getDisplay().getSystemColor(SWT.COLOR_DARK_RED));
} else {
label.setForeground(getForeground());
}
d++;
if (d > dayTitles.length) {
d -= dayTitles.length;
}
}
drawDays();
}
protected void drawDays() {
calendar.get(Calendar.DAY_OF_YEAR); // Force calendar update
Calendar cal = (Calendar) calendar.clone();
int firstDayOfWeek = cal.getFirstDayOfWeek();
cal.set(Calendar.DAY_OF_MONTH, 1);
dayOffset = firstDayOfWeek - cal.get(Calendar.DAY_OF_WEEK);
if (dayOffset >= 0) {
dayOffset -= 7;
}
cal.add(Calendar.DAY_OF_MONTH, dayOffset);
Color foregroundColor = getForeground();
String datesGB[][]=new String[0][0];
if((style & CHINESE) != 0){
CalendarGB calendarGB = new CalendarGB();
calendarGB.setGregorianHoliday(getGregorianHoliday());
calendarGB.setChineseHoliday(getChineseHoliday());
datesGB=calendarGB.getMonthTableGB(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH)-1,days.length);
}
for (int i = 0; i < days.length; cal.add(Calendar.DAY_OF_MONTH, 1)) {
DayControl dayControl = days[i++];
String dayText = Integer.toString(cal.get(Calendar.DAY_OF_MONTH));
if((style & CHINESE) != 0 )
dayText = numberGB[cal.get(Calendar.DAY_OF_MONTH)]+ "\n"+datesGB[i][0];
dayControl.setText(dayText);
if (isSameDay(cal, today)) {
dayControl.setBorderColor(getDisplay().getSystemColor(SWT.COLOR_BLACK));
} else {
dayControl.setBorderColor(getBackground());
}
if (isSameMonth(cal, calendar)) {
int d = cal.get(Calendar.DAY_OF_WEEK);
if ((d == Calendar.SUNDAY && (style & RED_SUNDAY) != 0 )||
(d == Calendar.SATURDAY && (style & RED_SATURDAY) != 0 ) ||
((style & CHINESE) != 0 && datesGB[i][1].equals("true"))) {
dayControl.setForeground(getDisplay().getSystemColor(SWT.COLOR_DARK_RED));
} else {
dayControl.setForeground(foregroundColor);
}
} else {
dayControl.setForeground(otherMonthColor);
}
if (isSameDay(cal, calendar)) {
dayControl.setBackground(getSelectionBackgroundColor());
dayControl.setForeground(getSelectionForegroundColor());
} else {
dayControl.setBackground(getBackground());
}
}
}
private static boolean isSameDay(Calendar cal1, Calendar cal2) {
return cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR)
&& cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
}
private static boolean isSameMonth(Calendar cal1, Calendar cal2) {
return cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
&& cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
}
public void setMonth(int month) {
calendar.set(Calendar.MONTH, month);
drawDays();
dateChanged();
}
public void setYear(int year) {
calendar.set(Calendar.YEAR, year);
drawDays();
dateChanged();
}
public void setCalendar(Calendar cal) {
calendar = (Calendar) cal.clone();
calendar.setLenient(true);
drawDays();
dateChanged();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
*/
public void mouseDown(MouseEvent event) {
if (event.button == 1) { // Left click
setFocus();
if (event.widget instanceof DayControl) {
int index = findDay(event.widget);
selectDay(index + 1 + dayOffset);
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
*/
public void mouseDoubleClick(MouseEvent event) {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
*/
public void mouseUp(MouseEvent event) {
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -