我使用SwingX JXDatePicker,我无法弄清楚如何提供下一/上一年按钮(因为默认情况下它仅提供下/上一月份按钮)。
此外,似乎SwingX不维护了:我应该使用较新的组件作为日期选择器?
任何帮助/提示将不胜感激。 谢谢,托马斯
更新:
为了澄清这个问题,我添加了一个JXDatePicker截图并以红色下一/上一月份按钮高亮显示。 问题是这样的:如何添加,将带来日历下一个/上一年按钮? 请注意,新的按钮必须是标准部件,因为他们需要通过特定的外观和感觉管理(Insusbtantial在这种情况下)来渲染。
非常感谢
我会建议使用Microba的DatePicker。 这是高度可定制的和你想要做什么。
http://microba.sourceforge.net/
编辑:
好的我明白了。 嗯,我做了一些研究,似乎你正在寻找的功能实际上是不存在的JXDatePicker。
不同的替代方案,我发现是:在JDatePicker http://sourceforge.net/projects/jdatepicker/ 。
主要网站: https://jdatepicker.org/
这仍然支持,似乎有你想要的功能。
我知道这是一个老问题,但我终于找到了答案在这里,约SwingsLab演示克列奥帕特拉的评论。
所述SwingsLab演示提供了如何设置在每个组件的基础自定义日历头的示例,但是这是我实际使用的代码(这是全局的;每个应用程序):
UIManager.put(CalendarHeaderHandler.uiControllerID, SpinningCalendarHeaderHandler.class.getName());
datePicker = new JXDatePicker();
datePicker.getMonthView().setZoomable(true); //this is needed for custom header
这似乎是实验代码(不完全不失),所以在自己的风险。 希望能帮助到你。
这是我几年前放在一起。 你可以修改它以满足您的需求。
你需要这个映像运行主要的测试: 。 只要把它放在同一目录与名称datepicker.gif源。
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Popup;
import javax.swing.PopupFactory;
public class DatePicker extends JPanel {
private static final long serialVersionUID = 1L;
protected boolean controlsOnTop;
protected boolean removeOnDaySelection;
protected Calendar currentDisplayDate;
protected JButton prevMonth;
protected JButton nextMonth;
protected JButton prevYear;
protected JButton nextYear;
protected JTextField textField;
protected List<ActionListener> popupListeners =
new ArrayList<ActionListener>();
protected Popup popup;
protected SimpleDateFormat dayName = new SimpleDateFormat("d");
protected SimpleDateFormat monthName = new SimpleDateFormat("MMMM");
protected String iconFile = "datepicker.gif";
protected String[] weekdayNames =
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
public DatePicker() {
super();
currentDisplayDate = Calendar.getInstance();
controlsOnTop = true;
removeOnDaySelection = true;
createPanel();
}
public DatePicker(Calendar date) {
super();
setDate(date);
controlsOnTop = true;
removeOnDaySelection = true;
createPanel();
}
public DatePicker(int month, int day, int year) {
super();
setDate(month, day, year);
controlsOnTop = true;
removeOnDaySelection = true;
createPanel();
}
public void setDate(String date) {
currentDisplayDate = Calendar.getInstance();
editDate(date);
}
public void setDate(Calendar date) {
currentDisplayDate = date;
createPanel();
validate();
repaint();
}
public void setDate(int month, int day, int year) {
currentDisplayDate = Calendar.getInstance();
currentDisplayDate.set(expandYear(year), month - 1, day);
createPanel();
validate();
repaint();
}
protected int expandYear(int year) {
if (year < 100) { // 2 digit year
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int current2DigitYear = currentYear % 100;
int currentCentury = currentYear / 100 * 100;
// set 2 digit year range +20 / -80 from current year
int high2DigitYear = (current2DigitYear + 20) % 100;
if (year <= high2DigitYear) {
year += currentCentury;
}
else {
year += (currentCentury - 100);
}
}
return year;
}
public void setControlsOnTop(boolean flag) {
controlsOnTop = flag;
createPanel();
validate();
repaint();
}
public void setRemoveOnDaySelection(boolean flag) {
removeOnDaySelection = flag;
}
public Popup getPopup(Container c) {
if (popup == null) {
Point p = c.getLocation();
PopupFactory factory = PopupFactory.getSharedInstance();
popup = factory.getPopup(c, this, p.x, p.y);
}
return popup;
}
public void popupShow(Container c) {
getPopup(c);
popup.show();
}
public void popupHide() {
popup.hide();
}
public Calendar getCalendarDate() {
return currentDisplayDate;
}
public Date getDate() {
return currentDisplayDate.getTime();
}
public String getFormattedDate() {
return Integer.toString(getMonth()) + "/" +
Integer.toString(getDay()) + "/" +
Integer.toString(getYear());
}
public int getMonth() {
return currentDisplayDate.get(Calendar.MONTH) + 1;
}
public int getDay() {
return currentDisplayDate.get(Calendar.DAY_OF_MONTH);
}
public int getYear() {
return currentDisplayDate.get(Calendar.YEAR);
}
public ImageIcon getImage() {
return createImageIcon(iconFile, "Calendar date picker");
}
/*
* Returns an ImageIcon, or null if the path was invalid.
*/
protected ImageIcon createImageIcon(String path, String description) {
URL imgURL = getClass().getResource(path);
String fileName = imgURL.getFile().replace("bin/", "src/");
fileName = fileName.replace("%20", " ").substring(1);
ImageIcon icon = new ImageIcon(fileName, description);
return icon;
}
protected void createPanel() {
removeAll();
setBorder(BorderFactory.createLineBorder(Color.black, 3));
setFocusable(true);
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
if (controlsOnTop) {
add(createControls());
add(createCalendar());
} else {
add(createCalendar());
add(createControls());
}
Dimension d = getPreferredSize();
setPreferredSize(new Dimension(d.width, d.height + 8));
}
protected JPanel createControls() {
JPanel c = new JPanel();
c.setBorder(BorderFactory.createRaisedBevelBorder());
c.setFocusable(true);
c.setLayout(new FlowLayout(FlowLayout.CENTER));
prevYear = new JButton("<<");
c.add(prevYear);
prevYear.setMargin(new Insets(0,0,0,0));
prevYear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
addYear(-1);
}
});
prevMonth = new JButton("<");
c.add(prevMonth);
prevMonth.setMargin(new Insets(0,0,0,0));
prevMonth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
addMonth(-1);
}
});
textField = new JTextField(getFormattedDate(), 10);
c.add(textField);
textField.setEditable(true);
textField.setEnabled(true);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
editDate(textField.getText());
}
});
nextMonth = new JButton(">");
c.add(nextMonth);
nextMonth.setMargin(new Insets(0,0,0,0));
nextMonth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
addMonth(+1);
}
});
nextYear = new JButton(">>");
c.add(nextYear);
nextYear.setMargin(new Insets(0,0,0,0));
nextYear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
addYear(+1);
}
});
return c;
}
protected JPanel createCalendar() {
JPanel x = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
x.setFocusable(true);
x.setLayout(gridbag);
String month = monthName.format(currentDisplayDate.getTime());
String year = Integer.toString(getYear());
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 7;
c.gridheight = 1;
JLabel title = new JLabel(month + " " + year);
x.add(title, c);
Font font = title.getFont();
// Font titleFont = new Font(font.getName(), font.getStyle(),
// font.getSize() + 2);
Font weekFont = new Font(font.getName(), font.getStyle(),
font.getSize() - 2);
title.setFont(font);
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
for (c.gridx = 0; c.gridx < 7; c.gridx++) {
JLabel label = new JLabel(weekdayNames[c.gridx]);
x.add(label, c);
label.setFont(weekFont);
}
Calendar draw = (Calendar) currentDisplayDate.clone();
draw.set(Calendar.DATE, 1);
draw.add(Calendar.DATE, -draw.get(Calendar.DAY_OF_WEEK) + 1);
int monthInt = currentDisplayDate.get(Calendar.MONTH);
// monthInt = 0;
// System.out.println("Current month: " + monthInt);
c.gridwidth = 1;
c.gridheight = 1;
int width = getFontMetrics(weekFont).stringWidth(" Wed ");
int width1 = getFontMetrics(weekFont).stringWidth("Wed");
int height = getFontMetrics(weekFont).getHeight() +
(width - width1);
for (c.gridy = 2; c.gridy < 8; c.gridy++) {
for (c.gridx = 0; c.gridx < 7; c.gridx++) {
JButton dayButton;
// System.out.print("Draw month: " + draw.get(Calendar.MONTH));
if (draw.get(Calendar.MONTH) == monthInt) {
String dayString = dayName.format(draw.getTime());
if (draw.get(Calendar.DAY_OF_MONTH) < 10)
dayString = " " + dayString;
dayButton = new JButton(dayString);
} else {
dayButton = new JButton();
dayButton.setEnabled(false);
}
// System.out.println(", day: " + dayName.format(draw.getTime()));
x.add(dayButton, c);
Color color = dayButton.getBackground();
if ((draw.get(Calendar.DAY_OF_MONTH) == getDay()) &&
(draw.get(Calendar.MONTH) == monthInt)) {
dayButton.setBackground(Color.yellow);
// dayButton.setFocusPainted(true);
// dayButton.setSelected(true);
} else
dayButton.setBackground(color);
dayButton.setFont(weekFont);
dayButton.setFocusable(true);
dayButton.setPreferredSize(new Dimension(width, height));
dayButton.setMargin(new Insets(0,0,0,0));
dayButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
changeDay(e.getActionCommand());
}
});
draw.add(Calendar.DATE, +1);
}
// if (draw.get(Calendar.MONTH) != monthInt) break;
}
return x;
}
public void addMonth(int month) {
currentDisplayDate.add(Calendar.MONTH, month);
createPanel();
validate();
repaint();
}
public void addYear(int year) {
currentDisplayDate.add(Calendar.YEAR, year);
createPanel();
validate();
repaint();
}
public void editDate(String date) {
parseDate(date);
createPanel();
validate();
repaint();
}
protected void parseDate(String date) {
String[] parts = date.split("/");
if (parts.length == 3) {
currentDisplayDate.set(Calendar.MONTH,
Integer.valueOf(parts[0]) - 1);
currentDisplayDate.set(Calendar.DAY_OF_MONTH,
Integer.valueOf(parts[1]));
currentDisplayDate.set(Calendar.YEAR,
expandYear(Integer.valueOf(parts[2])));
} else if (parts.length == 2) {
currentDisplayDate = Calendar.getInstance();
currentDisplayDate.set(Calendar.MONTH,
Integer.valueOf(parts[0]) - 1);
currentDisplayDate.set(Calendar.DAY_OF_MONTH,
Integer.valueOf(parts[1]));
} else {
// invalid date
currentDisplayDate = Calendar.getInstance();
}
}
public void changeDay(String day) {
currentDisplayDate.set(Calendar.DAY_OF_MONTH,
Integer.valueOf(day.trim()));
if (removeOnDaySelection) {
firePopupEvent(new ActionEvent(this, 1, "hide"));
popup = null;
} else {
createPanel();
validate();
repaint();
}
}
public void addPopupListener(ActionListener l) {
popupListeners.add(l);
}
public void removePopupListener(ActionListener l) {
popupListeners.remove(l);
}
public void firePopupEvent(ActionEvent e) {
for (int i = popupListeners.size() - 1; i >= 0; i--) {
ActionListener l = popupListeners.get(i);
l.actionPerformed(e);
}
}
public static void main(String[] args) {
final JFrame frame = new JFrame("Date Picker");
Container pane = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(450, 250));
pane.setLayout(new FlowLayout(FlowLayout.LEFT));
pane.add(new JLabel("Birthdate: "));
final JTextField testDate = new JTextField(10);
pane.add(testDate);
final DatePicker dp = new DatePicker();
ImageIcon ii = dp.getImage();
// System.out.println(ii.getIconWidth());
// System.out.println(ii.getIconHeight());
final JButton datePicker = new JButton(ii);
pane.add(datePicker);
datePicker.setPreferredSize(new Dimension(30, 24));
datePicker.setMargin(new Insets(0,0,0,0));
datePicker.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dp.setDate(testDate.getText());
dp.popupShow(datePicker);
}
});
dp.addPopupListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
testDate.setText(dp.getFormattedDate());
dp.popupHide();
}
});
frame.pack();
frame.setFocusable(true);
frame.setResizable(true);
frame.setVisible(true);
}
}
改进:
该dateTimePicker的是太远的按钮,
在行139:
public Popup getPopup(Container c) {
if (popup == null) {
Point p = c.getLocation();
PopupFactory factory = PopupFactory.getSharedInstance();
// FramePrinc.Location.x ==> public static Point Location ; in class FramePrinc
popup = factory.getPopup(c, this, FramePrinc.Location.x,FramePrinc.Location.y);
}
return popup;
}
和行动中你得到的组件的位置
datePicker.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Add this Line and you will get a good result
Location = datePickerButton.getLocationOnScreen();
dp.setDate(testDate.getText());
dp.popupShow(datePicker);
}
});
所以:
- 创建另一个类:例如FramePrinc
- 创建公共静态点位置
- 加你dateTimePiker在面板内部
- 把我的按钮动作里面说行
祝好运
Grine_Amine改进:)
缺乏JXDatePicker内置一个/下一个年度的按钮是主要的原因,我最终没有使用包我的软件。 否则,它是更好的日期选择器就在那里之一。
作为替代方案,我建议LGoodDatePicker。 它有回去和向前上一年按钮,再加上选择任何所需一年的菜单。 公平披露:我对这个项目的主要开发商。 请让我知道,如果它成为你的需求。
LGoodDatePicker主页: https://github.com/LGoodDatePicker/LGoodDatePicker
有一个在释放部分中的工作演示(可执行的JAR文件),以及核心功能的gitub页上的列表。
截图如下。