001/**
002 *  '$Author: crawl $'
003 *  '$Date: 2015-11-02 18:37:28 +0000 (Mon, 02 Nov 2015) $'
004 *  '$Revision: 34179 $'
005 *
006 *  For Details:
007 *  http://www.kepler-project.org
008 *
009 *  Copyright (c) 2009-2010 The Regents of the
010 *  University of California. All rights reserved. Permission is hereby granted,
011 *  without written agreement and without license or royalty fees, to use, copy,
012 *  modify, and distribute this software and its documentation for any purpose,
013 *  provided that the above copyright notice and the following two paragraphs
014 *  appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF
015 *  CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
016 *  OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
017 *  DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
018 *  POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY
019 *  DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
020 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
021 *  SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022 *  CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023 *  ENHANCEMENTS, OR MODIFICATIONS.
024 */
025
026package org.kepler.workflowrunmanager.gui;
027
028import java.awt.Component;
029import java.awt.KeyEventDispatcher;
030import java.awt.KeyboardFocusManager;
031import java.awt.event.KeyEvent;
032
033import javax.swing.DefaultCellEditor;
034import javax.swing.InputVerifier;
035import javax.swing.JComponent;
036import javax.swing.JTable;
037import javax.swing.JTextField;
038
039import org.kepler.workflowrunmanager.DurationQueryParse;
040import org.kepler.workflowrunmanager.WRMDefaults;
041
042public class DurationCellEditor extends DefaultCellEditor {
043
044        private final JTextField tf;
045        private DurationVerifier durationVerifier = new DurationVerifier();
046
047        private WRMDefaults wrmdefaults = WRMDefaults.getInstance();
048        
049        private KeyEventDispatcherClass dispatcher = null;
050
051        class KeyEventDispatcherClass implements KeyEventDispatcher{
052                @Override
053        public boolean dispatchKeyEvent(KeyEvent e) {
054                        // TODO find out why we get two tabs here:
055            if (e.getKeyCode() == KeyEvent.VK_TAB ||
056                    e.getKeyCode() == KeyEvent.VK_ESCAPE) {
057                                stopCellEditing();
058                        }
059                        return false;
060                }
061        }
062
063        public DurationCellEditor(JTextField jTextField) {
064                super(jTextField);
065                // tf = jTextField;
066                tf = (JTextField) getComponent();
067
068                tf.setInputVerifier(durationVerifier);
069
070                dispatcher =  new KeyEventDispatcherClass();
071                
072                // TODO likely be able to remove this when focus stuff reworked:
073                KeyboardFocusManager.getCurrentKeyboardFocusManager()
074                                .addKeyEventDispatcher(dispatcher);
075
076        }
077
078        @Override
079    public Component getTableCellEditorComponent(JTable table, Object value,
080                        boolean isSelected, int row, int column) {
081                tf.setText(value.toString());
082                return tf;
083        }
084
085        @Override
086    public Object getCellEditorValue() {
087                return tf.getText();
088        }
089
090        /**
091         * Forwards the message from the <code>CellEditor</code> to the
092         * <code>delegate</code>.
093         * 
094         * @see EditorDelegate#stopCellEditing
095         */
096        @Override
097    public boolean stopCellEditing() {
098
099                // if text invalid, just reset to default - friendlier than trapping
100                // user in the cell.
101                if (!durationVerifier.verify(tf)) {
102                        tf.setText(wrmdefaults.getDefault(WRMDefaults.DURATION));
103                } else {
104                        DurationQueryParse durationQueryParse = new DurationQueryParse(tf
105                                        .getText());
106                        String durationText = durationQueryParse.getCompleteText();
107                        if (isValid(durationText)){
108                                tf.setText(durationQueryParse.getCompleteText());
109                        }
110                }
111
112                return super.stopCellEditing();
113        }
114
115        // sanity check - verify strings we try to set in code too.
116        private boolean isValid(String test) {
117                JTextField testField = new JTextField(test);
118                if (!durationVerifier.verify(testField)) {
119                        System.out.println("ERROR trying to set duration text");
120                        return false;
121                } else {
122                        return true;
123                }
124        }
125
126        static class DurationVerifier extends InputVerifier {
127
128                @Override
129        public boolean verify(JComponent input) {
130                        JTextField tf = (JTextField) input;
131
132                        DurationQueryParse durationQueryParse = new DurationQueryParse(tf
133                                        .getText());
134                        if (durationQueryParse.isValid()) {
135                                return true;
136                        }
137                        return false;
138                }
139
140                // not necessary but probably good to have.
141                @Override
142        public boolean shouldYieldFocus(JComponent input) {
143                        boolean inputOK = verify(input);
144
145                        if (inputOK) {
146                                return true;
147                        } else {
148                                return false;
149                        }
150                }
151
152        }
153        
154        public void dispose(){
155                if (dispatcher != null){
156                        KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
157                }
158        }
159
160}