In other languages like VB, C#, in occasions where you want the user to enter a date, say in a text box,we can make a calendar to appear once you click on it. So the user can click on the corresponding date and that date will be put to the text box.
By that way we can get rid of problems that can be caused due to dates in an incorrect format. I need to know how we can achieve this in java?
Actually, I need to combine this with a JTable. there is a column where the date need to be entered. But users may enter dates in various formats. So I thought of going to something like this. Hope there is a way to do this, easily.
Will anyone please show me how to do this. Any help is greatly appreciated..
Thank you.
I wrote a DateTextField component.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JDialog;
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.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class DateTextField extends JTextField {
private static String DEFAULT_DATE_FORMAT = "MM/dd/yyyy";
private static final int DIALOG_WIDTH = 200;
private static final int DIALOG_HEIGHT = 200;
private SimpleDateFormat dateFormat;
private DatePanel datePanel = null;
private JDialog dateDialog = null;
public DateTextField() {
this(new Date());
}
public DateTextField(String dateFormatPattern, Date date) {
this(date);
DEFAULT_DATE_FORMAT = dateFormatPattern;
}
public DateTextField(Date date) {
setDate(date);
setEditable(false);
setCursor(new Cursor(Cursor.HAND_CURSOR));
addListeners();
}
private void addListeners() {
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent paramMouseEvent) {
if (datePanel == null) {
datePanel = new DatePanel();
}
Point point = getLocationOnScreen();
point.y = point.y + 30;
showDateDialog(datePanel, point);
}
});
}
private void showDateDialog(DatePanel dateChooser, Point position) {
Frame owner = (Frame) SwingUtilities
.getWindowAncestor(DateTextField.this);
if (dateDialog == null || dateDialog.getOwner() != owner) {
dateDialog = createDateDialog(owner, dateChooser);
}
dateDialog.setLocation(getAppropriateLocation(owner, position));
dateDialog.setVisible(true);
}
private JDialog createDateDialog(Frame owner, JPanel contentPanel) {
JDialog dialog = new JDialog(owner, "Date Selected", true);
dialog.setUndecorated(true);
dialog.getContentPane().add(contentPanel, BorderLayout.CENTER);
dialog.pack();
dialog.setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
return dialog;
}
private Point getAppropriateLocation(Frame owner, Point position) {
Point result = new Point(position);
Point p = owner.getLocation();
int offsetX = (position.x + DIALOG_WIDTH) - (p.x + owner.getWidth());
int offsetY = (position.y + DIALOG_HEIGHT) - (p.y + owner.getHeight());
if (offsetX > 0) {
result.x -= offsetX;
}
if (offsetY > 0) {
result.y -= offsetY;
}
return result;
}
private SimpleDateFormat getDefaultDateFormat() {
if (dateFormat == null) {
dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
}
return dateFormat;
}
public void setText(Date date) {
setDate(date);
}
public void setDate(Date date) {
super.setText(getDefaultDateFormat().format(date));
}
public Date getDate() {
try {
return getDefaultDateFormat().parse(getText());
} catch (ParseException e) {
return new Date();
}
}
private class DatePanel extends JPanel implements ChangeListener {
int startYear = 1980;
int lastYear = 2050;
Color backGroundColor = Color.gray;
Color palletTableColor = Color.white;
Color todayBackColor = Color.orange;
Color weekFontColor = Color.blue;
Color dateFontColor = Color.black;
Color weekendFontColor = Color.red;
Color controlLineColor = Color.pink;
Color controlTextColor = Color.white;
JSpinner yearSpin;
JSpinner monthSpin;
JButton[][] daysButton = new JButton[6][7];
DatePanel() {
setLayout(new BorderLayout());
setBorder(new LineBorder(backGroundColor, 2));
setBackground(backGroundColor);
JPanel topYearAndMonth = createYearAndMonthPanal();
add(topYearAndMonth, BorderLayout.NORTH);
JPanel centerWeekAndDay = createWeekAndDayPanal();
add(centerWeekAndDay, BorderLayout.CENTER);
reflushWeekAndDay();
}
private JPanel createYearAndMonthPanal() {
Calendar cal = getCalendar();
int currentYear = cal.get(Calendar.YEAR);
int currentMonth = cal.get(Calendar.MONTH) + 1;
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.setBackground(controlLineColor);
yearSpin = new JSpinner(new SpinnerNumberModel(currentYear,
startYear, lastYear, 1));
yearSpin.setPreferredSize(new Dimension(56, 20));
yearSpin.setName("Year");
yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
yearSpin.addChangeListener(this);
panel.add(yearSpin);
JLabel yearLabel = new JLabel("Year");
yearLabel.setForeground(controlTextColor);
panel.add(yearLabel);
monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1,
12, 1));
monthSpin.setPreferredSize(new Dimension(35, 20));
monthSpin.setName("Month");
monthSpin.addChangeListener(this);
panel.add(monthSpin);
JLabel monthLabel = new JLabel("Month");
monthLabel.setForeground(controlTextColor);
panel.add(monthLabel);
return panel;
}
private JPanel createWeekAndDayPanal() {
String colname[] = { "S", "M", "T", "W", "T", "F", "S" };
JPanel panel = new JPanel();
panel.setFont(new Font("Arial", Font.PLAIN, 10));
panel.setLayout(new GridLayout(7, 7));
panel.setBackground(Color.white);
for (int i = 0; i < 7; i++) {
JLabel cell = new JLabel(colname[i]);
cell.setHorizontalAlignment(JLabel.RIGHT);
if (i == 0 || i == 6) {
cell.setForeground(weekendFontColor);
} else {
cell.setForeground(weekFontColor);
}
panel.add(cell);
}
int actionCommandId = 0;
for (int i = 0; i < 6; i++)
for (int j = 0; j < 7; j++) {
JButton numBtn = new JButton();
numBtn.setBorder(null);
numBtn.setHorizontalAlignment(SwingConstants.RIGHT);
numBtn.setActionCommand(String
.valueOf(actionCommandId));
numBtn.setBackground(palletTableColor);
numBtn.setForeground(dateFontColor);
numBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JButton source = (JButton) event.getSource();
if (source.getText().length() == 0) {
return;
}
dayColorUpdate(true);
source.setForeground(todayBackColor);
int newDay = Integer.parseInt(source.getText());
Calendar cal = getCalendar();
cal.set(Calendar.DAY_OF_MONTH, newDay);
setDate(cal.getTime());
dateDialog.setVisible(false);
}
});
if (j == 0 || j == 6)
numBtn.setForeground(weekendFontColor);
else
numBtn.setForeground(dateFontColor);
daysButton[i][j] = numBtn;
panel.add(numBtn);
actionCommandId++;
}
return panel;
}
private Calendar getCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.setTime(getDate());
return calendar;
}
private int getSelectedYear() {
return ((Integer) yearSpin.getValue()).intValue();
}
private int getSelectedMonth() {
return ((Integer) monthSpin.getValue()).intValue();
}
private void dayColorUpdate(boolean isOldDay) {
Calendar cal = getCalendar();
int day = cal.get(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH, 1);
int actionCommandId = day - 2 + cal.get(Calendar.DAY_OF_WEEK);
int i = actionCommandId / 7;
int j = actionCommandId % 7;
if (isOldDay) {
daysButton[i][j].setForeground(dateFontColor);
} else {
daysButton[i][j].setForeground(todayBackColor);
}
}
private void reflushWeekAndDay() {
Calendar cal = getCalendar();
cal.set(Calendar.DAY_OF_MONTH, 1);
int maxDayNo = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int dayNo = 2 - cal.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);
}
daysButton[i][j].setText(s);
dayNo++;
}
}
dayColorUpdate(false);
}
public void stateChanged(ChangeEvent e) {
dayColorUpdate(true);
JSpinner source = (JSpinner) e.getSource();
Calendar cal = getCalendar();
if (source.getName().equals("Year")) {
cal.set(Calendar.YEAR, getSelectedYear());
} else {
cal.set(Calendar.MONTH, getSelectedMonth() - 1);
}
setDate(cal.getTime());
reflushWeekAndDay();
}
}
}
The LGoodDatePicker library includes a (swing) DatePicker component, which allows the user to choose dates from a calendar. (By default, the users can also type dates from the keyboard, but keyboard entry can be disabled if desired). The DatePicker has automatic data validation, which means (among other things) that any date that the user enters will always be converted to your desired date format.
Fair disclosure: I'm the primary developer.
Since the DatePicker is a swing component, you can add it to any other swing container including (in your scenario) the cells of a JTable.
The most commonly used date formats are automatically supported, and additional date formats can be added if desired.
To enforce your desired date format, you would most likely want to set your chosen format to be the default "display format" for the DatePicker. Formats can be specified by using the Java 8 DateTimeFormatter Patterns. No matter what the user types (or clicks), the date will always be converted to the specified format as soon as the user is done.
Besides the DatePicker, the library also has the TimePicker and DateTimePicker components. I pasted screenshots of all the components (and the demo program) below.
The library can be installed into your Java project from the project release page.
The project home page is on Github at:
https://github.com/LGoodDatePicker/LGoodDatePicker .
Another easy method in Netbeans is also avaiable here, There are libraries inside Netbeans itself,where the solutions for this type of situations are available.Select the relevant one as well.It is much easier.After doing the prescribed steps in the link,please restart Netbeans.
Step1:- Select Tools->Palette->Swing/AWT Components
Step2:- Click 'Add from JAR'in Palette Manager
Step3:- Browse to [NETBEANS HOME]\ide\modules\ext and select swingx-0.9.5.jar
Step4:- This will bring up a list of all the components available for the palette. Lots of goodies here! Select JXDatePicker.
Step5:- Select Swing Controls & click finish
Step6:- Restart NetBeans IDE and see the magic :)
Open your Java source code document and navigate to the JTable object you have created inside of your Swing class.
Create a new TableModel object that holds a DatePickerTable. You must create the DatePickerTable with a range of date values in MMDDYYYY format. The first value is the begin date and the last is the end date. In code, this looks like:
TableModel datePicker = new DatePickerTable("01011999","12302000");
Set the display interval in the datePicker object. By default each day is displayed, but you may set a regular interval. To set a 15-day interval between date options, use this code:
datePicker.interval = 15;
Attach your table model into your JTable:
JTable newtable = new JTable (datePicker);
Your Java application now has a drop-down date selection dialog.
Source: Stackoverflow.com