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: 2007
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: MappedOptionsField.java 1464 2007-07-02 02:34:40Z dmsmith $
21   */
22  package org.crosswire.common.config.swing;
23  
24  import java.awt.Dimension;
25  import java.util.Map;
26  
27  import javax.swing.ComboBoxModel;
28  import javax.swing.JComboBox;
29  import javax.swing.JComponent;
30  
31  import org.crosswire.common.config.Choice;
32  import org.crosswire.common.config.MappedChoice;
33  import org.crosswire.common.swing.GuiUtil;
34  import org.crosswire.common.swing.MapComboBoxModel;
35  import org.crosswire.common.swing.MapEntryRenderer;
36  import org.crosswire.common.swing.CWOtherMsg;
37  import org.crosswire.common.util.Logger;
38  
39  /**
40   * Allow the user to choose from a combo box.
41   * 
42   * @see gnu.lgpl.License for license details.<br>
43   *      The copyright to this program is held by it's authors.
44   * @author DM Smith [dmsmith555 at yahoo dot com]
45   */
46  public class MappedOptionsField implements Field {
47      /**
48       * Create an empty MappedOptionsField
49       */
50      public MappedOptionsField() {
51          combo = new JComboBox(new String[] {
52                  CWOtherMsg.lookupText("No Options Set")
53          });
54          // Set the preferred width. Note, the actual combo box will resize to
55          // the width of it's container
56          combo.setPreferredSize(new Dimension(100, combo.getPreferredSize().height));
57          GuiUtil.applyDefaultOrientation(combo);
58      }
59  
60      /**
61       * Some fields will need some extra info to display properly like the
62       * options in an options field. FieldMap calls this method with options
63       * provided by the choice.
64       * 
65       * @param param
66       *            The options provided by the Choice
67       */
68      public void setChoice(Choice param) {
69          if (!(param instanceof MappedChoice<?, ?>)) {
70              throw new IllegalArgumentException("Illegal type for Choice. Not a MappedChoice. " + param.getKey());
71          }
72          MappedChoice<?, ?> mc = (MappedChoice<?, ?>) param;
73          Map<?, ?> map = mc.getOptions();
74          if (map == null) {
75              throw new IllegalArgumentException("getOptions() returns null for option: " + param.getKey());
76          }
77          combo.setModel(new MapComboBoxModel(map));
78          combo.setRenderer(new MapEntryRenderer());
79      }
80  
81      /**
82       * Return a string for use in the properties file
83       * 
84       * @return The current value
85       */
86      public String getValue() {
87          Object reply = combo.getSelectedItem();
88  
89          if (reply instanceof Map.Entry<?, ?>) {
90              return ((Map.Entry<?, ?>) reply).getKey().toString();
91          }
92          return reply == null ? "" : reply.toString();
93      }
94  
95      /**
96       * Set the current value
97       * 
98       * @param value
99       *            The new text
100      */
101     public void setValue(String value) {
102         ComboBoxModel model = combo.getModel();
103         int size = model.getSize();
104         for (int i = 0; i < size; i++) {
105             Object match = model.getElementAt(i);
106             if (match instanceof Map.Entry<?, ?>) {
107                 Map.Entry<?, ?> mapEntry = (Map.Entry<?, ?>) match;
108                 if (mapEntry.getKey().toString().equals(value) || mapEntry.getValue().toString().equals(value)) {
109                     combo.setSelectedItem(mapEntry);
110                     return;
111                 }
112             }
113         }
114 
115         // Equate null and empty string
116         Object selected = combo.getSelectedItem();
117         if (value.length() > 0 && selected != null) {
118             log.warn("Checked for options without finding: '" + value + "'. Defaulting to first option: " + selected);
119         }
120     }
121 
122     /**
123      * Get the actual component that we can add to a Panel. (This can well be
124      * this in an implementation).
125      */
126     public JComponent getComponent() {
127         return combo;
128     }
129 
130     /**
131      * The component that we are wrapping in a field
132      */
133     private JComboBox combo;
134 
135     /**
136      * The log stream
137      */
138     private static final Logger log = Logger.getLogger(MappedOptionsField.class);
139 }
140