diff --git a/src/jdbernard/timestamper/NotesDialog.form b/src/jdbernard/timestamper/NotesDialog.form new file mode 100755 index 0000000..5b9aee2 --- /dev/null +++ b/src/jdbernard/timestamper/NotesDialog.form @@ -0,0 +1,96 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/jdbernard/timestamper/NotesDialog.java b/src/jdbernard/timestamper/NotesDialog.java new file mode 100755 index 0000000..079e03e --- /dev/null +++ b/src/jdbernard/timestamper/NotesDialog.java @@ -0,0 +1,148 @@ +/* + * NotesDialog.java + * + * Created on September 3, 2008, 4:53 PM + */ + +package jdbernard.timestamper; + +import java.awt.Font; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import javax.swing.JDialog; + +/** + * + * @author jbernard + */ +public class NotesDialog extends JDialog implements MouseMotionListener { + + /** Creates new form NotesDialog */ + public NotesDialog(TimeStamperView parent, boolean modal) { + super(parent.getFrame(), modal); + initComponents(); + + setSize(300, 200); + thinNotesFont = notesTextArea.getFont().deriveFont(Font.PLAIN); + boldNotesFont = notesTextArea.getFont().deriveFont(Font.BOLD); + + this.parent = parent; + } + + public void setNotes(String notes) { + notesTextArea.setText(notes); + notesTextArea.setFont(boldNotesFont); + } + + public String getNotes() { + return notesTextArea.getText(); + } + + /** 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() { + + mainPanel = new javax.swing.JPanel(); + notesScollPane = new javax.swing.JScrollPane(); + notesTextArea = new javax.swing.JTextArea(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setName("Form"); // NOI18N + setUndecorated(true); + + mainPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, new java.awt.Color(0, 0, 0))); + org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(NotesDialog.class); + mainPanel.setToolTipText(resourceMap.getString("mainPanel.toolTipText")); // NOI18N + mainPanel.setName("mainPanel"); // NOI18N + mainPanel.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + mainPanelMousePressed(evt); + } + }); + mainPanel.addMouseMotionListener(this); + + notesScollPane.setName("notesScollPane"); // NOI18N + + notesTextArea.setColumns(20); + notesTextArea.setRows(5); + notesTextArea.setName("notesTextArea"); // NOI18N + notesTextArea.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + notesTextAreaKeyReleased(evt); + } + }); + notesScollPane.setViewportView(notesTextArea); + + javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel); + mainPanel.setLayout(mainPanelLayout); + mainPanelLayout.setHorizontalGroup( + mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(mainPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(notesScollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE) + .addContainerGap()) + ); + mainPanelLayout.setVerticalGroup( + mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(notesScollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 174, Short.MAX_VALUE) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + + pack(); + }// //GEN-END:initComponents + +private void notesTextAreaKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_notesTextAreaKeyReleased + if ((evt.getKeyCode() == KeyEvent.VK_ENTER) && evt.isControlDown()) { + parent.setNotesForActiveTask(notesTextArea.getText()); + notesTextArea.setFont(boldNotesFont); + } else if (evt.getKeyCode() != KeyEvent.VK_CONTROL) + notesTextArea.setFont(thinNotesFont); +}//GEN-LAST:event_notesTextAreaKeyReleased + +private void mainPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mainPanelMousePressed + mousePressRelativeToWindow = evt.getPoint(); +}//GEN-LAST:event_mainPanelMousePressed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel mainPanel; + private javax.swing.JScrollPane notesScollPane; + private javax.swing.JTextArea notesTextArea; + // End of variables declaration//GEN-END:variables + + private TimeStamperView parent; + Font thinNotesFont; + Font boldNotesFont; + Point mousePressRelativeToWindow; + + public void mouseDragged(MouseEvent e) { + setLocation(TimeStamperView.calculateWindowMovement( + e.getLocationOnScreen(), mousePressRelativeToWindow, + getBounds(), parent.getFrame().getBounds(), + new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))); + } + + public void mouseMoved(MouseEvent e) { + } +} diff --git a/src/jdbernard/timestamper/TimeStamperApp.java b/src/jdbernard/timestamper/TimeStamperApp.java index 8175e24..2f798b2 100755 --- a/src/jdbernard/timestamper/TimeStamperApp.java +++ b/src/jdbernard/timestamper/TimeStamperApp.java @@ -66,7 +66,7 @@ implements Application.ExitListener { } /** - * + * */ @Override protected void initialize(String[] args) { if (args.length > 0) { diff --git a/src/jdbernard/timestamper/TimeStamperView.form b/src/jdbernard/timestamper/TimeStamperView.form index bd73c61..e43b23b 100755 --- a/src/jdbernard/timestamper/TimeStamperView.form +++ b/src/jdbernard/timestamper/TimeStamperView.form @@ -22,7 +22,7 @@ - + @@ -37,7 +37,7 @@ - + @@ -77,7 +77,7 @@ - + @@ -165,18 +165,6 @@ - - - - - - - - - - - - @@ -204,6 +192,18 @@ + + + + + + + + + + + + @@ -256,6 +256,6 @@ - + diff --git a/src/jdbernard/timestamper/TimeStamperView.java b/src/jdbernard/timestamper/TimeStamperView.java index 30b8b57..a82ac87 100755 --- a/src/jdbernard/timestamper/TimeStamperView.java +++ b/src/jdbernard/timestamper/TimeStamperView.java @@ -4,7 +4,6 @@ package jdbernard.timestamper; -import java.awt.Dimension; import java.awt.Font; import java.awt.Point; import java.awt.Rectangle; @@ -17,7 +16,6 @@ import java.util.Timer; import java.util.TimerTask; import javax.swing.JFileChooser; import org.jdesktop.application.Action; -import org.jdesktop.application.Application; import org.jdesktop.application.ResourceMap; import org.jdesktop.application.SingleFrameApplication; import org.jdesktop.application.FrameView; @@ -37,6 +35,7 @@ public class TimeStamperView extends FrameView implements MouseMotionListener { getFrame().setUndecorated(true); fileChooser = new JFileChooser(); + notesDialog = new NotesDialog(this, false); updateTimer = new Timer(); updateTimer.scheduleAtFixedRate(new TimerTask() { @@ -78,6 +77,7 @@ public class TimeStamperView extends FrameView implements MouseMotionListener { startTimeLabel.setText(Timeline.shortFormat.format(lastMarker.getTimestamp())); taskTextField.setText(lastMarker.getMark()); + notesDialog.setNotes(lastMarker.getNotes()); } } @@ -97,8 +97,8 @@ public class TimeStamperView extends FrameView implements MouseMotionListener { startTimeLabel = new javax.swing.JLabel(); totalTimeNow = new javax.swing.JLabel(); currentTimeLabel = new javax.swing.JLabel(); - notesButton = new javax.swing.JButton(); optionsButton = new javax.swing.JButton(); + notesButton = new javax.swing.JToggleButton(); optionsMenu = new javax.swing.JPopupMenu(); saveTimelineMenuItem = new javax.swing.JMenuItem(); saveTimelineAsMenuItem = new javax.swing.JMenuItem(); @@ -159,11 +159,6 @@ public class TimeStamperView extends FrameView implements MouseMotionListener { currentTimeLabel.setText(resourceMap.getString("currentTimeLabel.text")); // NOI18N currentTimeLabel.setName("currentTimeLabel"); // NOI18N - notesButton.setAction(actionMap.get("editNotes")); // NOI18N - notesButton.setHideActionText(true); - notesButton.setMargin(new java.awt.Insets(0, 0, 0, 0)); - notesButton.setName("notesButton"); // NOI18N - optionsButton.setIcon(resourceMap.getIcon("optionsButton.icon")); // NOI18N optionsButton.setContentAreaFilled(false); optionsButton.setFocusPainted(false); @@ -186,6 +181,11 @@ public class TimeStamperView extends FrameView implements MouseMotionListener { } }); + notesButton.setAction(actionMap.get("editNotes")); // NOI18N + notesButton.setHideActionText(true); + notesButton.setMargin(new java.awt.Insets(0, 0, 0, 0)); + notesButton.setName("notesButton"); // NOI18N + javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel); mainPanel.setLayout(mainPanelLayout); mainPanelLayout.setHorizontalGroup( @@ -232,7 +232,7 @@ public class TimeStamperView extends FrameView implements MouseMotionListener { .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(currentTimeLabel) .addComponent(totalTimeNow)))) - .addContainerGap(24, Short.MAX_VALUE)) + .addContainerGap(31, Short.MAX_VALUE)) ); optionsMenu.setName("optionsMenu"); // NOI18N @@ -291,7 +291,14 @@ private void optionsButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIR @Action public void editNotes() { - // TODO: + notesDialog.setVisible(notesButton.isSelected()); + } + + public void setNotesForActiveTask(String notes) { + Timeline t = ((TimeStamperApp) getApplication()).getActiveTimeline(); + Timeline.TimelineMarker tm = t.getLastMarker(new Date()); + if (tm == null) return; + tm.setNotes(notes); } // Variables declaration - do not modify//GEN-BEGIN:variables @@ -300,7 +307,7 @@ private void optionsButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIR private javax.swing.JButton exitButton; private javax.swing.JMenuItem loadTimelineMenuItem; private javax.swing.JPanel mainPanel; - private javax.swing.JButton notesButton; + private javax.swing.JToggleButton notesButton; private javax.swing.JButton optionsButton; private javax.swing.JPopupMenu optionsMenu; private javax.swing.JMenuItem saveTimelineAsMenuItem; @@ -316,47 +323,74 @@ private void optionsButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIR private Font boldTaskFont; private Font thinTaskFont; private Date mostRecentTask; + private NotesDialog notesDialog; public void mouseDragged(MouseEvent e) { - Point currentMousePoint = e.getLocationOnScreen(); + getFrame().setLocation(calculateWindowMovement(e.getLocationOnScreen(), + mousePressRelativeToFrame, getFrame().getBounds(), + new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))); + } + + public static Point calculateWindowMovement(Point currentMousePoint, + Point mousePressRelativeToWindow, Rectangle windowBounds, + Rectangle... snapBoxes) { // this is the point we will compute as the new upper left // coordinate of the frame. It needs to be translated some to account // for the fact that the user can press the mouse anywhere on the // main panel. - Point finalPoint = (Point) currentMousePoint.clone(); + Point currentWindowPoint = (Point) currentMousePoint.clone(); // find out where the new point should be, ignoreing screen bounds - finalPoint.translate(-mousePressRelativeToFrame.x, - -mousePressRelativeToFrame.y); + currentWindowPoint.translate(-mousePressRelativeToWindow.x, + -mousePressRelativeToWindow.y); - // get the current frame bounds - Rectangle frameBounds = getFrame().getBounds(); + Point finalWindowPoint = (Point) currentWindowPoint.clone(); - // screen resolution - Dimension resolution = Toolkit.getDefaultToolkit().getScreenSize(); + // snap tests. In the event of a conflict in snaps positions, the + // last snap wins + int wUp = windowBounds.y; + int wDown = windowBounds.y + windowBounds.height; + int wLeft = windowBounds.x; + int wRight = windowBounds.x + windowBounds.width; - // check to see if the frame is near any of the screen boundaries - // if it is, 'snap' the final point to that boundary. - if (frameBounds.x < 20) - finalPoint.translate(-finalPoint.x, 0); - if (frameBounds.y < 20) - finalPoint.translate(0, -finalPoint.y); - if ((resolution.width - (frameBounds.x + frameBounds.width)) < 20) - finalPoint.translate(resolution.width - - (finalPoint.x + frameBounds.width), 0); - if ((resolution.height - (frameBounds.y + frameBounds.height)) < 20) - finalPoint.translate(0, resolution.height - - (finalPoint.y + frameBounds.height)); +// currentTaskLabel.setText("U:" + wUp + " D:" + wDown + " L:" + wLeft +// + " R:" + wRight); + for (Rectangle r : snapBoxes) { + int rUp = r.y; + int rDown = r.y + r.height; + int rLeft = r.x; + int rRight = r.x + r.width; + + // check to see if the window is near any of the snap boundaries + // if it is, 'snap' the final point to that boundary. + if (Math.abs(rUp - wUp) < 20) // top of window to top of rect + finalWindowPoint.y = rUp; + else if (Math.abs(rUp - wDown) < 20) // bot of w to top of r + finalWindowPoint.y = rUp - windowBounds.height; + else if (Math.abs(rDown - wUp) < 20) // top of w to bot of r + finalWindowPoint.y = rDown; + else if (Math.abs(rDown - wDown) < 20) // bot of w to bot of r + finalWindowPoint.y = rDown - windowBounds.height; + + if (Math.abs(rLeft - wLeft) < 20) // left of w to left of r + finalWindowPoint.x = rLeft; + else if (Math.abs(rLeft - wRight) < 20) // right of w to left of r + finalWindowPoint.x = rLeft - windowBounds.width; + else if (Math.abs(rRight - wLeft) < 20) // left of w to right of r + finalWindowPoint.x = rRight; + else if (Math.abs(rRight - wRight) < 20) // right of w to right of r + finalWindowPoint.x = rRight - windowBounds.width; + } // this point represents a backwards version of the initial calculation // to find the finalPoint. It says, based on the current final point, // assume I moved the frame to that point. Where, relative to that point // should the mouse be, based on how far it was relative to the point // when the user pressed it. - Point whereMouseShouldBe = (Point) finalPoint.clone(); - whereMouseShouldBe.translate(mousePressRelativeToFrame.x, - mousePressRelativeToFrame.y); + Point whereMouseShouldBe = (Point) finalWindowPoint.clone(); + whereMouseShouldBe.translate(mousePressRelativeToWindow.x, + mousePressRelativeToWindow.y); // if the actual mouse location is different from the expected location, // then we know that the snapping behaviour has altered the frames new @@ -365,13 +399,12 @@ private void optionsButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIR // position. In this case, we want to ignore the snap calculations and // base the new frame location entirely on the current mouse location if (whereMouseShouldBe.distance(currentMousePoint) > 30) { - finalPoint = (Point) currentMousePoint.clone(); - finalPoint.translate(-mousePressRelativeToFrame.x, - -mousePressRelativeToFrame.y); + finalWindowPoint = (Point) currentMousePoint.clone(); + finalWindowPoint.translate(-mousePressRelativeToWindow.x, + -mousePressRelativeToWindow.y); } - // once we've figured out where to go, put us there :) - getFrame().setLocation(finalPoint); + return finalWindowPoint; } public void mouseMoved(MouseEvent e) { @@ -408,6 +441,7 @@ private void optionsButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIR startTimeLabel.setText(Timeline.shortFormat.format(lastMarker.getTimestamp())); taskTextField.setText(lastMarker.getMark()); + notesDialog.setNotes(lastMarker.getNotes()); } } } diff --git a/src/jdbernard/timestamper/resources/NotesDialog.properties b/src/jdbernard/timestamper/resources/NotesDialog.properties new file mode 100755 index 0000000..1ca991b --- /dev/null +++ b/src/jdbernard/timestamper/resources/NotesDialog.properties @@ -0,0 +1,4 @@ +# To change this template, choose Tools | Templates +# and open the template in the editor. + +mainPanel.toolTipText=Write notes for this event. diff --git a/src/jdbernard/timestamper/resources/TimeStamperView.properties b/src/jdbernard/timestamper/resources/TimeStamperView.properties index 69e5b38..70bbe25 100755 --- a/src/jdbernard/timestamper/resources/TimeStamperView.properties +++ b/src/jdbernard/timestamper/resources/TimeStamperView.properties @@ -44,3 +44,4 @@ exit.Action.text=Exit exit.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-em-cross.png exit.Action.shortDescription=Close the application. exit.Action.icon=/jdbernard/timestamper/resources/icons/16-em-cross.png +notesButton2.text=jToggleButton1