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