import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
* 时间选择器
* @author tang
* @since 2014/7/18
@SuppressWarnings("serial")
public class DateChooser extends JPanel {
public static void main(String[] args) {
final JFrame frame = new JFrame("时间选择器");
frame.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
final JTextField textField = new JTextField(10);
frame.add(textField);
final JButton buttonLeft = new JButton("选择日期(弹出的对话框以此按钮左对齐)");
buttonLeft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Dimension dialogSize = new Dimension(400, 250);
Point screen = buttonLeft.getLocationOnScreen();
Point point = new Point(screen.x, screen.y + buttonLeft.getPreferredSize().height + 5);
DateChooser dateChooser = new DateChooser();
String selectedDate = dateChooser.showDateDialog(frame, point, dialogSize);
if (dateChooser.isConfirm()) {
textField.setText(selectedDate);
frame.add(buttonLeft);
final JButton buttonRight = new JButton("选择日期(弹出的对话框以此按钮右对齐)");
buttonRight.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Dimension dialogSize = new Dimension(400, 250);
int x = dialogSize.width - buttonRight.getPreferredSize().width;
Point screen = buttonRight.getLocationOnScreen();
Point point = new Point(screen.x - x, screen.y + buttonRight.getPreferredSize().height + 5);
DateChooser dateChooser = new DateChooser();
String selectedDate = dateChooser.showDateDialog(frame, point, dialogSize);
if (dateChooser.isConfirm()) {
textField.setText(selectedDate);
frame.add(buttonRight);
frame.setVisible(true);
protected final int startYear;
protected final int lastYear;
protected final String[] weekStrings = { "日", "一", "二", "三", "四", "五", "六" };
protected Color selectedColor = new Color(250, 100, 100);
protected Color northColor = Color.decode("#f6f6f6"); // 控制条底色
protected Color labelColor = new Color(55, 80, 80); // 年/月标签文字色
protected Font labelFont = new Font("微软雅黑", Font.PLAIN, 14); // 年/月标签字体
protected Color weekLabelColor = new Color(150, 50, 150); // 星期标签文字色
protected Color weekendFontColor = new Color(100, 200, 100); // 周末文字色
protected Color dateFontColor = Color.BLACK; // 日期文字色
protected JDialog dialog;
protected JSpinner yearSpinner;
protected JSpinner monthSpinner;
protected JButton[][] dayButtons = new JButton[6][7];
protected ButtonGroup buttonGroup = new ButtonGroup();
protected DateFormat format;
protected Date date;
protected String selectedDay;
protected boolean isConfirm;
public DateChooser() {
this(new SimpleDateFormat("yyyy-MM-dd"));
public DateChooser(DateFormat format) {
this(format, new Date());
public DateChooser(DateFormat format, Date date) {
this(format, date, 1980, 2080);
public DateChooser(DateFormat format, Date date, int startYear, int lastYear) {
this.date = date;
this.format = format;
this.startYear = startYear;
this.lastYear = lastYear;
selectedDay = getCalendar().get(Calendar.DAY_OF_MONTH) + "";
setLayout(new BorderLayout());
setBackground(Color.WHITE);
JPanel northPanel = createNorthPanal();
northPanel.setPreferredSize(new Dimension(0, 40));
add(northPanel, BorderLayout.NORTH);
JPanel centerPanel = createCenterPanal();
add(centerPanel, BorderLayout.CENTER);
JPanel southPanel = createSouthPanel();
southPanel.setPreferredSize(new Dimension(0, 40));
add(southPanel, java.awt.BorderLayout.SOUTH);
private JPanel createNorthPanal() {
Calendar c = getCalendar();
int currentYear = c.get(Calendar.YEAR);
int currentMonth = c.get(Calendar.MONTH) + 1;
JPanel northPanel = new JPanel();
northPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 8));
northPanel.setBackground(northColor);
yearSpinner = new JSpinner(new SpinnerNumberModel(currentYear, startYear, lastYear, 1));
yearSpinner.setEditor(new JSpinner.NumberEditor(yearSpinner, "####"));
yearSpinner.setPreferredSize(new Dimension(60, 25));
yearSpinner.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
updateDate(Calendar.YEAR, (Integer) yearSpinner.getValue());
northPanel.add(yearSpinner);
JLabel yearLabel = new JLabel("年");
yearLabel.setForeground(labelColor);
yearLabel.setFont(labelFont);
northPanel.add(yearLabel);
northPanel.add(Box.createHorizontalStrut(15));
monthSpinner = new JSpinner(new SpinnerNumberModel(currentMonth, 1, 12, 1));
monthSpinner.setEditor(new JSpinner.NumberEditor(monthSpinner, "##"));
monthSpinner.setPreferredSize(new Dimension(60, 25));
monthSpinner.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
updateDate(Calendar.MONTH, (Integer) monthSpinner.getValue() - 1);
northPanel.add(monthSpinner);
JLabel monthLabel = new JLabel("月");
monthLabel.setForeground(labelColor);
monthLabel.setFont(labelFont);
northPanel.add(monthLabel);
return northPanel;
private JPanel createCenterPanal() {
JPanel centerPanel = new JPanel();
// 设置固定字体,以免调用环境改变影响界面美观
centerPanel.setFont(new Font("微软雅黑", Font.PLAIN, 13));
centerPanel.setLayout(new GridLayout(7, 7));
centerPanel.setBackground(Color.WHITE);
for (int i = 0; i < 7; i++) {
RolloverBackgroundButton cell = new RolloverBackgroundButton(weekStrings[i]);
cell.clearDefaultAttribute();
cell.setHorizontalAlignment(JLabel.RIGHT);
cell.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
cell.setNormalForeground(weekLabelColor);
centerPanel.add(cell);
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
final RolloverBackgroundButton numberButton = new RolloverBackgroundButton("");
numberButton.clearDefaultAttribute();
numberButton.setHorizontalAlignment(SwingConstants.RIGHT);
numberButton.setNormalForeground(dateFontColor);
numberButton.setSelectedForeground(selectedColor);
numberButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (numberButton.getText().length() == 0) {
return;
selectedDay = numberButton.getText();
updateDate(Calendar.DAY_OF_MONTH, Integer.parseInt(numberButton.getText()));
ComponentTool.clearButtonGroupSelected(buttonGroup);
numberButton.setSelected(true);
ComponentTool.updateButtonSelectedForeground(buttonGroup, selectedColor);
if (j == 0 || j == 6) {
numberButton.setNormalForeground(weekendFontColor);
} else {
numberButton.setNormalForeground(dateFontColor);
dayButtons[i][j] = numberButton;
centerPanel.add(numberButton);
buttonGroup.add(numberButton);
return centerPanel;
private JPanel createSouthPanel() {
JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 2));
southPanel.setOpaque(false);
JButton todayButton = new RolloverBackgroundButton("今天");
todayButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
today();
southPanel.add(todayButton);
JButton cancelButton = new RolloverBackgroundButton("取消");
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cancel();
southPanel.add(cancelButton);
JButton confirmButton = new RolloverBackgroundButton("确定");
confirmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
confirm();
southPanel.add(confirmButton);
return southPanel;
* 显示日期选择对话框
* @param owner
* @return
public String showDateDialog(Window owner) {
return showDateDialog(owner, null);
public String showDateDialog(Window owner, Point dialogPoint) {
return showDateDialog(owner, dialogPoint, new Dimension(400, 250));
* 显示日期选择对话框
* @param owner
* @param dialogPoint
* @return
public String showDateDialog(Window owner, Point dialogPoint, Dimension size) {
if (dialog == null) {
dialog = createDialog(owner, size);
dialog.setLocationRelativeTo(owner);
if (dialogPoint != null) {
dialog.setLocation(dialogPoint);
updateDayButtonsText();
dialog.setVisible(true);
return getDateText();
protected JDialog createDialog(Window owner, Dimension size) {
JDialog dialog = new JDialog(owner, "日期时间选择") {
public void setVisible(boolean b) {
if (b) {// 此处先if还是先super顺序很重要
isConfirm = false;
super.setVisible(b);
dialog.setModal(true);
dialog.setSize(size);
dialog.setContentPane(this);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
cancel();
return dialog;
* 用户点击取消
protected void cancel() {
isConfirm = false;
dialog.setVisible(false);
* 用户点击今天
protected void today() {
date = new Date();
Calendar c = getCalendar();
yearSpinner.setValue(c.get(Calendar.YEAR));
monthSpinner.setValue(c.get(Calendar.MONTH) + 1);
selectedDay = c.get(Calendar.DAY_OF_MONTH) + "";
setDate(c.getTime());
updateDayButtonsText();
* 用户点击确定
protected void confirm() {
isConfirm = true;
dialog.setVisible(false);
protected void updateDate(int type, int value) {
Calendar c = getCalendar();
if (type == Calendar.MONTH) {// 处理选择的天数超出月份最大的天数情况
int day = c.get(Calendar.DAY_OF_MONTH);
c.set(Calendar.DAY_OF_MONTH, 1);
c.set(type, value);
int maxMonth_to = c.getActualMaximum(Calendar.DAY_OF_MONTH);
if (Integer.parseInt(selectedDay) <= maxMonth_to) {// 如果当前月份所选择的天数小于即将更新的月份的最大天数
c.set(Calendar.DAY_OF_MONTH, day);// 还原天数
} else {// 否则
selectedDay = "1";
} else {
c.set(type, value);
setDate(c.getTime());
if (type != Calendar.DAY_OF_MONTH) {
updateDayButtonsText();
protected void updateDayButtonsText() {
Calendar c = getCalendar();
c.set(Calendar.DAY_OF_MONTH, 1);
int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
String s = "";
if (dayNo >= 1 && dayNo <= maxDayNo) {
s = String.valueOf(dayNo);
dayButtons[i][j].setText(s);
if (s.equals(selectedDay)) {
ComponentTool.clearButtonGroupSelected(buttonGroup);
dayButtons[i][j].setSelected(true);
ComponentTool.updateButtonSelectedForeground(buttonGroup, selectedColor);
dayNo++;
public Dimension getDialogSize() {
return dialog.getSize();
protected Calendar getCalendar() {
Calendar result = Calendar.getInstance();
result.setTime(getDate());
return result;
* 用户是否点击确定
* @return
public boolean isConfirm() {
return isConfirm;
* 获取选择的时间字符串
* @return
public String getDateText() {
return format.format(getDate());
* 设置默认的时间
* @param date
public void setDate(Date date) {
this.date = date;
* 获取选择的时间
* @return
public Date getDate() {
return date;
public static class ComponentTool {
public static void updateButtonSelectedForeground(ButtonGroup buttonGroup, Color selectedColor) {
for (Enumeration
enumBtn = buttonGroup.getElements(); enumBtn.hasMoreElements();) {
RolloverBackgroundButton button = (RolloverBackgroundButton) enumBtn.nextElement();
if (!button.isSelected()) {
button.setSelectedForeground(null);
} else {
button.setSelectedForeground(selectedColor);
button.repaint();
public static void clearButtonGroupSelected(ButtonGroup buttonGroup) {
for (Enumeration button = buttonGroup.getElements(); button.hasMoreElements();) {
button.nextElement().setSelected(false);
* 鼠标悬浮和按下以及选中时能切换背景颜色/边框颜色/前景颜色的Button
* @author tang
* @since 2014/8/23
public static class RolloverBackgroundButton extends JButton {
protected Color normalBackground;// 默认无状态时背景颜色,此属性父类中已定义(background)
protected Color pressedBackground;// 鼠标按下时背景颜色
protected Color rolloverBackground;// 鼠标悬浮时背景颜色
protected Color selectedBackground;// 选中时背景颜色
protected Color normalBorderColor;// 默认无状态时边框颜色
protected Color pressedBorderColor;// 鼠标按下时边框颜色
protected Color rolloverBorderColor;// 鼠标悬浮时边框颜色
protected Color selectedBorderColor;// 选中时边框颜色
protected Color normalForeground;// 默认时前景颜色
protected Color pressedForeground;// 鼠标按下时前景颜色
protected Color rolloverForeground;// 鼠标悬浮时前景颜色
protected Color selectedForeground;// 选中时前景颜色
initRolloverButton();
public RolloverBackgroundButton() {
public RolloverBackgroundButton(Icon icon) {
super(icon);
public RolloverBackgroundButton(String text, Icon icon) {
super(text, icon);
public RolloverBackgroundButton(String text) {
super(text);
public RolloverBackgroundButton(Action a) {
super(a);
private void initRolloverButton() {
setRolloverEnabled(true);
setBorderPainted(false);
setContentAreaFilled(false);
setFocusPainted(false);
setFont(new Font(Font.DIALOG, Font.PLAIN, 14));
setNormalBackground(new Color(216, 216, 216));
setPressedBackground(new Color(216, 216, 216, 100));
setNormalBorderColor(new Color(174, 174, 174));
setRolloverBorderColor(new Color(95, 205, 245));
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Paint oldPaint = g2d.getPaint();
if (isSelected() && selectedBackground != null) {// 选中时
g2d.setPaint(selectedBackground);
g2d.fillRect(0, 0, getWidth(), getHeight());// 背景
} else if (getModel().isPressed() && pressedBackground != null) {// 鼠标按下时
g2d.setPaint(pressedBackground);
g2d.fillRect(0, 0, getWidth(), getHeight());// 背景
} else if (getModel().isRollover() && rolloverBackground != null) {// 鼠标悬浮时
g2d.setPaint(rolloverBackground);
g2d.fillRect(0, 0, getWidth(), getHeight());// 背景
} else if (normalBackground != null) {// 默认无状态时
g2d.setPaint(normalBackground);
g2d.fillRect(0, 0, getWidth(), getHeight());// 背景
g2d.setPaint(oldPaint);
if (isSelected() && selectedForeground != null) {// 选中时
setForeground(selectedForeground);
} else if (getModel().isPressed() && pressedForeground != null) {// 鼠标按下时
setForeground(pressedForeground);
} else if (getModel().isRollover() && rolloverForeground != null) {// 鼠标悬浮时
setForeground(rolloverForeground);
} else if (normalForeground != null) {// 默认无状态时
setForeground(normalForeground);
super.paint(g2d);
if (isSelected() && selectedBorderColor != null) {// 选中时
g2d.setPaint(selectedBorderColor);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);// 边框
} else if (getModel().isPressed() && pressedBorderColor != null) {// 鼠标按下时
g2d.setPaint(pressedBorderColor);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);// 边框
} else if (getModel().isRollover() && rolloverBorderColor != null) {// 鼠标悬浮时
g2d.setPaint(rolloverBorderColor);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);// 边框
} else if (normalBorderColor != null) {// 默认无状态时
g2d.setPaint(normalBorderColor);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);// 边框
g2d.setPaint(oldPaint);
* 清空设置的默认属性值:
* setNormalBackground(null);
* setPressedBackground(null);
* setNormalBorderColor(null);
* setRolloverBorderColor(null);
public void clearDefaultAttribute() {
setNormalBackground(null);
setPressedBackground(null);
setNormalBorderColor(null);
setRolloverBorderColor(null);
public Color getNormalBackground() {
return normalBackground;
public void setNormalBackground(Color normalBackground) {
this.normalBackground = normalBackground;
public Color getPressedBackground() {
return pressedBackground;
public void setPressedBackground(Color pressedBackground) {
this.pressedBackground = pressedBackground;
public Color getRolloverBackground() {
return rolloverBackground;
public void setRolloverBackground(Color rolloverBackground) {
this.rolloverBackground = rolloverBackground;
public Color getNormalBorderColor() {
return normalBorderColor;
public void setNormalBorderColor(Color normalBorderColor) {
this.normalBorderColor = normalBorderColor;
public Color getPressedBorderColor() {
return pressedBorderColor;
public void setPressedBorderColor(Color pressedBorderColor) {
this.pressedBorderColor = pressedBorderColor;
public Color getRolloverBorderColor() {
return rolloverBorderColor;
public void setRolloverBorderColor(Color rolloverBorderColor) {
this.rolloverBorderColor = rolloverBorderColor;
public Color getPressedForeground() {
return pressedForeground;
public void setPressedForeground(Color pressedForeground) {
this.pressedForeground = pressedForeground;
public Color getRolloverForeground() {
return rolloverForeground;
public void setRolloverForeground(Color rolloverForeground) {
this.rolloverForeground = rolloverForeground;
public Color getNormalForeground() {
return normalForeground;
public void setNormalForeground(Color normalForeground) {
this.normalForeground = normalForeground;
public Color getSelectedBackground() {
return selectedBackground;
public void setSelectedBackground(Color selectedBackground) {
this.selectedBackground = selectedBackground;
public Color getSelectedBorderColor() {
return selectedBorderColor;
public void setSelectedBorderColor(Color selectedBorderColor) {
this.selectedBorderColor = selectedBorderColor;
public Color getSelectedForeground() {
return selectedForeground;
public void setSelectedForeground(Color selectedForeground) {
this.selectedForeground = selectedForeground;
运行效果图:
可以根据不同需要自行修改各种样式。
直接上代码,非常完整的代码,copy可以直接运行:package component;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Cursor;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Fon
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import
一个视图类: HongYeLingGuDate
一个抽象接口: SelectHYDateAbstract
需要导入的jar包: http://download.csdn.net/detail/male09/9884835
中的 flowlayout_v.jar 文件示例代码:HongYeLingGuDate类import java.awt.Color;
JTextField field = new JTextField ();
DatePicker . datePicker(field);
// DatePicker.datePicker(field, "yyyy-MM-dd");
###例子
####
日期
选择
器
JFrame frame = new JFrame ();
frame . setVisible( true );
frame . setDefaultClose
日常开发过程中将一些频繁操作进行自动化脚本处理,可以做到事半功倍。把时间花费到重要的事情上面。最近进行项目自动化处理,写了一个java
swing
的工具,开发过程中遇到的问题记录如下。
首先介绍下如何将java程序打成可执行的jar
方式1 eclipse ide
方式2 IntelliJ ide
早期用eclipse进行可执行jar打包,最近使用intelJ 打包。这里介绍intelJ...
示例代码段
JLabel dateJLabel = new JLabel("
日期
:");
final DatePicker datePicker1 = DatePickerUtil.getDatePicker();
JButton startDateBtn = new JButton("开始时间");
startDateBtn.addActi
声明:本控件来自互联网,仅可应用于个人项目,不可商用,如您未遵守造成的任何问题请自行承担点击下载 datepicker.jar使用方法
在eclipse中,单击你的项目名,右键–>Build Path–>Add External Archives–>
选择
datepicker.jar
import java.awt.Color;
import java.awt.Dimension;
当
选择
使用JPanel和顶层容
器
的content pane时,需要考虑布局管理。JPanel缺省是初始化一个FlowLayout,而content pane缺省是初始化一个BorderLayout。
下面将分别介绍几种最常用的布局管理
器
:FlowLayout、BorderLayout、BoxLayout、CardLayout、GridLayout和GridBagLayout。
代码演示
...
可以使用JDatePicker库来实现Java
Swing
中的
日期
控件。JDatePicker是一个开源的
日期
选择
器
库,提供了丰富的功能和灵活的配置选项。
首先,您需要下载并导入JDatePicker库。您可以在CSDN或其他开发资源网站上找到该库的下载链接。
接下来,您可以按照以下步骤在您的
Swing
应用程序中使用JDatePicker:
1. 创建一个JDatePicker实例:
JDatePicker datePicker = new JDatePicker();
2. 将JDatePicker添加到您的界面中:
yourContainer.add(datePicker);
3. 获取所选
日期
的值:
Date selectedDate = datePicker.getDate();
4. 添加
日期
更改监听
器
(可选):
datePicker.addDateChangeListener(new DateChangeListener() {
@Override
public void dateChanged(DateChangeEvent event) {
// 处理
日期
变更事件
has been blocked by CORS policy: Response to preflight request doesn‘t pass access control check
53137