javanetbeansjcalendar

Background color on specific dates using JCalendar


Im trying to set specific dates in my JCalendar in a different color depending on if there is something planned for that date in my database, the date is stored as"yyyy-MM-dd" in the database, I've seen similar posts here on stackOverflow but I just cant get it to work.

I'm not sure how "component[day].setBackground(Color.green)" works like and how I can set it to only dates that has something planned for them in the database

    public void kalender() {
    Calendar cal = Calendar.getInstance();

    cal.set(Calendar.DAY_OF_MONTH, 1);
    int offset = cal.get(Calendar.DAY_OF_WEEK);

    int mon = kalender.getMonthChooser().getMonth() + 1;

    int yr = kalender.getYearChooser().getYear();

    JPanel jPanel = kalender.getDayChooser().getDayPanel();

    Component component[] = jPanel.getComponents();

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
     String kalenderdatum = format.format(kalender.getDate());
     System.out.println(kalenderdatum);



    String sql2 = "SELECT DATUM FROM MOTE";
    try {
        Statement stmt = connection.createStatement();
        ResultSet rs = stmt.executeQuery(sql2);

        while (rs.next()) {
            String datumet = rs.getString("DATUM");



            String aret = datumet.substring(0, 4);
            int year = Integer.parseInt(aret);

            String manaden = datumet.substring(5,7);
            int month = Integer.parseInt(manaden);

            String dagen = datumet.substring(8,10);
            int day = Integer.parseInt(dagen);

            if(yr == year && mon == month)
            {

                component[day].setBackground(Color.green);
            }

            }

Solution

  • One solution that uses the JCalendar API is to create your own instance of IDateEvaluator and checks if a date has anything "special" about it.

    1. Converting

    First I suggest getting your dates (yyyy-MM-dd) into a list and convert them to Date objects. For example:

    List<String> mysqlDates = Arrays.asList("2019-02-14", "2019-03-06"); // Assume you've got this info somehow
    List<Date> specialDates = convertToDates(mysqlDates);
    

    With the help of the following function:

    public static List<Date> convertToDates(List<String> dateStrings) throws ParseException {
        List<Date> dates = new ArrayList<>();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    
        for (String dateString : dateStrings) {
            dates.add(df.parse(dateString));
        }
    
        return dates;
    }
    

    2. Create your SpecialDateEvaluator

    Then you need to create your own date evaluator that takes in the Date objects that are going to be handled differently. A simple example would be the following:

    public class SpecialDateEvaluator implements IDateEvaluator {
    
        private final List<Date> specialDates;
    
        public SpecialDateEvaluator(List<Date> specialDates) {
            this.specialDates = specialDates;
        }
    
        @Override
        public boolean isSpecial(Date date) {
            for (Date d : specialDates) {
                if (d.equals(date)) {
                    return true;
                }
            }
    
            return false;
        }
    
        @Override
        public Color getSpecialForegroundColor() {
            return Color.black;
        }
    
        @Override
        public Color getSpecialBackroundColor() {
            return Color.red;
        }
    
        @Override
        public String getSpecialTooltip() {
            return null;
        }
    
        @Override
        public boolean isInvalid(Date date) {
            return false;
        }
    
        @Override
        public Color getInvalidForegroundColor() {
            return null;
        }
    
        @Override
        public Color getInvalidBackroundColor() {
            return null;
        }
    
        @Override
        public String getInvalidTooltip() {
            return null;
        }
    }
    

    3. Utilize the date evaluator

    To utilize the evaluator you need to add it to the JDayChooser, taking in the list of Date objects and then setting the Calendar again to refresh the view. For example:

    JCalendar c = new JCalendar();
    c.getDayChooser().addDateEvaluator(new SpecialDateEvaluator(specialDates));
    c.setCalendar(Calendar.getInstance());
    

    To see a full example of this (with a main method), see this example gist.