这是我改写的网上的DateChooser代码后的作品,使用效果如图所示。用法参考备注,以及Main函数中用法。

/**
*
* Copyright: Ares.
* All Rights Reserved.
* Company: Insigma HT/上海创图
* @author Ares <a href="mailto:icerainsoft@hotmail.com>send email</a>
* @date 2013-11-17 16:53
*
* Revision History
*
* Date Programmer Notes
* --------- --------------------- --------------------------------------------
* 2013-11-17 Ares initial
* 2014-09-16 Ares fix bug @n3k123
*
* 1. you can change date format by parameter.
* 2. you can change week label content by showTEXT.
* 3. you can change dayOfWeek order by defaultStartDAY.
*/
package com.swing.test; import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List; import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.PopupFactory;
import javax.swing.SwingUtilities;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener; /**
* @author Ares
* @Describe(Date Chooser class)
*/
public class Chooser extends JPanel{ private static final long serialVersionUID = -5384012731547358720L; private Calendar calendar;
private Calendar now = Calendar.getInstance();
private JPanel calendarPanel;
private java.awt.Font font = new java.awt.Font("Times",java.awt.Font.PLAIN,12);
private java.text.SimpleDateFormat sdf;
private final LabelManager lm = new LabelManager();
private javax.swing.Popup pop;
private TitlePanel titlePanel;
private BodyPanel bodyPanel;
private FooterPanel footerPanel; private JComponent showDate;
private boolean isShow = false;
private static final String DEFAULTFORMAT = "yyyy-MM-dd";
private static final String[] showTEXT = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
private static WeekLabel[] weekLabels = new WeekLabel[7];
private static int defaultStartDAY = 0;//0 is from Sun, 1 is from Mon, 2 is from Tue
private static Color hoverColor = Color.BLUE; // hover color private Chooser(java.util.Date date, String format, int startDAY){
if(startDAY > -1 && startDAY < 7) defaultStartDAY = startDAY;
int dayIndex = defaultStartDAY;
for(int i=0; i<7; i++){
if(dayIndex > 6) dayIndex = 0;
weekLabels[i] = new WeekLabel(dayIndex, showTEXT[dayIndex]);
dayIndex ++ ;
}
sdf = new java.text.SimpleDateFormat(format);
calendar = Calendar.getInstance();
calendar.setTime(date);
initCalendarPanel();
} public static Chooser getInstance(java.util.Date date, String format){
return new Chooser(date, format, defaultStartDAY);
} public static Chooser getInstance(java.util.Date date){
return getInstance(date, DEFAULTFORMAT);
}
public static Chooser getInstance(String format){
return getInstance(new java.util.Date(), format);
}
public static Chooser getInstance(){
return getInstance(new java.util.Date(), DEFAULTFORMAT);
} private void initCalendarPanel(){
calendarPanel = new JPanel(new java.awt.BorderLayout());
calendarPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0xAA, 0xAA, 0xAA)));
calendarPanel.add(titlePanel = new TitlePanel(), java.awt.BorderLayout.NORTH);
calendarPanel.add(bodyPanel = new BodyPanel(), java.awt.BorderLayout.CENTER);
calendarPanel.add(footerPanel = new FooterPanel(),java.awt.BorderLayout.SOUTH);
this.addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent event) { }
public void ancestorRemoved(AncestorEvent event) {hidePanel();}
//hide pop when move component.
public void ancestorMoved(AncestorEvent event) {
hidePanel();
}
});
}
public void register(final JComponent showComponent) {
this.showDate = showComponent;
showComponent.setRequestFocusEnabled(true);
showComponent.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
showComponent.requestFocusInWindow();
}
});
this.add(showComponent, BorderLayout.CENTER);
this.setPreferredSize(new Dimension(90, 25));
this.setBorder(BorderFactory.createLineBorder(Color.GRAY));
showComponent.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
if (showComponent.isEnabled()) {
showComponent.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
}
public void mouseExited(MouseEvent me) {
if (showComponent.isEnabled()) {
showComponent.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
showComponent.setForeground(Color.BLACK);
}
}
public void mousePressed(MouseEvent me) {
if (showComponent.isEnabled()) {
showComponent.setForeground(hoverColor);
if (isShow) {
hidePanel();
} else {
showPanel(showComponent);
}
}
}
public void mouseReleased(MouseEvent me) {
if (showComponent.isEnabled()) {
showComponent.setForeground(Color.BLACK);
}
}
});
showComponent.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
hidePanel();
}
public void focusGained(FocusEvent e) { }
});
}
//hide the main panel.
private void hidePanel() {
if (pop != null) {
isShow = false;
pop.hide();
pop = null;
}
} //show the main panel.
private void showPanel(Component owner) {
if (pop != null) pop.hide();
Point show = new Point(0, showDate.getHeight());
SwingUtilities.convertPointToScreen(show, showDate);
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
int x = show.x;
int y = show.y;
if (x < 0) x = 0;
if (x > size.width - 212) x = size.width - 212;
if (y > size.height - 167) y -= 165;
pop = PopupFactory.getSharedInstance().getPopup(owner, calendarPanel, x, y);
pop.show();
isShow = true;
}
// change text or label's content.
private void commit() {
if (showDate instanceof JTextField) {
((JTextField) showDate).setText(sdf.format(calendar.getTime()));
}else if (showDate instanceof JLabel) {
((JLabel) showDate).setText(sdf.format(calendar.getTime()));
}
hidePanel();
} // control panel
private class TitlePanel extends JPanel { private static final long serialVersionUID = -2865282186037420798L;
private JLabel preYear,preMonth,center,nextMonth,nextYear,centercontainer; public TitlePanel(){
super(new java.awt.BorderLayout());
this.setBackground(new java.awt.Color(190, 200, 200));
initTitlePanel();
}
private void initTitlePanel(){
preYear = new JLabel("<<", JLabel.CENTER);
preMonth = new JLabel("<", JLabel.CENTER);
center = new JLabel("", JLabel.CENTER);
centercontainer = new JLabel("", JLabel.CENTER);
nextMonth = new JLabel(">", JLabel.CENTER);
nextYear = new JLabel(">>", JLabel.CENTER); preYear.setToolTipText("Last Year");
preMonth.setToolTipText("Last Month");
nextMonth.setToolTipText("Next Month");
nextYear.setToolTipText("Next Year"); preYear.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 10, 0, 0));
preMonth.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 15, 0, 0));
nextMonth.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 0, 0, 15));
nextYear.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 0, 0, 10)); centercontainer.setLayout(new java.awt.BorderLayout());
centercontainer.add(preMonth,java.awt.BorderLayout.WEST);
centercontainer.add(center,java.awt.BorderLayout.CENTER);
centercontainer.add(nextMonth,java.awt.BorderLayout.EAST); this.add(preYear,java.awt.BorderLayout.WEST);
this.add(centercontainer,java.awt.BorderLayout.CENTER);
this.add(nextYear,java.awt.BorderLayout.EAST);
this.setPreferredSize(new java.awt.Dimension(210, 25)); updateDate(); preYear.addMouseListener(new MyMouseAdapter(preYear, Calendar.YEAR, -1));
preMonth.addMouseListener(new MyMouseAdapter(preMonth, Calendar.MONTH, -1));
nextMonth.addMouseListener(new MyMouseAdapter(nextMonth, Calendar.MONTH, 1));
nextYear.addMouseListener(new MyMouseAdapter(nextYear, Calendar.YEAR, 1));
} private void updateDate() {
center.setText(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH) + 1));
}
// listener for control label.
class MyMouseAdapter extends java.awt.event.MouseAdapter{ JLabel label;
private int type, value; public MyMouseAdapter(final JLabel label, final int type, final int value){
this.label = label;
this.type = type;
this.value = value;
}
public void mouseEntered(java.awt.event.MouseEvent me) {
label.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
label.setForeground(hoverColor);
}
public void mouseExited(java.awt.event.MouseEvent me) {
label.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
label.setForeground(java.awt.Color.BLACK);
}
public void mousePressed(java.awt.event.MouseEvent me) {
calendar.add(type, value);
label.setForeground(java.awt.Color.WHITE);
refresh();
}
public void mouseReleased(java.awt.event.MouseEvent me) {
label.setForeground(java.awt.Color.BLACK);
}
}
}
// body panel, include week labels and day labels.
private class BodyPanel extends JPanel { private static final long serialVersionUID = 5677718768457235447L; public BodyPanel(){
super(new GridLayout(7, 7));
this.setPreferredSize(new java.awt.Dimension(210, 140));
initMonthPanel();
}
private void initMonthPanel(){
updateDate();
}
public void updateDate() {
this.removeAll();
lm.clear();
java.util.Date temp = calendar.getTime();
Calendar cal = Calendar.getInstance();
cal.setTime(temp);
cal.set(Calendar.DAY_OF_MONTH, 1); int index = cal.get(Calendar.DAY_OF_WEEK);
// 从当月1号前移,一直移动到面板显示的第一天的前一天;当-index + defaultStartDAY为正数时,为避免面板从当月1号之后开始显示,需要前移一周,确保当月显示完全
if(index > defaultStartDAY) cal.add(Calendar.DAY_OF_MONTH, -index + defaultStartDAY);
else cal.add(Calendar.DAY_OF_MONTH, -index + defaultStartDAY - 7); for (WeekLabel weekLabel : weekLabels) {
this.add(weekLabel);
}
for (int i = 0; i < 42; i++) {
cal.add(Calendar.DAY_OF_MONTH, 1);
lm.addLabel(new DayLabel(cal));
}
for (DayLabel my : lm.getLabels()) {
this.add(my);
}
}
} private class FooterPanel extends JPanel { private static final long serialVersionUID = 8135037333899746736L;
private JLabel dateLabel; public FooterPanel(){
super(new BorderLayout());
initFooterPanel();
}
private void initFooterPanel(){
dateLabel = new JLabel("Today is : "+sdf.format(new java.util.Date()));
dateLabel.addMouseListener(new MouseListener() { @Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
calendar.setTime(new Date());
refresh();
commit();
}
@Override
public void mouseExited(MouseEvent e) {
dateLabel.setForeground(Color.BLACK);
}
@Override
public void mouseEntered(MouseEvent e) {
dateLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
dateLabel.setForeground(hoverColor);
}
@Override
public void mouseClicked(MouseEvent e) {}
});
this.add(dateLabel);
}
public void updateDate(){};
}
//refresh all panel
private void refresh() {
titlePanel.updateDate();
bodyPanel.updateDate();
footerPanel.updateDate();
SwingUtilities.updateComponentTreeUI(this);
} private class WeekLabel extends JLabel { private static final long serialVersionUID = -8053965084432740110L;
private String name; public WeekLabel(int index, String name){
super(name, JLabel.CENTER);
this.name = name;
}
public String toString(){
return name;
}
} private class DayLabel extends JLabel implements java.util.Comparator<DayLabel>, java.awt.event.MouseListener, java.awt.event.MouseMotionListener { private static final long serialVersionUID = -6002103678554799020L;
private boolean isSelected;
private int year, month, day; public DayLabel(Calendar cal){
super(""+cal.get(Calendar.DAY_OF_MONTH), JLabel.CENTER);
this.year = cal.get(Calendar.YEAR);
this.month = cal.get(Calendar.MONTH);
this.day = cal.get(Calendar.DAY_OF_MONTH); this.setFont(font);
this.addMouseListener(this);
this.addMouseMotionListener(this);
if(month == calendar.get(Calendar.MONTH)) this.setForeground(java.awt.Color.BLACK);
else this.setForeground(java.awt.Color.LIGHT_GRAY); }
public boolean getIsSelected() {
return isSelected;
}
public void setSelected(boolean b, boolean isDrag) {
isSelected = b;
if (b && !isDrag) {
int temp = calendar.get(Calendar.MONTH);
calendar.set(year, month, day);
if (temp == month) {
SwingUtilities.updateComponentTreeUI(bodyPanel);
} else {
refresh();
}
this.repaint();
}
} @Override
protected void paintComponent(Graphics g) {
//set curr select day's background
if(day == calendar.get(Calendar.DAY_OF_MONTH) && month == calendar.get(Calendar.MONTH)){
g.setColor(new java.awt.Color(0xBB, 0xBF, 0xDA));
g.fillRect(0, 0, getWidth(), getHeight());
}
//set current day's border
if(year == now.get(Calendar.YEAR) && month == now.get(Calendar.MONTH) && day == now.get(Calendar.DAY_OF_MONTH)){
Graphics2D gd = (Graphics2D) g;
gd.setColor(new java.awt.Color(0x55, 0x55, 0x88));
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(getWidth() - 1, 0);
p.addPoint(getWidth() - 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}
if (isSelected){
Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 2.0f, 2.0f }, 1.0f);
Graphics2D gd = (Graphics2D) g;
gd.setStroke(s);
gd.setColor(Color.BLACK);
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(getWidth() - 1, 0);
p.addPoint(getWidth() - 1, getHeight() - 1);
p.addPoint(0, getHeight() - 1);
gd.drawPolygon(p);
}
super.paintComponent(g);
}
public boolean contains(Point p) {
return this.getBounds().contains(p);
}
private void update() {
repaint();
}
@Override
public void mouseDragged(MouseEvent e) { }
@Override
public void mouseMoved(MouseEvent e) { }
@Override
public void mouseClicked(MouseEvent e) { } @Override
public void mousePressed(MouseEvent e) {
isSelected = true;
update();
} @Override
public void mouseReleased(MouseEvent e) {
Point p = SwingUtilities.convertPoint(this, e.getPoint(), bodyPanel);
this.setForeground(Color.BLACK);
lm.setSelect(p, false);
commit();
}
@Override // change color when mouse over.
public void mouseEntered(MouseEvent e) {
this.setForeground(hoverColor);
this.repaint();
}
@Override // change color when mouse exit.
public void mouseExited(MouseEvent e) {
if(month == calendar.get(Calendar.MONTH)) this.setForeground(java.awt.Color.BLACK);
else this.setForeground(java.awt.Color.LIGHT_GRAY);
this.repaint();
}
@Override
public int compare(DayLabel o1, DayLabel o2) {
Calendar c1 = Calendar.getInstance();
c1.set(o1.year, o1.month, o1.day);
Calendar c2 = Calendar.getInstance();
c2.set(o2.year, o2.month, o2.day);
return c1.compareTo(c2);
} } private class LabelManager {
private List<DayLabel> list; public LabelManager(){
list = new ArrayList<Chooser.DayLabel>();
} public List<DayLabel> getLabels(){
return list;
}
public void addLabel(DayLabel label){
list.add(label);
}
public void clear() {
list.clear();
}
public void setSelect(Point p, boolean b) {
//如果是拖动,则要优化一下,以提高效率
if (b) {
//表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和
//将要显示的标签找到了就可以了
boolean findPrevious = false, findNext = false;
for (DayLabel lab : list) {
if (lab.contains(p)) {
findNext = true;
if (lab.getIsSelected()) findPrevious = true;
else lab.setSelected(true, b);
} else if (lab.getIsSelected()) {
findPrevious = true;
lab.setSelected(false, b);
}
if (findPrevious && findNext) return;
}
}else {
DayLabel temp = null;
for (DayLabel m : list) {
if (m.contains(p)) {
temp = m;
} else if (m.getIsSelected()) {
m.setSelected(false, b);
}
}
if (temp != null) temp.setSelected(true, b);
}
}
} /**
* @param args
*/
public static void main(String[] args) {
JFrame jf = new JFrame("Date Picker Test");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(null);
jf.setBounds(400, 200, 600, 400); Chooser ser = Chooser.getInstance();
javax.swing.JTextField text = new JTextField();
text.setBounds(10, 10, 200, 30);
text.setText("2013-10-11");
ser.register(text); Chooser ser2 = Chooser.getInstance("yyyy年MM月dd日");
JLabel label = new JLabel("please click me.");
label.setBounds(10, 50, 200, 30);
ser2.register(label); jf.add(text);
jf.add(label);
jf.setVisible(true);
}
}

