com.tmathmeyer.sentinel.ui.views.day.DayCalendar.java Source code

Java tutorial

Introduction

Here is the source code for com.tmathmeyer.sentinel.ui.views.day.DayCalendar.java

Source

/*******************************************************************************
 * Copyright (c) 2013 WPI-Suite
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Team YOCO (You Only Compile Once)
 ******************************************************************************/
package com.tmathmeyer.sentinel.ui.views.day;

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.BoundedRangeModel;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.MutableDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.lowagie.text.Font;
import com.tmathmeyer.sentinel.AbstractCalendar;
import com.tmathmeyer.sentinel.models.client.local.EventClient;
import com.tmathmeyer.sentinel.models.client.net.CommitmentClient;
import com.tmathmeyer.sentinel.models.data.Displayable;
import com.tmathmeyer.sentinel.ui.main.MainPanel;
import com.tmathmeyer.sentinel.ui.views.day.collisiondetection.DayPanel;
import com.tmathmeyer.sentinel.utils.Colors;
import com.tmathmeyer.sentinel.utils.Months;

public class DayCalendar extends AbstractCalendar {
    private static final long serialVersionUID = 1L;
    private DateTime time;

    private DayPanel current;

    private List<Displayable> displayableList = new ArrayList<Displayable>();

    private JPanel holder = new JPanel();
    private JScrollPane scroll = new JScrollPane(holder);

    private DateTimeFormatter titleFmt = DateTimeFormat.forPattern("EEEE, MMM d, yyyy");
    private boolean scrolled = false;

    public DayCalendar(DateTime on) {
        this.time = on;

        MutableDateTime mdt = time.toMutableDateTime();
        mdt.setMillis(0);
        mdt.addDays(1);
        mdt.addMillis(-1);

        scroll.setBackground(Colors.TABLE_BACKGROUND);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scroll.getVerticalScrollBar().setUnitIncrement(20);
        scroll.setAutoscrolls(true);
        scroll.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
        holder.setBackground(Colors.TABLE_BACKGROUND);

        this.setLayout(new BorderLayout());
        this.holder.setLayout(new BorderLayout());

        generateDay();
    }

    private void generateDay() {
        this.holder.removeAll();
        this.removeAll();
        this.add(scroll, BorderLayout.CENTER);

        JLabel dayTitle = new JLabel(time.toString(titleFmt));
        dayTitle.setFont(new java.awt.Font("DejaVu Sans", Font.BOLD, 25));
        dayTitle.setHorizontalAlignment(SwingConstants.CENTER);
        this.add(dayTitle, BorderLayout.NORTH);

        this.displayableList = getVisibleDisplayables();

        this.current = new DayPanel();
        this.current.setEvents(
                getDisplayablesInInterval(time.withMillisOfDay(0), time.plusDays(1).withMillisOfDay(0)), time);
        this.current.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Colors.BORDER));

        this.holder.add(new DayGridLabel(), BorderLayout.WEST);
        this.holder.add(this.current, BorderLayout.CENTER);

        // notify mini-calendar to change
        MainPanel.getInstance().miniMove(time);
    }

    /**
     * Get visible events for the current day view
     * 
     * @return returns the list of events to display
     */
    private List<Displayable> getVisibleDisplayables() {
        // Set up from and to datetime for search
        MutableDateTime f = new MutableDateTime(time);
        f.setMillisOfDay(0);
        DateTime from = f.toDateTime();
        f.addDays(1);
        DateTime to = f.toDateTime();

        // Return list of events to be displayed
        List<Displayable> visibleDisplayables = new ArrayList<Displayable>();
        visibleDisplayables.addAll(EventClient.getInstance().getWithinRange(from, to));
        visibleDisplayables.addAll(CommitmentClient.getInstance().getCommitments(from, to));

        Collections.sort(visibleDisplayables, new Comparator<Displayable>() {
            public int compare(Displayable d1, Displayable d2) {
                return d1.getStart().getMinuteOfDay() < d2.getStart().getMinuteOfDay() ? -1
                        : d1.getStart().getMinuteOfDay() > d2.getStart().getMinuteOfDay() ? 1 : 0;
            }
        });

        return visibleDisplayables;
    }

    @Override
    public void next() {
        display(Months.nextDay(this.time));
    }

    @Override
    public void previous() {
        display(Months.prevDay(this.time));
    }

    @Override
    public void display(DateTime newTime) {
        this.time = newTime;
        this.generateDay();

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                if (scrolled)
                    return;
                scrolled = true;
                // Scroll to now
                BoundedRangeModel jsb = scroll.getVerticalScrollBar().getModel();

                double day;

                if (!displayableList.isEmpty()) {
                    day = displayableList.get(0).getStart().getMinuteOfDay();
                } else {
                    day = DateTime.now().getMinuteOfDay();
                }

                day -= (day > 60) ? 60 : day;

                day /= time.minuteOfDay().getMaximumValue();
                day *= (jsb.getMaximum()) - jsb.getMinimum();
                jsb.setValue((int) day);
            }
        });

        MainPanel.getInstance().revalidate();
        MainPanel.getInstance().repaint();
    }

    @Override
    public void updateDisplayable(Displayable events, boolean added) {
        // at the moment, we don't care, and just re-pull from the DB. TODO:
        // this should change
        this.generateDay();
    }

    @Override
    public void select(Displayable item) {
        current.select(item);
    }

    @Override
    public void setSelectedDay(DateTime time) {

    }

    /**
     * Gets all the events in the week that also are in the given interval
     * 
     * @param intervalStart start of the interval to check
     * @param intervalEnd end of the interval to check
     * @return list of events that are both in the week and interval
     */
    private List<Displayable> getDisplayablesInInterval(DateTime intervalStart, DateTime intervalEnd) {
        List<Displayable> retrievedDisplayables = new ArrayList<>();
        Interval mInterval = new Interval(intervalStart, intervalEnd);

        for (Displayable d : displayableList) {
            if (isDisplayableInInterval(d, mInterval)) {
                retrievedDisplayables.add(d);
            }

        }

        return retrievedDisplayables;
    }

    private boolean isDisplayableInInterval(Displayable mDisplayable, Interval mInterval) {
        DateTime s = mDisplayable.getStart();
        if (this.time.isAfter(s))
            s = this.time;

        return (mInterval.contains(s));
    }
}