Project Time Tracker

Posted by Geertjan on Oracle Blogs See other posts from Oracle Blogs or by Geertjan
Published on Tue, 18 Dec 2012 08:00:00 +0000 Indexed on 2012/12/19 11:09 UTC
Read the original article Hit count: 192

Filed under:

Based on yesterday's blog entry, let's do something semi useful and display, in the project popup, which is available when you right-click a project in the Projects window, the time since the last change was made anywhere in the project, i.e., we can listen recursively to any changes done within a project and then update the popup with the newly acquired information, dynamically:

import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.AbstractAction;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.awt.StatusDisplayer;
import org.openide.filesystems.FileAttributeEvent;
import org.openide.filesystems.FileChangeListener;
import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileRenameEvent;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.Utilities;
import org.openide.util.WeakListeners;

@ActionID(
        category = "Demo",
        id = "org.ptt.TrackProjectSelectionAction")
@ActionRegistration(
        lazy = false,
        displayName = "NOT-USED")
@ActionReference(
        path = "Projects/Actions",
        position = 0)
public final class TrackProjectSelectionAction extends AbstractAction
        implements LookupListener, FileChangeListener {

    private Lookup.Result<Project> projects;
    private Project context;
    private Long startTime;
    private Long changedTime;
    private DateFormat formatter;
    private List<Project> timedProjects;

    public TrackProjectSelectionAction() {
        putValue("popupText", "Timer");
        formatter = new SimpleDateFormat("HH:mm:ss");
        timedProjects = new ArrayList<Project>();
        projects = Utilities.actionsGlobalContext().lookupResult(Project.class);
        projects.addLookupListener(
                WeakListeners.create(LookupListener.class, this, projects));
        resultChanged(new LookupEvent(projects));
    }

    @Override
    public void resultChanged(LookupEvent le) {
        Collection<? extends Project> allProjects = projects.allInstances();
        if (allProjects.size() == 1) {
            Project currentProject = allProjects.iterator().next();
            if (!timedProjects.contains(currentProject)) {
                String currentProjectName =
                        ProjectUtils.getInformation(currentProject).getDisplayName();
                putValue("popupText", "Start Timer for Project: " + currentProjectName);
                StatusDisplayer.getDefault().setStatusText(
                        "Current Project: " + currentProjectName);
                timedProjects.add(currentProject);
                context = currentProject;
            } 
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        refresh();
    }

    protected void refresh() {
        startTime = System.currentTimeMillis();
        String formattedStartTime = formatter.format(startTime);
        putValue("popupText", "Timer started: " + formattedStartTime + " ("
                + ProjectUtils.getInformation(context).getDisplayName() + ")");
    }

    @Override
    public void fileChanged(FileEvent fe) {
        changedTime = System.currentTimeMillis();
        formatter = new SimpleDateFormat("mm:ss");
        String formattedLapse = formatter.format(changedTime - startTime);
        putValue("popupText", "Time since last change: " + formattedLapse + " ("
                + ProjectUtils.getInformation(context).getDisplayName() + ")");
        startTime = changedTime;
    }

    @Override
    public void fileFolderCreated(FileEvent fe) {}
    @Override
    public void fileDataCreated(FileEvent fe) {}
    @Override
    public void fileDeleted(FileEvent fe) {}
    @Override
    public void fileRenamed(FileRenameEvent fre) {}
    @Override
    public void fileAttributeChanged(FileAttributeEvent fae) {}
    
}

Some more work needs to be done to complete the above, i.e., for each project you somehow need to maintain the start time and last change and redisplay that whenever the user right-clicks the project.

© Oracle Blogs or respective owner

Related posts about /NetBeans IDE