1
22 package org.crosswire.common.config.swing;
23
24 import java.awt.BorderLayout;
25 import java.awt.Color;
26 import java.awt.Component;
27 import java.awt.Dimension;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32
33 import javax.swing.BorderFactory;
34 import javax.swing.JComponent;
35 import javax.swing.JScrollPane;
36 import javax.swing.JTree;
37 import javax.swing.UIManager;
38 import javax.swing.tree.DefaultTreeCellRenderer;
39
40 import org.crosswire.common.config.Choice;
41 import org.crosswire.common.swing.CWScrollPane;
42 import org.crosswire.common.swing.CWMsg;
43
44
51 public class AdvancedConfigEditor extends TreeConfigEditor {
52
55 protected AdvancedConfigEditor() {
56 ctm = new AdvancedConfigureTreeModel();
57 tree = new JTree();
58 JScrollPane scroll = new CWScrollPane(tree);
59 scroll.setPreferredSize(new Dimension(150, 150));
60
61 CustomTreeCellRenderer render = new CustomTreeCellRenderer();
62 comps = new HashMap<String, Component>();
63
64 Color orig = UIManager.getColor("control");
66 Color bg = new Color(orig.getRed(), orig.getGreen(), orig.getBlue());
67
68 render.setLeafIcon(TASK_ICON_SMALL);
70 render.setBackgroundNonSelectionColor(bg);
71
72 tree.setBackground(bg);
73 tree.setModel(ctm);
74 tree.setCellRenderer(render);
75 tree.setShowsRootHandles(true);
76 tree.setRootVisible(false);
77 tree.putClientProperty("JTree.lineStyle", "None");
78 tree.setSelectionRow(0);
79 tree.setEditable(true);
80
81 setLayout(new BorderLayout(5, 10));
82 setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
83
84 add(BorderLayout.CENTER, scroll);
85 add(BorderLayout.SOUTH, new ButtonPane(this));
86 }
87
88
91 @Override
92 protected void updateTree() {
93
98
99 ctm.fireTreeStructureChanged(this);
100 }
101
102
105 @Override
106 protected void addChoice(Choice model) {
107 String key = model.getKey();
108 Field field = FieldMap.getField(model);
109 fields.put(key, field);
110
111 JComponent comp = field.getComponent();
113 comp.setToolTipText(model.getHelpText());
114 comps.put(key, comp);
115
116 String value = config.getLocal(key);
118 field.setValue(value);
119 }
120
121
124 @Override
125 protected void removeChoice(Choice choice) {
126 String key = choice.getKey();
127 Field field = fields.get(key);
128 if (field != null) {
129 fields.remove(key);
130 }
131
132 Component comp = comps.get(key);
133 if (comp != null) {
134 comps.remove(key);
135 }
136 }
137
138
142 @Override
143 public void selectCard() {
144 Object obj = tree.getLastSelectedPathComponent();
145 if (obj == null) {
146 return;
147 }
148
149 title.setText(CWMsg.gettext("{0} Preferences", obj));
152
153 Object[] list = tree.getSelectionPath().getPath();
155 StringBuilder path = new StringBuilder();
156
157 for (int i = 1; i < list.length; i++) {
158 if (i > 1) {
159 path.append('.');
160 }
161
162 path.append(list[i].toString());
163 }
164
165 String key = path.toString();
166 if (decks.containsKey(key)) {
167 layout.show(deck, key);
168 } else {
169 layout.show(deck, BLANK);
170 }
171
172 deck.repaint();
173 }
174
175
178 protected Map<String, Component> comps;
179
180
183 private static final long serialVersionUID = 3616451198199345203L;
184
185
190 class AdvancedConfigureTreeModel extends ConfigureTreeModel {
191
198 @Override
199 protected List<String> getChildren(String path) {
200 List<String> retcode = new ArrayList<String>();
201
202 for (Choice choice : config) {
203 if (choice.isHidden()) {
204 continue;
205 }
206
207 String temp = choice.getKey();
208
209 if (temp.startsWith(path) && !temp.equals(path)) {
210 temp = temp.substring(path.length());
212 if (temp.charAt(0) == '.') {
213 temp = temp.substring(1);
214 }
215
216 int dotPos = temp.indexOf('.');
218 if (dotPos != -1) {
219 temp = temp.substring(0, dotPos);
220 }
221
222 if (temp.length() > 0 && !retcode.contains(temp)) {
224 retcode.add(temp);
225 }
226 }
227 }
228
229 return retcode;
230 }
231
232
237 @Override
238 public Object getChild(Object parent, int index) {
239 if (parent instanceof CompNode) {
240 return null;
241 }
242
243 String path = ((Node) parent).getFullName();
244 List<String> children = getChildren(path);
245
246 if (children.isEmpty()) {
247 return new CompNode(path);
248 }
249
250 String name = children.get(index);
251 return new Node(path, name);
252 }
253
254
259 @Override
260 public int getChildCount(Object parent) {
261 if (parent instanceof CompNode) {
262 return 0;
263 }
264
265 String path = ((Node) parent).getFullName();
266 int children = getChildren(path).size();
267 if (children == 0) {
268 children = 1;
269 }
270
271 return children;
272 }
273
274
279 @Override
280 public boolean isLeaf(Object node) {
281 return node instanceof CompNode;
282 }
283 }
284
285
288 static class CompNode {
289
292 public CompNode(String path) {
293 this.path = path;
294 }
295
296
301 @Override
302 public String toString() {
303 return path;
304 }
305
306
309 public String getFullName() {
310 return path;
311 }
312
313
316 private String path;
317 }
318
319
322 class CustomTreeCellRenderer extends DefaultTreeCellRenderer {
323
331 @Override
332 public Component getTreeCellRendererComponent(JTree jtree, Object value, boolean isselected, boolean expanded, boolean leaf, int row, boolean focus) {
333 if (!(value instanceof CompNode)) {
334 return super.getTreeCellRendererComponent(jtree, value, isselected, expanded, leaf, row, focus);
335 }
336
337 JComponent comp = (JComponent) comps.get(value.toString());
338
339 if (comp == null) {
340 return super.getTreeCellRendererComponent(jtree, value, isselected, expanded, leaf, row, focus);
341 }
342
343 if (isselected) {
344 comp.setBorder(BorderFactory.createLineBorder(Color.black));
345 } else {
346 comp.setBorder(BorderFactory.createEmptyBorder());
347 }
348
349 return comp;
350 }
351
352
355 private static final long serialVersionUID = 3256720688860576049L;
356 }
357 }
358