2 * Copyright (C) 2003 Morten O. Alver, Nizar N. Batada
4 * All programs in this directory and subdirectories are published under the GNU
5 * General Public License as described below.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option) any later
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
21 * Further information about the GNU GPL is available at:
22 * http://www.gnu.org/copyleft/gpl.ja.html
25 package net.sf.jabref;
28 import javax.swing.text.JTextComponent;
30 import java.util.List;
32 import java.awt.event.*;
34 public class EntryEditorTab {
36 private JPanel panel = new JPanel();
37 private String[] fields;
38 private final static Object[] ARRAY = new String[0];
39 private EntryEditor parent;
40 private HashMap editors = new HashMap();
41 private FieldEditor activeField = null;
42 private JScrollPane sp = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
43 // private BibtexEntry entry;
45 public EntryEditorTab(List fields, EntryEditor parent, boolean addKeyField, String name) {
47 this.fields = (String[])fields.toArray(ARRAY);
49 this.fields = new String[] {};
51 setupPanel(addKeyField, name);
53 // The following line makes sure focus cycles inside tab instead of being lost
54 // to other parts of the frame:
55 panel.setFocusCycleRoot(true);
60 private final void setupPanel(boolean addKeyField, String title) {
61 GridBagLayout gbl = new GridBagLayout();
62 GridBagConstraints con = new GridBagConstraints();
64 double totalWeight = 0;
66 //panel.setOpaque(true);
67 //panel.setBackground(java.awt.Color.white);
69 for (int i=0; i<fields.length; i++) {
71 // Create the text area:
72 FieldTextArea ta = new FieldTextArea(fields[i], null);//stringContent);
73 JComponent ex = parent.getExtra(fields[i], ta);
74 // Attach listeners and key bindings:
75 setupJTextComponent(ta);
76 ta.addFocusListener(new FieldListener(ta));
78 // Store the editor for later reference:
79 editors.put(fields[i], ta);
83 // The label for this field:
84 con.insets = new Insets(5, 5, 0, 0);
85 con.anchor = GridBagConstraints.WEST;
86 con.fill = GridBagConstraints.BOTH;
90 con.anchor = GridBagConstraints.NORTH;
91 con.fill = GridBagConstraints.BOTH;
92 gbl.setConstraints(ta.getLabel(), con);
93 panel.add(ta.getLabel());
96 con.fill = GridBagConstraints.BOTH;
98 con.weighty = GUIGlobals.getFieldWeight(fields[i]);
99 totalWeight += con.weighty;
100 // The gridwidth depends on whether we will add an extra component to the right:
104 con.gridwidth = GridBagConstraints.REMAINDER;
105 gbl.setConstraints(ta.getPane(), con);
106 panel.add(ta.getPane());
108 // Possibly an extra component:
110 con.gridwidth = GridBagConstraints.REMAINDER;
111 con.anchor = GridBagConstraints.NORTH;
112 con.fill = GridBagConstraints.HORIZONTAL;
114 gbl.setConstraints(ex, con);
117 panel.setName(title);
120 // Add the edit field for Bibtex-key.
122 con.insets.top += 25;
123 con.insets.bottom = 10;
127 con.fill = GridBagConstraints.HORIZONTAL;
128 con.anchor = GridBagConstraints.SOUTHWEST;
129 FieldTextField tf = new FieldTextField(Globals.KEY_FIELD, (String) parent.getEntry().getField(Globals.KEY_FIELD), true);
130 editors.put("bibtexkey", tf);
132 // If the key field is the only field, we should have only one editor, and this one should be set
133 // as active initially:
134 if (editors.size() == 1)
137 gbl.setConstraints(tf.getLabel(), con);
138 panel.add(tf.getLabel());
139 con.gridwidth = GridBagConstraints.REMAINDER;
141 setupJTextComponent(tf);
142 tf.addFocusListener(new FieldListener(tf));
143 gbl.setConstraints(tf, con);
151 public void setActive(FieldEditor c) {
153 //System.out.println(c.toString());
156 public FieldEditor getActive() {
160 public List getFields() {
161 return java.util.Arrays.asList(fields);
164 public void activate() {
165 if (activeField != null)
166 activeField.requestFocus();
169 //System.out.println("Activate, hurra");
172 public void updateAll() {
173 // Test: make sure all fields are correct:
174 setEntry(parent.getEntry());
175 /*for (int i=0; i<fields.length; i++) {
176 FieldEditor fe = (FieldEditor)editors.get(fields[i]);
181 public void setEntry(BibtexEntry entry) {
182 for (Iterator i=editors.keySet().iterator(); i.hasNext();) {
183 String field = (String)i.next();
184 FieldEditor ed = (FieldEditor)editors.get(field);
185 Object content = entry.getField(ed.getFieldName());
186 ed.setText((content == null) ? "" : content.toString());
190 public boolean updateField(String field, String content) {
191 if (!editors.containsKey(field))
193 FieldEditor ed = (FieldEditor)editors.get(field);
198 public void validateAllFields() {
199 for (Iterator i=editors.keySet().iterator(); i.hasNext();) {
200 String field = (String)i.next();
201 FieldEditor ed = (FieldEditor)editors.get(field);
202 if (((Component)ed).hasFocus())
203 ed.setBackground(GUIGlobals.activeEditor);
205 ed.setBackground(GUIGlobals.validFieldBackground);
209 public void setEnabled(boolean enabled) {
210 for (Iterator i=editors.keySet().iterator(); i.hasNext();) {
211 String field = (String)i.next();
212 FieldEditor ed = (FieldEditor)editors.get(field);
213 ed.setEnabled(enabled);
217 public Component getPane() {
222 public void setupJTextComponent(JTextComponent ta) {
223 // Activate autocompletion if it should be used for this field.
225 // Set up key bindings and focus listener for the FieldEditor.
226 InputMap im = ta.getInputMap(JComponent.WHEN_FOCUSED);
227 ActionMap am = ta.getActionMap();
229 im.put(Globals.prefs.getKey("Entry editor, previous entry"), "prev");
230 am.put("prev", parent.prevEntryAction);
231 im.put(Globals.prefs.getKey("Entry editor, next entry"), "next");
232 am.put("next", parent.nextEntryAction);
234 im.put(Globals.prefs.getKey("Entry editor, store field"), "store");
235 am.put("store", parent.storeFieldAction);
236 im.put(Globals.prefs.getKey("Entry editor, next panel"), "right");
237 im.put(Globals.prefs.getKey("Entry editor, next panel 2"), "right");
238 am.put("left", parent.switchLeftAction);
239 im.put(Globals.prefs.getKey("Entry editor, previous panel"), "left");
240 im.put(Globals.prefs.getKey("Entry editor, previous panel 2"), "left");
241 am.put("right", parent.switchRightAction);
242 im.put(Globals.prefs.getKey("Help"), "help");
243 am.put("help", parent.helpAction);
244 im.put(Globals.prefs.getKey("Save database"), "save");
245 am.put("save", parent.saveDatabaseAction);
246 im.put(Globals.prefs.getKey("Next tab"), "nexttab");
247 am.put("nexttab", parent.frame.nextTab);
248 im.put(Globals.prefs.getKey("Previous tab"), "prevtab");
249 am.put("prevtab", parent.frame.prevTab);
254 new HashSet(ta.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
256 keys.add(AWTKeyStroke.getAWTKeyStroke("pressed TAB"));
257 ta.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);
259 new HashSet(ta.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
261 keys.add(KeyStroke.getKeyStroke("shift pressed TAB"));
262 ta.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys);
263 } catch (Throwable t) {
264 System.err.println(t);
271 * Focus listener that fires the storeFieldAction when a FieldTextArea loses
274 class FieldListener extends FocusAdapter {
278 public FieldListener(FieldEditor fe) {
282 public void focusGained(FocusEvent e) {
286 public void focusLost(FocusEvent e) {
287 if (!e.isTemporary())
288 parent.updateField(fe);