i am trying to get the date from the JDatePicker but my problem is eventhough i selected the date its not displaying in the result textbox.
here is my code
can anyone help to how to solve this problem.
public class Datepicker extends JFrame {Datepicker(){
JFrame frame=new JFrame();
frame.setLayout(new FlowLayout());
UtilDateModel model=new UtilDateModel();
Properties p=new Properties();
p.put("text.today","Today");
p.put("text.month","Month");
p.put("text.year","Year");
JDatePanelImpl panel=new JDatePanelImpl(model, p);
JDatePickerImpl datepic=new JDatePickerImpl(panel,null);
datepic.setBounds(220,350,120,30);
frame.add(datepic);
Date selectedDate=(Date)datepic.getModel().getValue();
frame.setSize(300, 300);
frame.setVisible(true);}
ThankYou.
Please, instead of
JDatePickerImpl datepic=new JDatePickerImpl(panel,null);
do this as follow, it's worked for me :
datePicker = new JDatePickerImpl(datePanel,new DateLabelFormatter());
public class DateLabelFormatter extends AbstractFormatter {
private String datePattern = "yyyy-MM-dd";
private SimpleDateFormat dateFormatter = new SimpleDateFormat(datePattern);
#Override
public Object stringToValue(String text) throws ParseException {
return dateFormatter.parseObject(text);
}
#Override
public String valueToString(Object value) throws ParseException {
if (value != null) {
Calendar cal = (Calendar) value;
return dateFormatter.format(cal.getTime());
}
return "";
}
}
Related
I want to disable all the Sundays on the JDateChooser but I don't know how.
I saw some answers earlier while searching and they're using a range with start and end but in my case it's all the sundays in the jdatechooser. It was for our school project and we're not allowed to drag and drop controls so I declared the datechooser and imported the com.toedter.calendar.JDateChooser;
Below is my code for JDateChooser. I really hope to learn more, thank you.
JDateChooser date = new JDateChooser(new Date());
date.setBounds(120,150,150,30);
sapp1.add(date);
As I mentioned in the comment to the original post, you can obtain JCalendar from JDateChooser and customize it to achieve the desired result.
JDateChooser date = new JDateChooser(new Date());
date.getJCalendar().getDayChooser().addDateEvaluator(new MyDateEvaluator());
You can set a custom IDateEvaluator which allows to makes all Sundays disabled.
#Override
public boolean isInvalid(Date date) {
return date.getDay() == 0;
}
Here is the code that makes all Sundays disabled:
import com.toedter.calendar.IDateEvaluator;
import com.toedter.calendar.JDateChooser;
import javax.swing.*;
import java.awt.*;
import java.util.Date;
public class CustomizedDateChooser {
public static void main(String[] args) {
JFrame f = new JFrame("ComboBox Example");
JDateChooser date = new JDateChooser(new Date());
date.getJCalendar().getDayChooser().addDateEvaluator(new MyDateEvaluator());
date.setBounds(200,200,200,50);
JPanel p = new JPanel();
p.add(new JLabel("Choose a Date:"));
p.add(date);
f.add(p);
f.setLayout(new FlowLayout());
f.setSize(400, 500);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
private static class MyDateEvaluator implements IDateEvaluator {
#Override
public boolean isSpecial(Date date) {
return false;
}
#Override
public Color getSpecialForegroundColor() {
return null;
}
#Override
public Color getSpecialBackroundColor() {
return null;
}
#Override
public String getSpecialTooltip() {
return null;
}
#Override
public boolean isInvalid(Date date) {
return date.getDay() == 0;
}
#Override
public Color getInvalidForegroundColor() {
return null;
}
#Override
public Color getInvalidBackroundColor() {
return null;
}
#Override
public String getInvalidTooltip() {
return null;
}
}
}
I am using a JDateChooser component from an external library toedter(jcalendar1.4). I used a custom DateEvaluator by implementing IDateEvaluator which is later added to JDateChooser component:
public static class HighlightEvaluator implements IDateEvaluator {
private final List<Date> list = new ArrayList<>();
public void add(Date date) {
list.add(date);
}
public void remove(Date date) {
list.remove(date);
}
public void setDates(List<Date> dates) {
list.addAll(dates);
}
#Override
public Color getInvalidBackroundColor() {
return Color.BLACK;
}
#Override
public Color getInvalidForegroundColor() {
return null;
}
#Override
public String getInvalidTooltip() {
return null;
}
#Override
public Color getSpecialBackroundColor() {
return Color.GREEN;
}
#Override
public Color getSpecialForegroundColor() {
return Color.RED;
}
#Override
public String getSpecialTooltip() {
return "filled";
}
#Override
public boolean isInvalid(Date date) {
return false;
}
#Override
public boolean isSpecial(Date date) {
return list.contains(date);
}
}
and here is my main method:
public static void main(){
JDateChooser dateChooser = new JDateChooser();
List<Date> dates = new ArrayList<Date>();
dates.add(new Date());
HighlightEvaluator evaluator = new HighlightEvaluator();
evaluator.setDates(dates);
dateChooser.getJCalendar().getDayChooser().addDateEvaluator(evaluator);
}
Now the current date is supposed to be highlighted by the code but its not getting highlighted. Please tell a fix for this
You need to alter the Date variable a little bit. When you create a Date variable it grabs the current day month year along with time(hours, minutes, seconds, milliseconds)
However setting the same date to evaluator will not work because evaluator expects date to be devoid of the time details. So alternatively you can use Calendar object in your main function as illustrated below:
public static void main(){
JDateChooser dateChooser = new JDateChooser();
List<Date> dates = new ArrayList<Date>();
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, desiredyear);
c.set(Calendar.MONTH, desiredmonth);
c.set(Calendar.DAY_OF_MONTH, desiredday);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
dates.add(c.getTime());
HighlightEvaluator evaluator = new HighlightEvaluator();
evaluator.setDates(dates);
dateChooser.getJCalendar().getDayChooser().addDateEvaluator(evaluator);
}
I am using JDateChooser for a java swing project I am developing and in this, the date could be set in two ways: by the end user or programmatically.
So I have defined a propertychangelistener in the respective class(the variable trig is initialised to zero and maintains track on how many times a property change is listened).
public class WriteEntry{
private int trig=0;
private Date currentDate = new Date();
public JDateChooser dateChooser = new JDateChooser();
public CustomDate selectedDate = DateConverter.convertDate(currentDate);
private static String filename = StorageSpace.currentpath+CurrentUser.getInstance().getUserName()+"\\"+
Integer.toString(selectedDate.getYear())+"\\"
+Integer.toString(selectedDate.getMonth())+"\\"+Integer.toString(selectedDate.getDay())+".txt";
private JLabel dayinfo = new JLabel("");
private JTextArea contentfield = new JTextArea("");
private PropertyChangeListener lis = new PropertyChangeListener(){
#Override
public void propertyChange(PropertyChangeEvent e) {
System.out.println("triggered "+trig++);
if(dateBoundary()) {
selectedDate = DateConverter.convertDate(dateChooser);
filename = StorageSpace.currentpath+CurrentUser.getInstance().getUserName()+"\\"+
Integer.toString(selectedDate.getYear())+"\\"
+Integer.toString(selectedDate.getMonth())+"\\"+Integer.toString(selectedDate.getDay())+".txt";
}
else {
updateDateChooser(selectedDate);
}
if(isAlreadyWritten())
{
try {
updateEditFields(selectedDate, "content");
} catch (IOException e1) {
e1.printStackTrace();
}
}
else
{
contentfield.setText("Start writing here");
dayinfo.setText("You are making entry for: "+ new SimpleDateFormat("dd/MM/yyyy").format(dateChooser.getDate()));
}
}
};
WriteEntry() //constructor
{
dateChooser.setDateFormatString("dd MM yyyy");
dateChooser.addPropertyChangeListener(lis);
updateEditFields(DateConverter.convertDate(currentDate), "Start");
}
}
And here is the code for dateBoundary():
public static boolean dateBoundary() {
Object[] option = {"I get it","My Bad!"};
if(dateChooser.getDate().compareTo(currentDate)>0) {
JOptionPane.showOptionDialog(HomePage.getFrame(),"message1",
"",JOptionPane.DEFAULT_OPTION,JOptionPane.ERROR_MESSAGE,null,option,option[0]);
return false;
}
if(dateChooser.getDate().compareTo(DateConverter.convertfromCustom(CurrentUser.getInstance().getDob()))<0){
JOptionPane.showOptionDialog(HomePage.getFrame(),"message2",
"",JOptionPane.DEFAULT_OPTION,JOptionPane.ERROR_MESSAGE,null,option,option[0]);
return false;
}
return true;
}
Code for isAlreadyWritten():
public static boolean isAlreadyWritten() {
File f = new File(filename);
if(f.length()!=0)
{
Object[] option = {"Read","Edit"};
JOptionPane.showOptionDialog(HomePage.getFrame(),"You already updated diary for this day. Do you want to edit?",
"",JOptionPane.DEFAULT_OPTION,JOptionPane.INFORMATION_MESSAGE,null,option,option[0]);
return true;
}
else
return false;
}
Code for updateDateChooser():
public static void updateDateChooser(CustomDate date) {
dateChooser.removePropertyChangeListener(lis); //to stop it from getting triggered when date is set programatically
dateChooser.setDate(DateConverter.convertfromCustom(date));
dateChooser.addPropertyChangeListener(lis);
}
Code for updateEditFields():
public static void updateEditFields(CustomDate searchDate, String excontent) {
updateDateChooser(searchDate);
selectedDate = DateConverter.convertDate(dateChooser);
dayinfo.setText("You are editing entry for: "+ new SimpleDateFormat("dd/MM/yyyy").format(dateChooser.getDate()));
contentfield.setText(excontent);
}
Now my dateboundary function is working as expected. whenever a date greater than current date is chosen, the optiondialog gets displayed and its gone after a click, and the datechooser is set to the last selected date, although the propertychange method is called thrice:
once before the dialog is displayed
twice after the dialog gets closed.
But my isAlreadyWritten() is not working as expected and the optiondialog is getting displayed 4 times with propertychange() method being called four times:
once before each time the dialog is displayed.
I want to understand why propertychange is being called 4 times even though the datechooser is detached from the listener when the date is set programatically?
So, I put together this quick snippet and ran it
import com.toedter.calendar.JDateChooser;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JDateChooser dateChooser = new JDateChooser();
dateChooser.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt.getPropertyName());
}
});
dateChooser.setDate(new Date());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(dateChooser);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I opened the date selector and selected a date. The program outputted...
date
ancestor
date
date
Was me setting the date programmatically
ancestor is it getting added to the container
Was me selecting the date picker
Was me selecting a date
So, as you can see, not only are you getting spammed with a lot of "date" property changes, you're also getting all the "other" property changes as well 😓
So, the first thing you want to do, is limit the the notifications to the "date" property only, something like...
dateChooser.addPropertyChangeListener("date", new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt.getPropertyName());
}
});
This at least means you don't get bother by all the additional information you don't care about.
While you can add and remove the listener, I tend to find it a pain, as I don't always have a reference to the listener(s), instead, I tend to use a state flag instead
private boolean manualDate = false;
//...
dateChooser.addPropertyChangeListener("date", new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (manualDate) {
return;
}
System.out.println(evt.getPropertyName());
}
});
manualDate = true;
dateChooser.setDate(new Date());
manualDate = false;
Not a big change, but this alone means that you're now down to two event notifications.
Instead, you should compare the oldValue with the newValue of the PropertyChangeEvent
JDateChooser dateChooser = new JDateChooser();
dateChooser.addPropertyChangeListener("date", new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (manualDate) {
return;
}
Date newDate = (Date) evt.getNewValue();
Date oldDate = (Date) evt.getOldValue();
if (newDate != null && oldDate != null) {
LocalDate newLD = LocalDate.ofInstant(newDate.toInstant(), ZoneId.systemDefault());
LocalDate oldLD = LocalDate.ofInstant(oldDate.toInstant(), ZoneId.systemDefault());
if (newLD.equals(oldLD)) {
return;
}
}
System.out.println(evt.getPropertyName());
}
});
And now, we're down to one change event. The only draw back is it won't tell you when they reselect the current date.
A slightly better work flow might be to ignore it all and simply have a JButton that the user can press to perform what ever associated actions you need carried out
Runnable Example...
import com.toedter.calendar.JDateChooser;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
private boolean manualDate;
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JDateChooser dateChooser = new JDateChooser();
dateChooser.addPropertyChangeListener("date", new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (manualDate) {
return;
}
Date newDate = (Date) evt.getNewValue();
Date oldDate = (Date) evt.getOldValue();
if (newDate != null && oldDate != null) {
LocalDate newLD = LocalDate.ofInstant(newDate.toInstant(), ZoneId.systemDefault());
LocalDate oldLD = LocalDate.ofInstant(oldDate.toInstant(), ZoneId.systemDefault());
if (newLD.equals(oldLD)) {
return;
}
}
System.out.println(evt.getPropertyName());
}
});
manualDate = true;
dateChooser.setDate(new Date());
manualDate = false;
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(dateChooser);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I load my jCalendar to Calendar then I used the day for the index but problem every month's days different so I can't select. When I click 21, I'm selecting 10.
Calendar cal = Calendar.getInstance();
cal.setTime(jCalendar1.getDate());
int day = cal.get(Calendar.DAY_OF_MONTH);
JPanel jpanel = jCalendar1.getDayChooser().getDayPanel();
Component compo[] = jpanel.getComponents();
compo[day].setBackground(Color.red);
public class CalendarTest2 extends JFrame {
private static final long serialVersionUID = 1L;
public CalendarTest2() {
Calendar cal = Calendar.getInstance();
JCalendar jCalendar1 = new JCalendar();
cal.setTime(jCalendar1.getDate());
int dayToBeSelected = cal.get(Calendar.DAY_OF_MONTH);
dayToBeSelected = 21;
JPanel jpanel = jCalendar1.getDayChooser().getDayPanel();
Component compo[] = jpanel.getComponents();
for (Component comp : compo) {
if (!(comp instanceof JButton))
continue;
JButton btn = (JButton) comp;
if (btn.getText().equals(String.valueOf(dayToBeSelected)))
comp.setBackground(Color.red);
}
add(jpanel);
}
public static void main(String[] args) {
CalendarTest2 test = new CalendarTest2();
test.setVisible(true);
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setSize(800, 800);
}
}
Instead of accessing the 'button to be selected' through index,
try to access the button through the text(day number) written on it.
The reason is, calendar of a month is displayed using 49 buttons arranged in 7x7 fashion .
So for ex) index 0 will always point to 'Sunday' button.
I am getting an error that it can't find the method getModel() and I am not sure what to do about this. I am trying to make it so that when a button is clicked, the dob variable is set to the value in the jdatechooser.
public Calendar getDOB()
{
return dob;
}
JDateChooser jdc = new JDateChooser();
JCalendar jc = new JCalendar();
Calendar calendar;
UtilDateModel model = new UtilDateModel();
model.setDate(1990, 8, 24);
JDatePanelImpl datePanel;
JDatePickerImpl datePicker;
Person samplePerson = new Person();
btnSubmit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
samplePerson.setDOB(calendar.getModel().getValue());
}
});
You're calling the getModel method on your Calendar instance (which doesn't have a getModel method) instead of on your JDatePanel instance
nevermind! I got it! The following line worked for me.
samplePerson.setDOB(jdc.getCalendar());