/* * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is JIM, a Java Information Manager. * (http://www.kclee.com/clemens/java/jim/). * * The Initial Developer of the Original Code is Chr. Clemens Lee. * Portions created by Chr. Clemens Lee are Copyright (C) 2000 * Chr. Clemens Lee. All Rights Reserved. * * Contributor(s): Chr. Clemens Lee <clemens@kclee.com> */ package jim; import ccl.swing.AutoGridBagLayout; import ccl.swing.CCLBorder; import ccl.swing.DateField; import ccl.swing.OKCancelPanel; import ccl.swing.SwingUtil; import ccl.util.Comparable; import ccl.util.Util; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Event; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.LayoutManager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.border.BevelBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.text.JTextComponent; import javax.swing.text.Keymap; import javax.swing.text.TextAction; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; /** * The panel for all the ToDo stuff. * * @author Chr. Clemens Lee * @version $Id: ToDoPanel.java,v 1.5 2000/09/19 18:20:55 clemens Exp clemens $ */ public class ToDoPanel extends JPanel implements TreeSelectionListener , ListSelectionListener , ChangeListener { private static final int STATE_STARTUP = 0; private static final int STATE_NORMAL = STATE_STARTUP + 1; private static final int STATE_INPUT = STATE_NORMAL + 1; private static final int STATE_TASK = STATE_INPUT + 1; private static String S_LIST_NAME = "ToDoListPane"; /** * Used by jim test. */ public static String S_TASK_NAME = "ToDoTaskPane"; private JButton _btnNewTask = null; private JButton _btnEditTask = null; private JButton _btnCutTask = null; private JButton _btnPasteTask = null; private JButton _btnNewProject = null; private JButton _btnEditProject = null; private JButton _btnCutProject = null; private JButton _btnPasteProject = null; private JButton _btnDependencies = null; private ToDoTask _pToDoTask = null; private CardLayout _pCardLayout = null; private JPanel _pnlToDoListOrTask = null; private JTextField _txtTask = null; private JTextArea _txtComment = null; private JTextField _txtStart = null; private JTextField _txtWorkStart = null; private JTextField _txtDeadline = null; private JTextField _txtFinished = null; private JTextField _txtClosed = null; private JComboBox _cmbPriority = null; private OKCancelPanel _ocpTask = null; private JList _lstToDo = null; private JTextArea _txtNotes = null; private ViewController _pViewController = null; private JSplitPane _pSplitPane = null; /** * We want to rely on the fact that always one item is * selected in the tree. Also, always at least one node * has to be present in the tree. */ private JTree _trToDos = null; private DefaultMutableTreeNode _tnRoot = null; private DefaultMutableTreeNode _ndLast = null; private JTextField _txtInput = null; private OKCancelPanel _pOKCancelPanel = null; private static final JDialog DLG_DUMMY = new JDialog(); private WindowAdapter _waOKCancelPanel = null; private WindowAdapter _waOKCancelTask = null; private boolean _bTaskVisible = false; private boolean _bInputVisible = false; private boolean _bInputVisibleBefore = false; private boolean _bEditProjectName = false; private int _state = STATE_STARTUP; private DefaultMutableTreeNode _tnCutProject = null; private ToDoTask _cutToDoTask = null; /** * This method en- and disables buttons etc. depending * on the current state of the application.<p> * * At appropriate places in the code this method has * to be invoked to keep the state uptodate. */ private void _setState( int state_ ) { if ( state_ == STATE_NORMAL ) { // Ensable all buttons except ok and cancel. // Ensable tree as well. boolean bTaskSelected = _lstToDo .getSelectedIndex() != -1; // one project should always be selected in tree _btnNewProject .setEnabled( true ); _btnEditProject .setEnabled( true ); _btnCutProject .setEnabled( true ); _btnPasteProject.setEnabled( _tnCutProject != null ); _btnNewTask .setEnabled( true ); _btnEditTask .setEnabled( bTaskSelected ); _btnCutTask .setEnabled( bTaskSelected ); _btnPasteTask .setEnabled( _cutToDoTask != null ); _trToDos .setEnabled( true ); } else if ( state_ == STATE_INPUT ) { Util.panicIf( _state != STATE_NORMAL ); // Disable all buttons except ok and cancel. // Disable tree as well. _btnNewProject .setEnabled( false ); _btnEditProject .setEnabled( false ); _btnCutProject .setEnabled( false ); _btnPasteProject.setEnabled( false ); _btnNewTask .setEnabled( false ); _btnEditTask .setEnabled( false ); _btnCutTask .setEnabled( false ); _btnPasteTask .setEnabled( false ); _trToDos .setEnabled( false ); } _state = state_; } private void _setInputVisible( boolean bVisible_ ) { if ( _bInputVisible == bVisible_ ) { // nothing to do return; } String sProjectName = _txtInput.getText(); if ( _bEditProjectName ) { sProjectName = _getSelectedProject().toString(); Util.debug( this , "_setInputVisible(..).sProjectName: " + sProjectName ); } _txtInput.setText ( sProjectName ); _txtInput.setVisible( bVisible_ ); _pOKCancelPanel.setVisible( bVisible_ ); _txtInput.invalidate(); _pOKCancelPanel.invalidate(); validate(); _pOKCancelPanel.validate(); if ( bVisible_ ) { _setState( STATE_INPUT ); _txtInput.requestFocus(); _waOKCancelPanel.windowOpened( null ); _bInputVisibleBefore = true; } else { _setState( STATE_NORMAL ); if ( _bInputVisibleBefore ) { _waOKCancelPanel.windowClosed( null ); _bInputVisibleBefore = false; } } if ( _trToDos != null && _txtInput != null ) { _trToDos.setEnabled( !bVisible_ ); _txtNotes.setEnabled( !bVisible_ ); } _bInputVisible = bVisible_; } private void _sort() { Util.debug( this, "_sort().START: " + (new Date()) ); // create comparator Comparable pComparable = new ToDoComparable(); /*Comparable() { public int compare( Object oFirst_, Object oSecond_ ) { ToDoTask tdFirst = (ToDoTask)oFirst_; ToDoTask tdSecond = (ToDoTask)oSecond_; //Util.debug( this, "compare(..).tdFirst: " + // tdFirst ); //Util.debug( this, "compare(..).tdSecond: " + //tdSecond ); int retVal = tdFirst.getFinished().compareTo( tdSecond.getFinished() ); if ( retVal == 0 ) { String sDeadline1 = tdFirst.getDeadline(); String sDeadline2 = tdSecond.getDeadline(); if ( Util.isEmpty( sDeadline1 ) ) { sDeadline1 = "Z"; } if ( Util.isEmpty( sDeadline2 ) ) { sDeadline2 = "Z"; } retVal = sDeadline1.compareTo( sDeadline2 ); } if ( retVal == 0 ) { retVal = tdFirst.getPriority().compareTo( tdSecond.getPriority() ); } if ( retVal == 0 ) { retVal = tdFirst.getStart().compareTo( tdSecond.getStart() ); } if ( retVal == 0 ) { retVal = tdFirst.getTitle().compareTo( tdSecond.getTitle() ); } //Util.debug( this, "compare(..).retVal: " + // retVal ); return retVal; } };*/ // get selected node DefaultMutableTreeNode pSelectedNode = (DefaultMutableTreeNode)_trToDos. getLastSelectedPathComponent(); if ( pSelectedNode == null ) { Util.debug( this, "_sort().NOTHING_SELECFTED" ); return; } Vector vToDoTasks = (Vector)pSelectedNode.getUserObject(); Util.debug( this, "_sort().vToDoTasks.size: " + vToDoTasks.size() ); // sort Util.sortFast( vToDoTasks, pComparable ); pSelectedNode.setUserObject( vToDoTasks ); // fill list model DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); /*Enumeration eToDoTasks = dlmToDo.elements(); Vector vToDoTasks = Util.sort( eToDoTasks, pComparable );*/ _lstToDo.clearSelection(); dlmToDo.removeAllElements(); Enumeration eToDoTasks = vToDoTasks.elements(); int index = 0; while( eToDoTasks.hasMoreElements() ) { index++; dlmToDo.addElement( "" + index + " " + eToDoTasks.nextElement().toString() ); } Util.debug( this, "_sort().END: " + (new Date()) ); } // create comparator public static class ToDoComparable implements Comparable { public int compare( Object oFirst_, Object oSecond_ ) { ToDoTask tdFirst = (ToDoTask)oFirst_; ToDoTask tdSecond = (ToDoTask)oSecond_; /*Util.debug( this, "compare(..).tdFirst: " + tdFirst ); Util.debug( this, "compare(..).tdSecond: " + tdSecond );*/ int retVal = tdFirst.getEnd().compareTo( tdSecond.getEnd() ); // for closed and finished, order is reverse if ( (!tdFirst.isOpen()) && (!tdSecond.isOpen()) ) { retVal *= -1; } if ( retVal == 0 ) { String sDeadline1 = tdFirst.getDeadline(); String sDeadline2 = tdSecond.getDeadline(); if ( Util.isEmpty( sDeadline1 ) ) { sDeadline1 = "z"; } if ( Util.isEmpty( sDeadline2 ) ) { sDeadline2 = "z"; } retVal = sDeadline1.compareTo( sDeadline2 ); } if ( retVal == 0 ) { retVal = tdFirst.getPriority().compareTo( tdSecond.getPriority() ); } if ( retVal == 0 ) { retVal = tdFirst.getStart().compareTo( tdSecond.getStart() ); } if ( retVal == 0 ) { retVal = tdFirst.getTitle().compareTo( tdSecond.getTitle() ); } /*Util.debug( this, "compare(..).retVal: " + retVal );*/ return retVal; } }; public static Comparable _pComparable = new ToDoComparable(); private void _insert( ToDoTask pToDoTask_ ) { Util.debug( this, "_insert().START: " + (new Date()) ); // get selected node DefaultMutableTreeNode pSelectedNode = (DefaultMutableTreeNode)_trToDos. getLastSelectedPathComponent(); if ( pSelectedNode == null ) { Util.debug( this, "_insert().NOTHING_SELECFTED" ); return; } Vector vToDoTasks = (Vector)pSelectedNode.getUserObject(); Util.debug( this, "_insert().vToDoTasks.size: " + vToDoTasks.size() ); // sort int selectedIndex = Util.insert( vToDoTasks, pToDoTask_, _pComparable ); pSelectedNode.setUserObject( vToDoTasks ); // fill list model DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); /*Enumeration eToDoTasks = dlmToDo.elements(); Vector vToDoTasks = Util.sort( eToDoTasks, pComparable );*/ /*_lstToDo.clearSelection(); dlmToDo.removeAllElements(); Enumeration eToDoTasks = vToDoTasks.elements(); int index = 0; while( eToDoTasks.hasMoreElements() ) { index++; dlmToDo.addElement( "" + index + " " + eToDoTasks.nextElement().toString() ); }*/ dlmToDo.insertElementAt( "" + (selectedIndex + 1) + " " + pToDoTask_.toString(), selectedIndex ); for( int index = 0; index < vToDoTasks.size(); index++ ) { dlmToDo.setElementAt( "" + (index + 1) + " " + vToDoTasks.elementAt( index ), index ); } _lstToDo.setSelectedIndex( selectedIndex ); Util.debug( this, "_insert().END: " + (new Date()) ); } private void _setTaskVisible( boolean bVisible_ ) { if ( _bTaskVisible == bVisible_ ) { // nothing to do return; } if ( bVisible_ ) { _setState( STATE_TASK ); _trToDos.setEnabled( false ); _pCardLayout.show( _pnlToDoListOrTask, S_TASK_NAME ); _txtStart.setText( _pToDoTask.getStart() );
_txtTask.setText( _pToDoTask.getTitle() ); _txtTask.requestFocus(); _txtComment.setText( _pToDoTask.getComment() ); _txtClosed.setText( _pToDoTask.getClosed() ); Util.debug( this, "_setTaskVisible(..)._pToDoTask.getFinished(): --->" + _pToDoTask.getFinished() + "<---" ); _txtFinished.setText( _pToDoTask.getFinished() ); _txtDeadline.setText( _pToDoTask.getDeadline() ); _cmbPriority.setSelectedItem( _pToDoTask.getPriority() ); //_btnNewTask .setEnabled( false ); //_btnEditTask.setEnabled( false ); //_btnCutTask .setEnabled( false ); } else { _setState( STATE_NORMAL ); _pCardLayout.show( _pnlToDoListOrTask, S_LIST_NAME ); //_btnNewTask .setEnabled( true ); //_btnEditTask.setEnabled( true ); //_btnCutTask .setEnabled( true ); //_trToDos.setEnabled( true ); } _bTaskVisible = bVisible_; } /** * Use this method to also get the project name, * just append a 'toString()' method.<p> * * You receive the original object, not a cloned object. */ private ToDoTaskVector _getSelectedProject() { DefaultMutableTreeNode pSelectedNode = (DefaultMutableTreeNode)_trToDos. getLastSelectedPathComponent(); if ( pSelectedNode == null ) { return null; } ToDoTaskVector vToDoTasks = (ToDoTaskVector)pSelectedNode.getUserObject(); return vToDoTasks; } private void _commitTask() { Util.debug( this, "_commitTask().START: " + (new Date()) ); _pViewController.setModified( true ); _pToDoTask.setStart( _txtStart.getText() ); _pToDoTask.setTitle( _txtTask.getText() ); _pToDoTask.setComment( _txtComment.getText() ); _pToDoTask.setClosed( _txtClosed.getText() ); _pToDoTask.setFinished( _txtFinished.getText() ); _pToDoTask.setDeadline( _txtDeadline.getText() ); _pToDoTask.setPriority( (ToDoTask.Priority)_cmbPriority.getSelectedItem() );
// is it a new task? ToDoTaskVector vToDoTaskVector = _getSelectedProject(); Util.panicIf ( vToDoTaskVector == null ); int index = vToDoTaskVector.indexOf( _pToDoTask ); if ( index != -1 ) { vToDoTaskVector.removeElementAt( index ); DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); dlmToDo.removeElementAt( index ); } _insert( _pToDoTask ); /*_sort(); int selectIndex = _getSelectedProject().indexOf( _pToDoTask ); _lstToDo.setSelectedIndex( selectIndex );*/ Util.debug( this, "_commitTask().END: " + (new Date()) ); }
private JPanel _createToDoTaskPane() { JPanel pnlToDoTask = new JPanel(); pnlToDoTask.setName( S_TASK_NAME ); pnlToDoTask.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); AutoGridBagLayout agblTask = new AutoGridBagLayout(); pnlToDoTask.setLayout( agblTask ); agblTask.setAnchor( GridBagConstraints.WEST ); // start date pnlToDoTask.add( new JLabel( "Start Date: " ) ); String sTimezonID = _pViewController.getInit(). getKeyValue( "TimezoneID" ); _txtStart = new DateField( sTimezonID ); _txtStart.setName( "StartText" ); //_txtStart.setBorder( SwingUtil.createCCLBorder() ); _txtStart.setMinimumSize( new Dimension( 100, 24 ) ); _txtStart.setPreferredSize( new Dimension( 100, 24 ) ); pnlToDoTask.add( _txtStart ); agblTask.endLine(); // work start pnlToDoTask.add( new JLabel( "Work start: " ) ); _txtWorkStart = new DateField( sTimezonID ); //_txtWorkStart.setBorder( SwingUtil.createCCLBorder() ); _txtWorkStart.setMinimumSize( new Dimension( 100, 24 ) ); _txtWorkStart.setPreferredSize( new Dimension( 100, 24 ) ); pnlToDoTask.add( _txtWorkStart ); agblTask.endLine(); // deadline pnlToDoTask.add( new JLabel( "Deadline: " ) ); _txtDeadline = new DateField( sTimezonID ); //_txtDeadline.setBorder( SwingUtil.createCCLBorder() ); _txtDeadline.setMinimumSize( new Dimension( 100, 24 ) ); _txtDeadline.setPreferredSize( new Dimension( 100, 24 ) ); agblTask.setFillVertical(); pnlToDoTask.add( _txtDeadline ); agblTask.setFillNone(); agblTask.endLine(); // title agblTask.setAnchor( GridBagConstraints.NORTHWEST ); pnlToDoTask.add( new JLabel( "Task: " ) ); _txtTask = new JTextField(); _txtTask.setName( "TitleText" ); _txtTask.setBorder( SwingUtil.createCCLBorder() ); _txtTask.setPreferredSize( new Dimension( 100, 24 ) ); agblTask.setFillHorizontal(); agblTask.setExpandHorizontal(); agblTask.setExtend( 2, 1 ); pnlToDoTask.add( _txtTask ); agblTask.setExtend( 1, 1 ); agblTask.setFillNone(); agblTask.setExpandNone(); agblTask.endLine(); // comment pnlToDoTask.add( new JLabel( "Comment: " ) ); _txtComment = new JTextArea(); _pViewController.addDateAction( _txtComment ); _txtComment.setName( "CommentText" ); _txtComment.setBackground( Color.white ); JScrollPane scpComment = new JScrollPane( _txtComment ); scpComment.setBorder( SwingUtil.createCCLBorder() ); agblTask.setFillBoth(); agblTask.setExpandBoth(); agblTask.setExtend( 2, 1 ); pnlToDoTask.add( scpComment ); agblTask.setExtend( 1, 1 ); agblTask.setFillNone(); agblTask.setExpandNone(); agblTask.endLine(); // priority pnlToDoTask.add( new JLabel( "Priority: " ) ); _cmbPriority = new JComboBox(); _cmbPriority.addItem( ToDoTask.A ); _cmbPriority.addItem( ToDoTask.B ); _cmbPriority.addItem( ToDoTask.C ); _cmbPriority.addItem( ToDoTask.D ); pnlToDoTask.add( _cmbPriority ); // dependencies _btnDependencies = new JButton( "Dependencies" ); //_btnDependencies.addActionListener( this ); agblTask.setAnchor( AutoGridBagLayout.EAST ); pnlToDoTask.add( _btnDependencies ); agblTask.setAnchor( AutoGridBagLayout.WEST ); agblTask.endLine(); // closed pnlToDoTask.add( new JLabel( "Closed: " ) ); _txtClosed = new DateField( sTimezonID ); //_txtClosed.setBorder( SwingUtil.createCCLBorder() ); _txtClosed.setMinimumSize( new Dimension( 100, 24 ) ); _txtClosed.setPreferredSize( new Dimension( 100, 24 ) ); agblTask.setFillVertical(); pnlToDoTask.add( _txtClosed ); agblTask.setFillNone(); agblTask.endLine(); // finished pnlToDoTask.add( new JLabel( "Finished: " ) ); _txtFinished = new DateField( sTimezonID ); _txtFinished.setName( "FinishedText" ); //_txtFinished.setBorder( SwingUtil.createCCLBorder() ); _txtFinished.setMinimumSize( new Dimension( 100, 24 ) ); _txtFinished.setPreferredSize( new Dimension( 100, 24 ) ); agblTask.setFillVertical(); pnlToDoTask.add( _txtFinished ); agblTask.setFillNone(); agblTask.endLine(); // OK or cancel pnlToDoTask.add( new JLabel( " " ) ); agblTask.endLine(); agblTask.skip(); agblTask.setAnchor( GridBagConstraints.EAST ); _ocpTask = new OKCancelPanel( DLG_DUMMY, 0 ); JButton btnOK = _ocpTask.getOKButton(); _pViewController.getRootPane().setDefaultButton( btnOK ); _waOKCancelTask = _pOKCancelPanel.getWindowAdapter(); DLG_DUMMY.removeWindowListener( _waOKCancelTask ); agblTask.setExtend( 2, 1 ); pnlToDoTask.add( _ocpTask ); agblTask.setExtend( 1, 1 ); btnOK.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { //String sInput = _txtInput.getText().trim(); _commitTask(); _setTaskVisible( false ); } } ); _ocpTask.getCancelButton().addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _setTaskVisible( false ); } } ); agblTask.endLine(); return pnlToDoTask; }
private String _getTimezoneID() { return _pViewController.getInit().getKeyValue( "TimezoneID" ); } public ToDoPanel( ViewController pViewController_ ) { super(); _pViewController = pViewController_; AutoGridBagLayout pAutoGridBagLayout = new AutoGridBagLayout( 2 ); setLayout( pAutoGridBagLayout ); setBorder( BorderFactory.createEmptyBorder( 7, 5, 5, 5 ) ); pAutoGridBagLayout.setAnchor( GridBagConstraints.WEST ); // buttons { _btnNewProject = new JButton( "New Project" ); _btnNewProject.setName( "AddButton" ); _btnNewProject.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _setInputVisible( true ); } } ); add( _btnNewProject ); _btnEditProject = new JButton( "Edit Project" ); _btnEditProject.setName( "EditButton" ); _btnEditProject.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _bEditProjectName = true; _setInputVisible( true ); } } ); add( _btnEditProject ); _btnCutProject = new JButton( "Cut Project" ); _btnCutProject.setName( "DeleteButton" ); _btnCutProject.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _setInputVisible( false ); deleteNote(); } } ); pAutoGridBagLayout.setFillHorizontal(); add( _btnCutProject ); _btnPasteProject = new JButton( "Paste Project" ); _btnPasteProject.setName( "PasteButton" ); _btnPasteProject.setEnabled( false ); _btnPasteProject.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _setInputVisible( false ); pasteProject(); } } ); add( _btnPasteProject ); } // input field { add( new JLabel( " " ) ); _txtInput = new JTextField(); _txtInput.setName( "InputText" ); _txtInput.setBorder( SwingUtil.createCCLBorder() ); pAutoGridBagLayout.setExpandHorizontal(); pAutoGridBagLayout.setFillHorizontal(); add( _txtInput ); pAutoGridBagLayout.setExpandNone(); pAutoGridBagLayout.setFillNone(); _pOKCancelPanel = new OKCancelPanel( DLG_DUMMY, 0 ); JButton btnOK = _pOKCancelPanel.getOKButton(); _pViewController.getRootPane().setDefaultButton( btnOK ); _waOKCancelPanel = _pOKCancelPanel.getWindowAdapter(); DLG_DUMMY.removeWindowListener( _waOKCancelPanel ); add( _pOKCancelPanel ); _pOKCancelPanel.getOKButton().addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { String sInput = _txtInput.getText().trim(); if ( _bEditProjectName ) { editProject( sInput ); _bEditProjectName = false; } else { createNewProject( sInput ); } _setInputVisible( false ); } } ); _pOKCancelPanel.getCancelButton().addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _setInputVisible( false ); } } ); pAutoGridBagLayout.endLine(); } // ToDoListPanel JScrollPane scpToDoList = null; { DefaultListModel dlmToDo = new DefaultListModel(); _lstToDo = new JList( dlmToDo ); _lstToDo.setName( "ToDoList" ); _lstToDo.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); _lstToDo.addListSelectionListener( this ); scpToDoList = new JScrollPane( _lstToDo ); scpToDoList.setBorder( SwingUtil.createCCLBorder() ); } // ToDoTaskPanel JPanel pnlToDoTask = _createToDoTaskPane(); // ToDoListOrTaskPanel { _pnlToDoListOrTask = new JPanel(); _pCardLayout = new CardLayout(); _pnlToDoListOrTask.setLayout( _pCardLayout ); _pnlToDoListOrTask.add( scpToDoList, S_LIST_NAME ); _pnlToDoListOrTask.add( pnlToDoTask, S_TASK_NAME ); } // todo buttons { pAutoGridBagLayout.setFillHorizontal(); _btnNewTask = new JButton( "New Task" ); _btnNewTask.setName( "NewTask" ); _btnNewTask.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _pToDoTask = new ToDoTask( _getTimezoneID() ); _setTaskVisible( true ); } } ); add( _btnNewTask ); _btnEditTask = new JButton( "Edit Task" ); _btnEditTask.setName( "EditTask" ); _btnEditTask.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { ToDoTaskVector vToDoTaskVector = _getSelectedProject(); int index = _lstToDo.getSelectedIndex(); if ( index == -1 ) { SwingUtil.showMessage( _pViewController, "No ToDo-task selected!" ); return; } _pToDoTask = (ToDoTask)vToDoTaskVector.elementAt( index ); _setTaskVisible( true ); } } ); add( _btnEditTask ); _btnCutTask = new JButton( "Cut Task" ); _btnCutTask.setName( "DeleteTask" ); _btnCutTask.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { cutTask(); } } ); add( _btnCutTask ); _btnPasteTask = new JButton( "Paste Task" ); _btnPasteTask.setName( "PasteTask" ); _btnPasteTask.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { pasteTask(); } } ); add( _btnPasteTask ); pAutoGridBagLayout.endLine(); } _txtNotes = new JTextArea(); JScrollPane scpText = new JScrollPane( _txtNotes ); scpText.setBorder( SwingUtil.createCCLBorder() ); DocumentListener pDocumentListener = new DocumentListener() { public void insertUpdate(DocumentEvent e) { if ( _bValueChanged ) { return; } _pViewController.stateChanged( null ); } public void removeUpdate(DocumentEvent e) { if ( _bValueChanged ) { return; } _pViewController.stateChanged( null ); } public void changedUpdate(DocumentEvent e) { if ( _bValueChanged ) { return; } _pViewController.stateChanged( null ); } }; _txtNotes.getDocument().addDocumentListener( pDocumentListener ); _txtNotes.setName( "_txtNotes" ); // set date insertion text action TextAction pDateTextAction = new DateTextAction(); Keymap kmOld = _txtNotes.getKeymap(); Keymap kmNew = _txtNotes.addKeymap( null, kmOld ); KeyStroke ksCtrlD = KeyStroke.getKeyStroke ( KeyEvent.VK_D, Event.CTRL_MASK ); kmNew.removeKeyStrokeBinding( ksCtrlD ); kmNew.addActionForKeyStroke ( ksCtrlD, pDateTextAction); _txtNotes.setKeymap( kmNew ); _tnRoot = createRootNode(); _trToDos = new JTree( _tnRoot ); _trToDos.setName( "ToDoTree" ); _trToDos.getSelectionModel(). setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); JScrollPane scpTree = new JScrollPane( _trToDos ); scpTree.setBorder( SwingUtil.createCCLBorder() ); _trToDos.addTreeSelectionListener( this ); _trToDos.setSelectionInterval( 0, 0 ); _pSplitPane = new JSplitPane(); _pSplitPane.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 0 ) ); _pSplitPane.setLeftComponent( scpTree ); _pSplitPane.setRightComponent( _pnlToDoListOrTask ); _pSplitPane.setDividerSize( 2 ); _pSplitPane.setDividerLocation( 300 ); Util.debug( this, "<init>(..).splitpane.size: " + _pSplitPane.getSize() ); Util.debug( this, "<init>(..).splitpane.dividerLocation: " + _pSplitPane.getDividerLocation() ); pAutoGridBagLayout.setExtend( 7, 1 ); pAutoGridBagLayout.setExpandBoth(); pAutoGridBagLayout.setFillBoth(); add( _pSplitPane ); // true necessary or set visible will have no effect _bInputVisible = true; _setInputVisible( false ); } public boolean isTaskVisible() { return _bTaskVisible; } public void deleteNote() { // might not be necessary, but can't hurt saveLastNode(); // get selected note TreePath pTreePath = _trToDos.getSelectionPath(); DefaultMutableTreeNode tnSelected = (DefaultMutableTreeNode) pTreePath.getLastPathComponent(); // don't delete top node DefaultMutableTreeNode tnParent = (DefaultMutableTreeNode)tnSelected.getParent(); if ( tnParent == null ) { SwingUtil.showMessage( _pViewController, "Sorry, you can't delete this project!" ); return; } // sure to delete this note? boolean bDelete = SwingUtil.isOKOrCancel ( _pViewController, "Is it OK to delete note\n'" + tnSelected.toString() + "'\nand all of its sub projects?" ); _tnCutProject = tnSelected; // delete it if ( bDelete ) { DefaultTreeModel pModel = (DefaultTreeModel)_trToDos.getModel(); TreePath tpParent = pTreePath.getParentPath(); pModel.removeNodeFromParent( tnSelected ); // make sure something is selected _trToDos.setSelectionPath( tpParent ); } _pViewController.setModified( true ); _btnPasteProject.setEnabled( true ); } public void pasteProject() { saveLastNode(); if ( _tnCutProject == null ) { // nothing to paste return; } // find parent TreePath pTreePath = _trToDos.getSelectionPath(); DefaultMutableTreeNode tnParent = (DefaultMutableTreeNode) pTreePath.getLastPathComponent(); // find new index Vector pVector = (Vector)_tnCutProject.getUserObject(); int newIndex = 0; Enumeration eChildren = tnParent.children(); while( eChildren.hasMoreElements() ) { DefaultMutableTreeNode tnNext = (DefaultMutableTreeNode) eChildren.nextElement(); if ( pVector.toString().compareTo ( tnNext.getUserObject().toString() ) < 0 ) { break; } newIndex++; } // insert DefaultMutableTreeNode tnNew = cloneProjectNode( _tnCutProject ); ((DefaultTreeModel)_trToDos.getModel()). insertNodeInto( tnNew, tnParent, newIndex ); _pViewController.setModified( true ); } public void createNewProject( String sKey_ ) { ToDoTaskVector vProject = new ToDoTaskVector( sKey_ ); // find parent TreePath pTreePath = _trToDos.getSelectionPath(); DefaultMutableTreeNode tnParent = (DefaultMutableTreeNode) pTreePath.getLastPathComponent(); // find new index int newIndex = 0; Enumeration eChildren = tnParent.children(); while( eChildren.hasMoreElements() ) { DefaultMutableTreeNode tnNext = (DefaultMutableTreeNode) eChildren.nextElement(); if ( vProject.toString().compareTo ( tnNext.getUserObject().toString() ) < 0 ) { break; } newIndex++; } // insert DefaultMutableTreeNode tnNew = new DefaultMutableTreeNode( vProject ); ((DefaultTreeModel)_trToDos.getModel()). insertNodeInto( tnNew, tnParent, newIndex ); _pViewController.setModified( true ); } public void editProject( String sKey_ ) { ToDoTaskVector vProject = _getSelectedProject(); vProject.setName( sKey_ ); // update tree view TreePath pTreePath = _trToDos.getSelectionPath(); DefaultMutableTreeNode tnSelected = (DefaultMutableTreeNode) pTreePath.getLastPathComponent(); ((DefaultTreeModel)_trToDos.getModel()) .valueForPathChanged( pTreePath , vProject ); _pViewController.setModified( true ); } public synchronized void saveLastNode() { /* // no real need to save this, // because we always work on vector directly and use list just for presentation. if ( _ndLast != null ) { Vector vProject = (Vector)_ndLast.getUserObject(); vProject.removeAllElements(); DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); Enumeration pEnumeration = dlmToDo.elements(); while( pEnumeration.hasMoreElements() ) { vProject.addElement( pEnumeration.nextElement() ); } }*/ } public void cutTask() { _pViewController.setModified( true ); ToDoTaskVector pToDoTaskVector = _getSelectedProject(); int index = _lstToDo.getSelectedIndex(); if ( index == -1 ) { Util.printlnErr( "Cut ToDo Task should not be enabled if no task is selected!" ); SwingUtil.showMessage( _pViewController, "No ToDo-task selected to cut!" ); return; } _cutToDoTask = (ToDoTask)((ToDoTask)pToDoTaskVector.elementAt( index )).clone(); pToDoTaskVector.removeElementAt( index ); DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); dlmToDo.removeElementAt( index ); while( index < pToDoTaskVector.size() ) { dlmToDo.setElementAt( "" + (index + 1) + " " + pToDoTaskVector.elementAt( index ), index ); index++; } _setState( STATE_NORMAL ); } public void pasteTask() { if ( _cutToDoTask == null ) { // nothing to paste Util.printlnErr( "Paste ToDo Task button should be disabled if nothing is to be pasted!" ); return; } _pViewController.setModified( true ); // insert task into project _insert( (ToDoTask)_cutToDoTask.clone() ); _setState( STATE_NORMAL ); } public void insertDate() { if ( !_txtNotes.isEnabled() ) { return; } SwingUtil.invokeLaterIfNecessary( new Runnable() { public void run() { Date pDate = new Date(); SimpleDateFormat pDateFormat = new SimpleDateFormat ("yyyy-MM-dd"); _txtNotes.replaceSelection( pDateFormat.format( pDate ) ); } } ); } public class DateTextAction extends TextAction { public DateTextAction() { super( "DateTextAction" ); } public void actionPerformed( ActionEvent pActionEvent_ ) { JTextComponent txtTarget = getTextComponent( pActionEvent_ ); if ( txtTarget.getName() != null && txtTarget.getName().equals( "_txtNotes" ) ) { insertDate(); } } } private boolean _bValueChanged = false; public synchronized void valueChanged( TreeSelectionEvent pTreeSelectionEvent_ ) { //saveLastNode(); DefaultMutableTreeNode pNode = (DefaultMutableTreeNode)_trToDos. getLastSelectedPathComponent(); if ( pNode == null ) { return; } // set list Vector vToDoTasks = (Vector)pNode.getUserObject(); DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); _lstToDo.clearSelection(); dlmToDo.removeAllElements(); Enumeration pEnumeration = vToDoTasks.elements(); int index = 0; while( pEnumeration.hasMoreElements() ) { index++; dlmToDo.addElement( "" + index + " " + pEnumeration.nextElement().toString() ); } //_sort(); _setState( STATE_NORMAL ); //_ndLast = pNode; } public void valueChanged( ListSelectionEvent e ) { _setState( STATE_NORMAL ); } public static final String getNotesName() { return getToDoName(); } public static final String getToDoName() { return "ToDo"; } public String getName() { return getToDoName(); } public DefaultMutableTreeNode getToDos() { saveLastNode(); return _tnRoot; } public void setNotes( DefaultMutableTreeNode tnRoot_ ) { _ndLast = null; _tnRoot = tnRoot_; _trToDos.setModel( new DefaultTreeModel( _tnRoot ) ); _trToDos.setSelectionInterval( 0, 0 ); } public static DefaultMutableTreeNode createRootNode() { DefaultMutableTreeNode tnRoot = new DefaultMutableTreeNode( new ToDoTaskVector( getToDoName() ) ); return tnRoot; } public static DefaultMutableTreeNode cloneProjectNode( DefaultMutableTreeNode tnProject_ ) { DefaultMutableTreeNode tnRetVal = null; if ( tnProject_ == null ) { return tnRetVal; } // clone vector ToDoTaskVector pToDoTaskVector = (ToDoTaskVector) (ToDoTaskVector)tnProject_.getUserObject(); ToDoTaskVector vDestination = new ToDoTaskVector( pToDoTaskVector.toString() ); Enumeration pEnumeration = pToDoTaskVector.elements(); while( pEnumeration.hasMoreElements() ) { vDestination.addElement( ((ToDoTask)pEnumeration.nextElement()).clone() ); } tnRetVal = new DefaultMutableTreeNode( vDestination ); // go through children for ( int child = 0; child < tnProject_.getChildCount(); child++ ) { DefaultMutableTreeNode tnNextChild = (DefaultMutableTreeNode)tnProject_.getChildAt( child ); DefaultMutableTreeNode tnNextClone = cloneProjectNode( tnNextChild ); // add child to return value tnRetVal.add( tnNextClone ); } return tnRetVal; } /*public Vector getToDoTasks() { DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); Vector vRetVal = new Vector(); Enumeration eToDoTasks = dlmToDo.elements(); while( eToDoTasks.hasMoreElements() ) { vRetVal.addElement( eToDoTasks.nextElement() ); } return vRetVal; }*/ public void setToDos( DefaultMutableTreeNode tnRoot_ ) { _tnRoot = tnRoot_; _trToDos.setModel( new DefaultTreeModel( _tnRoot ) ); _trToDos.setSelectionInterval( 0, 0 ); //_sort(); } public void setToDoTasks( ToDoTaskVector vToDoTasks_ ) { DefaultMutableTreeNode tnRoot = new DefaultMutableTreeNode( vToDoTasks_ ); _tnRoot = tnRoot; _trToDos.setModel( new DefaultTreeModel( _tnRoot ) ); _trToDos.setSelectionInterval( 0, 0 ); /*_lstToDo.clearSelection(); DefaultListModel dlmToDo = (DefaultListModel)_lstToDo.getModel(); dlmToDo.removeAllElements(); Enumeration eToDoTasks = vToDoTasks_.elements(); while( eToDoTasks.hasMoreElements() ) { dlmToDo.addElement( eToDoTasks.nextElement() ); } _sort();*/ } public ToDoTask getToDoTask() { return _pToDoTask; } public void stateChanged( ChangeEvent pChangeEvent_ ) { // must be tabbed pane JTabbedPane pTabbedPane = (JTabbedPane)pChangeEvent_.getSource(); if ( pTabbedPane.getSelectedIndex() == 1 ) { _pSplitPane.setDividerLocation( 300 ); pTabbedPane.removeChangeListener( this ); } } }
/* * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is JIM, a Java Information Manager. * (http://www.kclee.com/clemens/java/jim/). * * The Initial Developer of the Original Code is Chr. Clemens Lee. * Portions created by Chr. Clemens Lee are Copyright (C) 2000 * Chr. Clemens Lee. All Rights Reserved. * * Contributor(s): Chr. Clemens Lee <clemens@kclee.com> */ package jim; import ccl.util.Util; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Vector; /** * * @author Chr. Clemens Lee * @version $Id: ToDoTask.java,v 1.3 2000/01/24 23:48:30 clemens Exp clemens $ */ public class ToDoTask implements Cloneable { public static Priority A = new Priority( "A", 1.0f ); public static Priority B = new Priority( "B", 2.0f ); public static Priority C = new Priority( "C", 3.0f ); public static Priority D = new Priority( "D", 4.0f ); private String _sTitle = null; private String _sComment = null; private Date _dtStart = null; /** * Each task should have a distinct ID. In practice * we want to use the current time in millis. */ private long _lId = 0; /** * No need to work on it earlier. If null, work could or * should start immediately. */ private Date _dtWorkStart = null; /** * Should be finished at this day. If null, it should be * finished as soon as possible or when you find the time * (or take as much time as you want :-). */ private Date _dtDeadline = null; /** * Either _dtFinished or _dtClosed have to be set to either * make clear this job is done or will nether be done because * it is not necessary to finish. */ private Date _dtFinished = null; /** * Either _dtFinished or _dtClosed have to be set to either * make clear this job is done or will nether be done because * it is not necessary to finish. */ private Date _dtClosed = null; /** * 0 means, your life depends on it. Top priority is 1.0. * Lowest priority should be 3.0 - 5.0, haven't made up * my mind yet. */ private Priority _pPriority = null; private String _sTimezoneID = null;
static private long _lLastId = -1; static private synchronized long _getNextId() { long lNextId = new Date().getTime(); while( lNextId <= _lLastId ) { lNextId++; } _lLastId = lNextId; return lNextId; }
public ToDoTask() { super(); _dtStart = new Date(); _sTitle = ""; _sComment = ""; _pPriority = C; _sTimezoneID = null; _lId = _getNextId(); } public ToDoTask( String sTimezoneID_ ) { this(); _sTimezoneID = sTimezoneID_; } public void setPriority( Priority pPriority_ ) { _pPriority = pPriority_; } public void setPriority( String sPriority_ ) { if ( sPriority_ == null ) { _pPriority = C; } else if ( sPriority_.equals( "A" ) ) { _pPriority = A; } else if ( sPriority_.equals( "B" ) ) { _pPriority = B; } else if ( sPriority_.equals( "D" ) ) { _pPriority = D; } else { _pPriority = C; } } public Priority getPriority() { return _pPriority; } /** * The ToDo task is neither finished nor closed. */ public boolean isOpen() { return ((_dtFinished == null) && (_dtClosed == null)); } public String getStart() { return Util.getStandardDate( _dtStart ); } /** * For example: 1999-11-26 * * @return true on parse error, still current date is set. */ public boolean setStart( String sStart_ ) { try { String sYear = sStart_.substring( 0, 4 ); String sMonth = sStart_.substring( 5, 7 ); String sDay = sStart_.substring( 8, 10 ); int year = Util.atoi( sYear ); int month = Util.atoi( sMonth ) - 1; int day = Util.atoi( sDay ); Util.debug( this, "setStart(..).year: " + year ); Util.debug( this, "setStart(..).month: " + month ); Util.debug( this, "setStart(..).day: " + day ); Calendar pCalendar = new GregorianCalendar(); pCalendar.setTime( _dtStart ); pCalendar.set( Calendar.YEAR, year ); pCalendar.set( Calendar.MONTH, month ); pCalendar.set( Calendar.DAY_OF_MONTH, day ); _dtStart.setTime( pCalendar.getTime().getTime() ); Util.debug( this, "setStart(..)._dtStart: " + _dtStart ); } catch( Exception pException ) { Util.debug( this, "setStart(..).pException: " + pException ); _dtStart = new Date(); return true; } Util.panicIf( !sStart_.equals( getStart() ), "_dtStart: " + _dtStart ); return false; } public void setTitle( String sTitle_ ) { _sTitle = sTitle_; } /** * Returns 0 for green, 1 for yellow, 2 for red, * 3 for finished, 4 for closed. */ public int getStatus() { if ( isFinished() ) { return 3; } if ( isClosed() ) { return 4; } if ( !Util.isEmpty( getDeadline() ) ) { String sToday = Util.getDate ( Util.getCalendar( _sTimezoneID ) ); if ( sToday.compareTo( getDeadline() ) <= 0 ) { return 1; } else { return 2; } } return 0; } private static final String[] AS_STATUS_HTML = { "<font color=\"00FF00\">Green</font>", "<font color=\"00FFFF\">Yellow</font>", "<font color=\"FF0000\">Red</font>", "<font color=\"0000FF\">Done</font>", "<font color=\"000000\">Closed</font>" }; public String getStatusHTML() { return AS_STATUS_HTML[ getStatus() ]; } public String getDate() { int status = getStatus(); if ( status == 3 ) { return getFinished(); } else if ( status == 4 ) { return getClosed(); } else if ( status == 0 ) { return getStart(); } // yellow or red return getDeadline(); } public String toString() { String sRetVal = getPriority() + " "; if ( isFinished() ) { sRetVal += "+ " + getFinished() + " "; } if ( isClosed() ) { sRetVal += "- " + getClosed() + " "; } if ( isOpen() ) { if ( !Util.isEmpty( getDeadline() ) ) { String sToday = Util.getStandardDate( new Date() ); if ( sToday.compareTo( getDeadline() ) <= 0 ) { sRetVal += "Y " + getDeadline() + " "; } else { sRetVal += "R " + getDeadline() + " "; } } else { sRetVal += "G " + getStart() + " "; } } sRetVal += getTitle(); return sRetVal; } public String getTitle() { return _sTitle; } public String getComment() { return _sComment; } public void setComment( String sComment_ ) { Util.panicIf( sComment_ == null ); _sComment = sComment_; } public boolean isFinished() { if ( Util.isEmpty( getFinished() ) ) { return false; } return true; } public boolean isClosed() { return !Util.isEmpty( getClosed() ); } public void setClosed( String sClosed_ ) { _dtClosed = Util.stringToDate( sClosed_ ); } public void setFinished( String sFinished_ ) { _dtFinished = Util.stringToDate( sFinished_ ); } public void setDeadline( String sDeadline_ ) { _dtDeadline = Util.stringToDate( sDeadline_ ); } /** * @return "" or well defined string. */ public String getDeadline() { String sDeadline = ""; if ( _dtDeadline != null ) { sDeadline = Util.getStandardDate( _dtDeadline ); } return sDeadline; } /** * @return "" or well defined string. */ public String getClosed() { String sClosed = ""; if ( _dtClosed != null ) { sClosed = Util.getStandardDate( _dtClosed ); } return sClosed; } /** * @return "" or well defined string. */ public String getFinished() { String sFinished = ""; if ( _dtFinished != null ) { sFinished = Util.getStandardDate( _dtFinished ); } return sFinished; } /** * End date is either closed date, finished date, or null. */ public String getEnd() { String sRetVal = getClosed(); if ( Util.isEmpty( sRetVal ) ) { sRetVal = getFinished(); } return sRetVal; } public long getId() { return _lId; }
public void setId( long lId_ ) { _lId = lId_; }
/** * Warning, this returns only true if two tasks really are * the same, not if they have equal values. */ public boolean equals( Object oToDoTask ) { return( this == oToDoTask ); } public Object clone() { ToDoTask pToDoTask = new ToDoTask( _sTimezoneID ); pToDoTask._sTitle = this._sTitle; pToDoTask._sComment = this._sComment; pToDoTask._dtStart = null; if ( this._dtStart != null ) { pToDoTask._dtStart = new Date(); pToDoTask._dtStart.setTime( this._dtStart.getTime() ); } pToDoTask._dtWorkStart = null; if ( this._dtWorkStart != null ) { pToDoTask._dtWorkStart = new Date(); pToDoTask._dtWorkStart.setTime( this._dtWorkStart.getTime() ); } pToDoTask._dtDeadline = null; if ( this._dtDeadline != null ) { pToDoTask._dtDeadline = new Date(); pToDoTask._dtDeadline.setTime( this._dtDeadline.getTime() ); } pToDoTask._dtFinished = null; if ( this._dtFinished != null ) { pToDoTask._dtFinished = new Date(); pToDoTask._dtFinished.setTime( this._dtFinished.getTime() ); } pToDoTask._dtClosed = null; if ( this._dtClosed != null ) { pToDoTask._dtClosed = new Date(); pToDoTask._dtClosed.setTime( this._dtClosed.getTime() ); } pToDoTask._pPriority = this._pPriority; pToDoTask._lId = this._lId; return pToDoTask; } public static class Priority extends Object { private String _sName = null; private String _sComment = null; private float _fPriority = 3.0f; private Priority( String sName_, float fPriority_ ) { super(); _sName = sName_; _fPriority = fPriority_; } public String toString() { return _sName; } public int compareTo( Priority pPriority_ ) { return toString().compareTo( pPriority_.toString() ); } } }
Therefore we need to remember the highest id which has been given to any ToDoTask object. This will be a static variable in ToDoTask:
static private long _lLastId = 0;
static private synchronized long _getNextId() { long lNextId = _lLastId + 1; _lLastId = lNextId; return lNextId; }
public void setId( long lId_ ) { _lId = lId_; if ( _lId > _lLastId ) { _lLastId = _lId; } } static public void resetLastId() { _lLastId = 0; }
ToDoTask.resetLastId();
Let's have a quick gui layout overview for the ToDoPanel:
*-------------------------------------------------------------* | | | | | | | Start date: | ********** | | Id: | XXXXXX | | | | | | | | Work start: | ********** | | | | | | | | | | | Deadline: | ********** | | | | | | | | | | | Task: | ********************************************* | | | | | | | Comment: | ********************************************* | | | ********************************************* | | | ********************************************* | | | ********************************************* | | | ********************************************* | | | ********************************************* | | | | | | | | Priority: | ** | | | | | | | | | | | Closed: | ********** | Depends on: | ****************** | | | | | | | | Finished: | ********** | Blocks: | ****************** | | | | | | | | | | | | | | | | | | | | | | < OK > <Cancel> | | | | | | | *-------------------------------------------------------------*This results in the following code in the ToDoPanel constructor:
private JTextField _txtDependsOn = null; private JTextField _txtBlocks = null; private JLabel _lblId = null; private JPanel _createToDoTaskPane() { String sTimezonID = _pViewController.getInit(). getKeyValue( "TimezoneID" ); _txtStart = new DateField( sTimezonID ); _txtStart.setName ( "StartText" ); _txtStart.setMinimumSize ( new Dimension( 100, 24 ) ); _txtStart.setPreferredSize( new Dimension( 100, 24 ) ); _lblId = new JLabel( "XXXXXX" ); _txtWorkStart = new DateField( sTimezonID ); _txtWorkStart.setMinimumSize ( new Dimension( 100, 24 ) ); _txtWorkStart.setPreferredSize( new Dimension( 100, 24 ) ); _txtDeadline = new DateField( sTimezonID ); _txtDeadline.setMinimumSize ( new Dimension( 100, 24 ) ); _txtDeadline.setPreferredSize( new Dimension( 100, 24 ) ); _txtTask = new JTextField(); _txtTask.setName ( "TitleText" ); _txtTask.setBorder ( SwingUtil.createCCLBorder() ); _txtTask.setPreferredSize( new Dimension( 100, 24 ) ); _txtComment = new JTextArea(); _txtComment.setName( "CommentText" ); _txtComment.setBackground( Color.white ); JScrollPane scpComment = new JScrollPane( _txtComment ); scpComment.setBorder( SwingUtil.createCCLBorder() ); _pViewController.addDateAction( _txtComment ); _cmbPriority = new JComboBox(); _cmbPriority.addItem( ToDoTask.A ); _cmbPriority.addItem( ToDoTask.B ); _cmbPriority.addItem( ToDoTask.C ); _cmbPriority.addItem( ToDoTask.D ); _txtClosed = new DateField( sTimezonID ); _txtClosed.setMinimumSize ( new Dimension( 100, 24 ) ); _txtClosed.setPreferredSize( new Dimension( 100, 24 ) ); _txtFinished = new DateField( sTimezonID ); _txtFinished.setName ( "FinishedText" ); _txtFinished.setMinimumSize ( new Dimension( 100, 24 ) ); _txtFinished.setPreferredSize( new Dimension( 100, 24 ) ); _txtDependsOn = new JTextField(); _txtBlocks = new JTextField(); _txtDependsOn.setBorder( SwingUtil.createCCLBorder() ); _txtBlocks .setBorder( SwingUtil.createCCLBorder() ); _ocpTask = new OKCancelPanel( DLG_DUMMY, 0 ); JButton btnOK = _ocpTask.getOKButton(); _pViewController.getRootPane().setDefaultButton( btnOK ); _waOKCancelTask = _pOKCancelPanel.getWindowAdapter(); DLG_DUMMY.removeWindowListener( _waOKCancelTask ); btnOK.addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _commitTask(); _setTaskVisible( false ); } } ); _ocpTask.getCancelButton().addActionListener ( new ActionListener() { public void actionPerformed( ActionEvent pActionEvent_ ) { _setTaskVisible( false ); } } ); JPanel pnlToDoTask = new JPanel(); pnlToDoTask.setName( S_TASK_NAME ); pnlToDoTask.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); AutoGridBagLayout agblTask = new AutoGridBagLayout(); agblTask.setLayoutOn ( pnlToDoTask ); agblTask.setAnchor ( AutoGridBagLayout.WEST ); // start date agblTask.add ( pnlToDoTask , new JLabel( "Start date: " ) ); agblTask.add ( pnlToDoTask , _txtStart ); // Id agblTask.skip (); agblTask.setAnchor ( AutoGridBagLayout.EAST ); agblTask.setExpandHorizontal(); agblTask.add ( pnlToDoTask , new JLabel( "Id: " ) ); agblTask.setExpandNone (); agblTask.add ( pnlToDoTask, _lblId ); agblTask.setAnchor ( AutoGridBagLayout.WEST ); agblTask.endLine (); // work start agblTask.add ( pnlToDoTask , new JLabel( "Work start: " ) ); agblTask.add ( pnlToDoTask, _txtWorkStart ); agblTask.endLine (); // deadline agblTask.add ( pnlToDoTask , new JLabel( "Deadline: " ) ); agblTask.setFillVertical (); agblTask.add ( pnlToDoTask, _txtDeadline ); agblTask.setFillNone (); agblTask.endLine (); // title agblTask.add ( pnlToDoTask , new JLabel( "Task: " ) ); agblTask.setFillHorizontal (); agblTask.setExpandHorizontal(); agblTask.setExtend ( 4, 1 ); agblTask.add ( pnlToDoTask, _txtTask ); agblTask.setExtend ( 1, 1 ); agblTask.setFillNone (); agblTask.setExpandNone (); agblTask.endLine (); // comment agblTask.setAnchor ( AutoGridBagLayout.NORTHWEST ); agblTask.add ( pnlToDoTask , new JLabel( "Comment: " ) ); agblTask.setAnchor ( AutoGridBagLayout.WEST ); agblTask.setFillBoth (); agblTask.setExpandBoth (); agblTask.setExtend ( 4, 1 ); agblTask.add ( pnlToDoTask, scpComment ); agblTask.setExtend ( 1, 1 ); agblTask.setFillNone (); agblTask.setExpandNone (); agblTask.endLine (); // priority agblTask.add ( pnlToDoTask , new JLabel( "Priority: " ) ); agblTask.add ( pnlToDoTask, _cmbPriority ); agblTask.endLine(); // closed agblTask.add ( pnlToDoTask , new JLabel( "Closed: " ) ); agblTask.setFillVertical (); agblTask.add ( pnlToDoTask, _txtClosed ); agblTask.setFillNone (); // Depends on agblTask.add ( pnlToDoTask , new JLabel( " Depends on: " ) ); agblTask.setFillBoth (); agblTask.setExpandHorizontal(); agblTask.setExtend ( 2, 1 ); agblTask.add ( pnlToDoTask, _txtDependsOn ); agblTask.setExtend ( 1, 1 ); agblTask.setExpandNone (); agblTask.setFillNone (); agblTask.endLine (); // finished agblTask.add ( pnlToDoTask , new JLabel( "Finished: " ) ); agblTask.setFillVertical (); agblTask.add ( pnlToDoTask, _txtFinished ); agblTask.setFillNone (); // Blocks agblTask.add ( pnlToDoTask , new JLabel( " Blocks: " ) ); agblTask.setFillBoth (); agblTask.setExpandHorizontal(); agblTask.setExtend ( 2, 1 ); agblTask.add ( pnlToDoTask, _txtBlocks ); agblTask.setExtend ( 1, 1 ); agblTask.setExpandNone (); agblTask.setFillNone (); agblTask.endLine (); // OK or cancel agblTask.add ( pnlToDoTask, new JLabel( " " ) ); agblTask.endLine (); agblTask.setAnchor ( GridBagConstraints.EAST ); agblTask.setExtend ( 5, 1 ); pnlToDoTask.add ( _ocpTask ); agblTask.setExtend ( 1, 1 ); agblTask.endLine (); return pnlToDoTask; }
_lblId.setText( Util.ltoa( _pToDoTask.getId() ) );
At some point we need to convert a vector of strings to a comma separated string and vice versa. These two routines could either go into the ToDoPanel or ToDoTask class. I vote for the ToDoTask class.
In the '_setTaskVisible' method the dependencies and blocks are set.
_txtDependsOn.setText( _pToDoTask.getDependenciesString() ); _txtBlocks .setText( _pToDoTask.getBlocksString () );
_pToDoTask.setDependencies( _txtDependsOn.getText() ); _pToDoTask.setBlocks ( _txtBlocks .getText() );
/** * This vector contains id strings to other tasks which * have to be finished before this one can be finished. */ private Vector _vDependencies = new Vector(); /** * This vector contains id strings to other tasks which * can't be finished unless this task is finished. */ private Vector _vBlocks = new Vector(); public void setDependencies( Vector vDependencies_ ) { _vDependencies = (Vector)vDependencies_.clone(); } public Vector getDependencies() { return (Vector)_vDependencies.clone(); } public void setBlocks( Vector vBlocks_ ) { _vBlocks = (Vector)vBlocks_.clone(); } public Vector getBlocks() { return (Vector)_vBlocks.clone(); } public void setDependencies( String sDependencies_ ) { _vDependencies = Util.stringToLines( Util.replace( sDependencies_, " ", "" ), ',' ); } public void setBlocks( String sBlocks_ ) { _vBlocks = Util.stringToLines( Util.replace( sBlocks_, " ", "" ), ',' ); } public String getDependenciesString() { return Util.concat( _vDependencies, ", " ); } public String getBlocksString() { return Util.concat( _vBlocks, ", " ); }
For saving it is time to dump the dom and just print out xml strings into a file. Much simpler and no memory problems. I don't know why I got the other idea in the first place. Well, it maybe was easier to convert java text to xml text.
Inside the loop in '_createTODOProjectElement' we add the dependencies and blocks vector. Do we create a parent node first for them are do we add a variable number of <DEPENDSON> and <BLOCKS> nodes directly into the <TODO> node? Having a parent node might add more complexity to id, so we go without it.
Enumeration eDependencies = pToDoTask.getDependencies().elements(); while( eDependencies.hasMoreElements() ) { String sDependsOn = (String)eDependencies.nextElement(); ElementNode enDependsOn = (ElementNode)pXmlDocument_.createElement( "DEPENDSON" ); enToDo.appendChild( enDependsOn ); pText = pXmlDocument_.createTextNode( sDependsOn ); enDependsOn.appendChild( pText ); } Enumeration eBlocks = pToDoTask.getBlocks().elements(); while( eBlocks.hasMoreElements() ) { String sBlocks = (String)eBlocks.nextElement(); ElementNode enBlocks = (ElementNode)pXmlDocument_.createElement( "BLOCKS" ); enToDo.appendChild( enBlocks ); pText = pXmlDocument_.createTextNode( sBlocks ); enBlocks.appendChild( pText ); }
We will need a method in ToDoTask to add a single dependson or block id.
public void addDependency( String sId_ ) { _vDependencies.addElement( sId_ ); } public void addBlock( String sId_ ) { _vBlocks.addElement( sId_ ); }
When adding a new task and then cancelling it the
largest id still gets increased.
3 ViewController
jim.ViewController
is the central gui and infrastructure class.