1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: PathField.java 2104 2011-03-07 18:54:34Z dmsmith $
21   */
22  package org.crosswire.common.config.swing;
23  
24  import java.awt.BorderLayout;
25  import java.awt.FlowLayout;
26  import java.awt.Font;
27  import java.io.File;
28  import java.io.IOException;
29  import java.io.ObjectInputStream;
30  
31  import javax.swing.BorderFactory;
32  import javax.swing.DefaultComboBoxModel;
33  import javax.swing.JButton;
34  import javax.swing.JComponent;
35  import javax.swing.JFileChooser;
36  import javax.swing.JList;
37  import javax.swing.JPanel;
38  import javax.swing.JScrollPane;
39  import javax.swing.ListSelectionModel;
40  
41  import org.crosswire.common.config.Choice;
42  import org.crosswire.common.swing.ActionFactory;
43  import org.crosswire.common.swing.CWScrollPane;
44  import org.crosswire.common.swing.CWMsg;
45  import org.crosswire.common.util.Convert;
46  
47  /**
48   * A StringArrayField allows editing of an array of Strings in a JList. It
49   * allows the user to specify additional classes that extend the functionality
50   * of the program.
51   * 
52   * @see gnu.lgpl.License for license details.<br>
53   *      The copyright to this program is held by it's authors.
54   * @author Joe Walker [joe at eireneh dot com]
55   */
56  public class PathField extends JPanel implements Field {
57      /**
58       * Create a PropertyHashtableField for editing String arrays.
59       */
60      public PathField() {
61          model = new DefaultComboBoxModel();
62          list = new JList(model);
63  
64          actions = new ActionFactory(this);
65  
66          JPanel buttons = new JPanel(new FlowLayout());
67  
68          list.setFont(new Font("Monospaced", Font.PLAIN, 12));
69          list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
70          // list.setPreferredScrollableViewportSize(new Dimension(30, 100));
71  
72          JScrollPane scroll = new CWScrollPane(list);
73  
74          // TRANSLATOR: This is the text on an "Add" button.
75          buttons.add(new JButton(actions.addAction("Add", CWMsg.gettext("Add"))));
76          // TRANSLATOR: This is the text on a "Remove" button.
77          buttons.add(new JButton(actions.addAction("Remove", CWMsg.gettext("Remove"))));
78          // TRANSLATOR: This is the text on an "Update" button for a path
79          // Note: The " (path)" is not to be translated.
80          // It is here because some languages translate "Update" differently depending on context.
81          buttons.add(new JButton(actions.addAction("Update", CWMsg.gettext("Update (path)"))));
82  
83          setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
84  
85          setLayout(new BorderLayout());
86          add(scroll, BorderLayout.CENTER);
87          add(buttons, BorderLayout.PAGE_END);
88      }
89  
90      /*
91       * (non-Javadoc)
92       * 
93       * @see
94       * org.crosswire.common.config.swing.Field#setChoice(org.crosswire.common
95       * .config.Choice)
96       */
97      public void setChoice(Choice param) {
98      }
99  
100     /*
101      * (non-Javadoc)
102      * 
103      * @see org.crosswire.common.config.swing.Field#getValue()
104      */
105     public String getValue() {
106         return Convert.stringArray2String(getArray(), File.pathSeparator);
107     }
108 
109     /**
110      * Return the actual Hashtable being edited
111      * 
112      * @return The current value
113      */
114     public String[] getArray() {
115         String[] retcode = new String[model.getSize()];
116         for (int i = 0; i < retcode.length; i++) {
117             retcode[i] = (String) model.getElementAt(i);
118         }
119 
120         return retcode;
121     }
122 
123     /*
124      * (non-Javadoc)
125      * 
126      * @see org.crosswire.common.config.swing.Field#setValue(java.lang.String)
127      */
128     public void setValue(String value) {
129         setArray(Convert.string2StringArray(value, File.pathSeparator));
130     }
131 
132     /**
133      * Set the current value using a String array
134      * 
135      * @param value
136      *            The new text
137      */
138     public void setArray(String[] value) {
139         model = new DefaultComboBoxModel(value.clone());
140         list.setModel(model);
141     }
142 
143     /*
144      * (non-Javadoc)
145      * 
146      * @see org.crosswire.common.config.swing.Field#getComponent()
147      */
148     public JComponent getComponent() {
149         return this;
150     }
151 
152     /**
153      * Pop up a dialog to allow editing of a new value
154      */
155     public void doAddPathEntry() {
156         JFileChooser chooser = new JFileChooser();
157         chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
158         if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
159             String path = chooser.getSelectedFile().getPath();
160             model.addElement(path);
161         }
162     }
163 
164     /**
165      * Pop up a dialog to allow editing of a current value
166      */
167     public void doUpdatePathEntry() {
168         JFileChooser chooser = new JFileChooser(currentValue());
169         chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
170         if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
171             String path = chooser.getSelectedFile().getPath();
172 
173             model.removeElement(currentValue());
174             model.addElement(path);
175         }
176     }
177 
178     /**
179      * Delete the current value in the hashtable
180      */
181     public void doRemovePathEntry() {
182         model.removeElement(currentValue());
183     }
184 
185     /**
186      * What is the currently selected value?
187      * 
188      * @return The currently selected value
189      */
190     private String currentValue() {
191         return (String) model.getElementAt(list.getSelectedIndex());
192     }
193 
194     /**
195      * Serialization support.
196      * 
197      * @param is
198      * @throws IOException
199      * @throws ClassNotFoundException
200      */
201     private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
202         actions = new ActionFactory(this);
203         is.defaultReadObject();
204     }
205 
206     private transient ActionFactory actions;
207 
208     /**
209      * The TableModel that points the JTable at the Hashtable
210      */
211     private DefaultComboBoxModel model;
212 
213     /**
214      * The Table - displays the Hashtble
215      */
216     private JList list;
217 
218     /**
219      * Serialization ID
220      */
221     private static final long serialVersionUID = 3256443607736072242L;
222 }
223