diff --git a/build.xml b/build.xml
index 574c0b4..c6bbd56 100755
--- a/build.xml
+++ b/build.xml
@@ -82,4 +82,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties
index 1974116..30d5b4c 100755
--- a/nbproject/private/private.properties
+++ b/nbproject/private/private.properties
@@ -4,3 +4,4 @@ javac.debug=true
javadoc.preview=true
jaxws.endorsed.dir=C:\\Program Files\\NetBeans 6.1\\java2\\modules\\ext\\jaxws21\\api
user.properties.file=C:\\Documents and Settings\\jbernard\\.netbeans\\6.1\\build.properties
+axis2.deploy.war=C:\\Program Files\\glassfish-v2ur2\\domains\\domain1\\autodeploy\\axis2.war
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index f3fb4c5..c1f155a 100755
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -1,8 +1,4 @@
-
- file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/TimeStamperApp.java
- file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/TimeStamperView.java
-
diff --git a/src/jdbernard/timestamper/PunchcardDisplayDialog.form b/src/jdbernard/timestamper/PunchcardDisplayDialog.form
new file mode 100755
index 0000000..e1b8c0f
--- /dev/null
+++ b/src/jdbernard/timestamper/PunchcardDisplayDialog.form
@@ -0,0 +1,65 @@
+
+
+
diff --git a/src/jdbernard/timestamper/PunchcardDisplayDialog.java b/src/jdbernard/timestamper/PunchcardDisplayDialog.java
new file mode 100755
index 0000000..7f7c9e7
--- /dev/null
+++ b/src/jdbernard/timestamper/PunchcardDisplayDialog.java
@@ -0,0 +1,100 @@
+/*
+ * PunchcardDisplayDialog.java
+ *
+ * Created on October 16, 2008, 4:37 PM
+ */
+
+package jdbernard.timestamper;
+
+import java.io.File;
+import java.util.Calendar;
+
+/**
+ *
+ * @author jbernard
+ */
+public class PunchcardDisplayDialog extends javax.swing.JDialog {
+
+ /** Creates new form PunchcardDisplayDialog */
+ public PunchcardDisplayDialog(java.awt.Frame parent, boolean modal) {
+ super(parent, modal);
+ initComponents();
+ timelineDayDisplay1.setDay(Calendar.getInstance());
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ timelineDayDisplay1 = new jdbernard.timestamper.TimelineDayDisplay();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setName("Form"); // NOI18N
+
+ timelineDayDisplay1.setName("timelineDayDisplay1"); // NOI18N
+
+ javax.swing.GroupLayout timelineDayDisplay1Layout = new javax.swing.GroupLayout(timelineDayDisplay1);
+ timelineDayDisplay1.setLayout(timelineDayDisplay1Layout);
+ timelineDayDisplay1Layout.setHorizontalGroup(
+ timelineDayDisplay1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 380, Short.MAX_VALUE)
+ );
+ timelineDayDisplay1Layout.setVerticalGroup(
+ timelineDayDisplay1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 278, Short.MAX_VALUE)
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(timelineDayDisplay1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(timelineDayDisplay1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) throws Exception {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ PunchcardDisplayDialog dialog = new PunchcardDisplayDialog(new javax.swing.JFrame(), true);
+ try { dialog.timelineDayDisplay1.setTimeline(Timeline.readFromFile("test-timeline.txt")); }
+ catch (Exception e) {
+ System.err.println("Could not open timeline text.");
+ try { new File("PLACE_HERE").createNewFile(); }
+ catch (Exception e1) {}
+ }
+ dialog.addWindowListener(new java.awt.event.WindowAdapter() {
+ public void windowClosing(java.awt.event.WindowEvent e) {
+ System.exit(0);
+ }
+ });
+ dialog.setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private jdbernard.timestamper.TimelineDayDisplay timelineDayDisplay1;
+ // End of variables declaration//GEN-END:variables
+
+ private Timeline timeline;
+}
diff --git a/src/jdbernard/timestamper/TimelineDayDisplay.java b/src/jdbernard/timestamper/TimelineDayDisplay.java
new file mode 100755
index 0000000..cf64a7c
--- /dev/null
+++ b/src/jdbernard/timestamper/TimelineDayDisplay.java
@@ -0,0 +1,136 @@
+/* TimelineDayDisplay.java
+ * Author: Jonathan Bernard - jonathan.bernard@gemalto.com
+ */
+
+package jdbernard.timestamper;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+
+/**
+ *
+ * @author jbernard
+ */
+public class TimelineDayDisplay extends JComponent {
+
+ private Timeline timeline;
+ private Calendar day;
+
+ private final Color evenTrans = new Color(0.75f, 0.75f, 0.75f, 0.4f);
+ private final Color evenOpaque = new Color(0.75f, 0.75f, 0.75f, 1f);
+ private final Color oddTrans = new Color(0.5f, 0.5f, 0.5f, 0.4f);
+ private final Color oddOpaque = new Color(0.5f, 0.5f, 0.5f, 1f);
+
+ public TimelineDayDisplay() {
+ super();
+ }
+
+ public TimelineDayDisplay(Timeline timeline, Calendar day) {
+ super();
+ this.timeline = timeline;
+ this.day = day;
+ }
+
+ public void setTimeline(Timeline t) {
+ timeline = t;
+ }
+
+ public Timeline getTimeline() {
+ return timeline;
+ }
+
+ public void setDay(Calendar d) {
+ day = d;
+ day.set(Calendar.HOUR_OF_DAY, 0);
+ day.set(Calendar.MINUTE, 0);
+ day.set(Calendar.SECOND, 0);
+ }
+
+ public Calendar getDay() {
+ return day;
+ }
+
+ @Override
+ public void paintComponent(Graphics g) {
+ Insets insets = this.getInsets();
+ Rectangle bounds = this.getBounds();
+ Rectangle canvasBounds = new Rectangle(insets.left, insets.top,
+ bounds.width - insets.left - insets.right - 1,
+ bounds.height - insets.top - insets.bottom - 1);
+
+ Calendar nextDay = Calendar.getInstance();
+ nextDay.setTime(day.getTime());
+ nextDay.add(Calendar.DAY_OF_YEAR, 1);
+
+ Graphics2D g2d = (Graphics2D) g;
+ double hourHeight = canvasBounds.getHeight() / 24.0;
+ long oneDayInMilli = (24 * 60 * 60 * 1000);
+ Rectangle2D stringBounds = getFontMetrics(getFont()).getStringBounds("00:00 ", g);
+ for (int i = 1; i < 24; i++) {
+ int lineY = (int) Math.round(hourHeight * (double) i);
+ g.drawLine(canvasBounds.x + (int) stringBounds.getWidth(), canvasBounds.y + lineY,
+ canvasBounds.x + canvasBounds.width,
+ canvasBounds.y + lineY);
+
+ if ((hourHeight > (stringBounds.getHeight()) || ((i % 2) == 0))) {
+ g.drawString(String.format("%1$02d:00", i),
+ canvasBounds.x + 2, lineY + (int) (stringBounds.getHeight() / 2));
+ }
+ }
+
+ Timeline.TimelineMarker tm = timeline.getLastMarker(day.getTime());
+ Iterator itr = timeline.iterator();
+
+ while (!itr.next().equals(tm));
+
+ ArrayList markers = new ArrayList();
+ while (nextDay.getTime().after(tm.getTimestamp())) {
+ markers.add(tm);
+ if (itr.hasNext()) tm = itr.next();
+ else break;
+ }
+
+ markers.add(tm);
+
+ for (int i = 0; i < markers.size(); i++) {
+ int boxY = 0;
+ int boxHeight = 1;
+ if (i != 0) {
+ double relTime = markers.get(i).getTimestamp().getTime() - day.getTimeInMillis();
+ boxY = (int) Math.round((relTime / oneDayInMilli)
+ * canvasBounds.getHeight()) + canvasBounds.y;
+ }
+ if (i == markers.size() - 1) {
+ double relTime = nextDay.getTime().getTime()
+ - markers.get(i).getTimestamp().getTime();
+ boxHeight = (int) Math.round(relTime / oneDayInMilli
+ * canvasBounds.getHeight());
+ } else {
+ double relTime = markers.get(i + 1).getTimestamp().getTime()
+ - markers.get(i).getTimestamp().getTime();
+ boxHeight = (int) Math.round(relTime / oneDayInMilli
+ * canvasBounds.getHeight());
+ }
+ g.setColor((i % 2 == 0 ? evenTrans : oddTrans));
+ g.fillRect(canvasBounds.x + (int) stringBounds.getWidth() + 5, boxY,
+ canvasBounds.x + canvasBounds.width, boxHeight);
+ g2d.setColor((i % 2 == 0 ? evenOpaque : oddOpaque));
+ g2d.setStroke(new BasicStroke(3f));
+ g2d.drawRect(canvasBounds.x + (int) stringBounds.getWidth() + 5, boxY,
+ canvasBounds.x + canvasBounds.width, boxHeight);
+ }
+
+ g.setColor(Color.BLACK);
+ g.drawRect(canvasBounds.x, canvasBounds.y, canvasBounds.width, canvasBounds.height);
+ }
+}
diff --git a/test-timeline.txt b/test-timeline.txt
new file mode 100755
index 0000000..1cb120c
Binary files /dev/null and b/test-timeline.txt differ