Java Swing 日历 控件的更多相关文章

  1. Java Swing 日期控件(转载)

    http://www.cnblogs.com/lzy1991/p/5714935.html

  2. 【转】【WebDriver】不可编辑域和日历控件域的输入 javascript

    http://blog.csdn.net/fudax/article/details/8089404 今天用到日历控件,用第一个javascript执行后页面上的日期控件后,在html中可以看到生效日 ...

  3. Selenium2+python自动化25-js处理日历控件(修改readonly属性)

    前言 日历控件是web网站上经常会遇到的一个场景,有些输入框是可以直接输入日期的,有些不能,以我们经常抢票的12306网站为例,详细讲解如何解决日历控件为readonly属性的问题. 基本思路:先用j ...

  4. android日历控件(一)

    自定义日历并且具备设置今天以前的时间不可点选,以前的颜色和当前的颜色不同,以及获取两次点击日期之间间隔的天数所以说细节比较多 个人习惯,先上图 靠,笔记本不知道怎么回事,禁用到触摸板之后 再次唤醒屏幕 ...

  5. 推荐一款JavaScript日历控件:kimsoft-jscalendar

    一.什么是 kimsoft-jscalendar     一个简洁的avaScript日历控件,可在Java Web项目,.NET Web 项目中使用 二.kimsoft-jscalendar 有什么 ...

  6. My97DatePicker日历控件日报、每周和每月的选择

    My97DatePicker日历控件日报.每周和每月的选择 1.设计源代码 <%@ page language="java" import="java.util.* ...

  7. Android自己定义组件之日历控件-精美日历实现(内容、样式可扩展)

    需求 我们知道.Android系统本身有自带的日历控件,网络上也有非常多开源的日历控件资源.可是这些日历控件往往样式较单一.API较多.不易于在实际项目中扩展并实现出符合详细样式风格的,内容可定制的效 ...

  8. Android 一个日历控件的实现代码

    转载  2017-05-19   作者:Othershe   我要评论 本篇文章主要介绍了Android 一个日历控件的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看 ...

  9. 简洁js日历控件的使用

    往Web工程添加纯js日历控件 在网上找到了DatePicker.js(http://www.cnblogs.com/shenyixin/archive/2013/03/11/2954156.html ...

随机推荐

  1. [CentOS] CentOS for vsftpd with MySQL Virtual user

    從ubuntu 12.04的安裝手法拿到CentOS來真的有些很大的不同 絕大部分的語法.概念都是差不多的,只是指令上有些差別,跟ubuntu 有不一樣的地方特別拿出來另外說明 要讓vsftpd與my ...

  2. Atitit.编程语言的主要的种类and趋势 逻辑式语言..函数式语言...命令式语言

    Atitit.编程语言的主要的种类and趋势 逻辑式语言..函数式语言...命令式语言 1. 编程语言的主要的种类 逻辑式语言..函数式语言...命令式语言 1 2. 逻辑式语言,,不必考虑实现过程而 ...

  3. 如何使用VIM的列编辑模式 [转]

    如何使用VIM的列编辑模式? * windows 我使用的VIM FOR WINDOWS,一直都听说VIM有列编辑模式,一直没有使用过,试了几次都失败了.今天又因为工作需要,到网上查了一下,经过不断的 ...

  4. [svc]raid基础知识-冷知识

    参阅:磁盘接口与RAID Dell 服务器做Raid 1,raid形象理解(饮水机模型) http://dingyichao.blog.51cto.com/442449/698762 2,raid利用 ...

  5. 进程控制函数(2)-setpgid() 修改当前进程的进程组ID

    定义:int setpgid(pid_t pid,pid_t pgid); 表头文件:#include<unistd.h> 说明:setpgid()将参数pid 指定进程所属的组识别码设为 ...

  6. Overflow sort stage buffered data usage of 33554495 bytes exceeds internal limit of 33554432 bytes

    MongoDB执行错误: Overflow sort stage buffered data usage of 33554495 bytes exceeds internal limit of 335 ...

  7. Swift 3.1 的一些新特性

    Swift 3.1 的一些新特性   推荐序 本文来自泊学的投稿,介绍了 Swift 3.1 的新特性,感谢泊学授权发表.以下为文章正文. 正文 Apple 终于发布了Xcode 8.3以及Swift ...

  8. vue的路由使用

    1). 安装 vue-router npm install vue-router --save 2). 新建路由配置 安装成功后,在 src 新建 router 文件夹,然后新建 index.js 文 ...

  9. 从constructor中抛出exception后,constructor会返回null吗?

    刚才琢磨这个问题主要是在想,如果constructor抛出了exception,那么返回的object是什么一个情况呢?如果我这个object中有一些关键的资源没有初始化,比如说Database co ...

  10. 折腾kali linux2.0

    偶然的机会了解到了kali linux这个用于渗透测试的linux发行版,于是就从官网下了iso,但是制作启动盘老出错.网上查了下说在linux下用dd命令特别简单,于是转到ubuntu下制作启动盘, ...