001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.filechooser;
017    
018    import java.awt.event.ActionEvent;
019    import java.awt.event.ActionListener;
020    import java.io.File;
021    
022    import javax.swing.JButton;
023    import javax.swing.JComponent;
024    import javax.swing.JFileChooser;
025    import javax.swing.JLabel;
026    import javax.swing.JPanel;
027    import javax.swing.JTextField;
028    import javax.swing.SwingUtilities;
029    
030    import org.springframework.binding.form.ValidatingFormModel;
031    import org.springframework.binding.validation.ValidationListener;
032    import org.springframework.richclient.factory.AbstractControlFactory;
033    import org.springframework.richclient.form.binding.swing.SwingBindingFactory;
034    
035    import com.jgoodies.forms.layout.CellConstraints;
036    import com.jgoodies.forms.layout.FormLayout;
037    
038    /**
039     * A combo box that allows you to type and/or select files, as well as click a
040     * Browse button to navigate to the file you wish to work with.
041     * 
042     * @author Keith Donald
043     */
044    public class FileChooserComboBox extends AbstractControlFactory {
045    
046        private JFileChooser fileChooser;
047    
048        private String fileChooserLabel = "fileChooserLabel";
049    
050        private JTextField fileNameField;
051    
052        private JButton browseButton;
053    
054        private File startDirectory;
055    
056        private ValidatingFormModel formModel;
057    
058        private String formProperty;
059    
060        public FileChooserComboBox() {
061        }
062    
063        public FileChooserComboBox(ValidatingFormModel formModel, String formProperty) {
064            this.formModel = formModel;
065            this.formProperty = formProperty;
066        }
067    
068        public void addValidationListener(ValidationListener listener) {
069            formModel.getValidationResults().addValidationListener(listener);
070        }
071    
072        public void removeValidationListener(ValidationListener listener) {
073            formModel.getValidationResults().removeValidationListener(listener);
074        }
075    
076        public void setLabelMessageCode(String labelKey) {
077            this.fileChooserLabel = labelKey;
078        }
079    
080        public void setStartDirectory(File file) {
081            this.startDirectory = file;
082        }
083    
084        public File getStartDirectory() {
085            if (startDirectory != null) 
086                return startDirectory;
087    
088            return getSelectedFile();
089        }
090    
091        public File getSelectedFile() {
092            String filePath = (String)formModel.getValueModel(formProperty).getValue();
093            return (filePath == null) ? null : new File( filePath );
094        }
095    
096        public void setEnabled(boolean enabled) {
097            fileNameField.setEnabled(enabled);
098            browseButton.setEnabled(false);
099        }
100    
101        protected JComponent createControl() {
102            this.fileNameField = (JTextField)new SwingBindingFactory(formModel).createBinding(JTextField.class,
103                    formProperty).getControl();
104            JLabel fileToProcess = getComponentFactory().createLabelFor(fileChooserLabel, fileNameField);
105            this.browseButton = getComponentFactory().createButton("button.browse");
106            BrowseActionHandler browseActionHandler = new BrowseActionHandler();
107            browseButton.addActionListener(browseActionHandler);
108            FormLayout layout = new FormLayout("pref:grow, 6dlu:none, min", "pref, 3dlu, pref");
109            JPanel panel = new JPanel(layout);
110            CellConstraints cc = new CellConstraints();
111            panel.add(fileToProcess, cc.xyw(1, 1, 3));
112            panel.add(fileNameField, cc.xy(1, 3));
113            panel.add(browseButton, cc.xy(3, 3));
114            return panel;
115        }
116        
117        private class BrowseActionHandler implements ActionListener {
118            public void actionPerformed(ActionEvent event) {
119                if (fileChooser == null) {
120                    fileChooser = new JFileChooser(getStartDirectory());
121                }
122                else {
123                    fileChooser.setCurrentDirectory(getStartDirectory());
124                }
125                int returnVal = fileChooser.showOpenDialog(SwingUtilities.getWindowAncestor(browseButton));
126                if (returnVal == JFileChooser.APPROVE_OPTION) {
127                    File selectedFile = fileChooser.getSelectedFile();
128                    fileNameField.setText(selectedFile.getAbsolutePath());
129                    if (selectedFile.isDirectory()) {
130                        setStartDirectory(selectedFile);
131                    }
132                    else {
133                        setStartDirectory(selectedFile.getParentFile());
134                    }
135                }
136            }
137        }
138    }