1
22 package org.crosswire.bibledesktop.book;
23
24 import java.awt.Component;
25 import java.awt.FlowLayout;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.beans.PropertyChangeEvent;
29 import java.io.IOException;
30 import java.io.ObjectInputStream;
31
32 import javax.swing.JComboBox;
33 import javax.swing.JList;
34 import javax.swing.JPanel;
35 import javax.swing.JScrollPane;
36 import javax.swing.JSplitPane;
37 import javax.swing.JTree;
38 import javax.swing.ListSelectionModel;
39 import javax.swing.event.ListSelectionEvent;
40 import javax.swing.event.ListSelectionListener;
41 import javax.swing.event.TreeSelectionEvent;
42 import javax.swing.event.TreeSelectionListener;
43 import javax.swing.tree.TreePath;
44
45 import org.crosswire.bibledesktop.display.BookDataDisplay;
46 import org.crosswire.bibledesktop.display.BookDataDisplayFactory;
47 import org.crosswire.bibledesktop.display.URIEventListener;
48 import org.crosswire.bibledesktop.passage.KeyChangeListener;
49 import org.crosswire.bibledesktop.passage.KeyListListModel;
50 import org.crosswire.bibledesktop.passage.KeyTreeCellRenderer;
51 import org.crosswire.bibledesktop.passage.KeyTreeModel;
52 import org.crosswire.bibledesktop.passage.KeyTreeNode;
53 import org.crosswire.common.swing.CWScrollPane;
54 import org.crosswire.common.swing.FixedSplitPane;
55 import org.crosswire.common.swing.GuiUtil;
56 import org.crosswire.common.util.Logger;
57 import org.crosswire.jsword.book.Book;
58 import org.crosswire.jsword.book.BookFilter;
59 import org.crosswire.jsword.book.BookFilters;
60 import org.crosswire.jsword.book.Defaults;
61 import org.crosswire.jsword.book.KeyType;
62 import org.crosswire.jsword.passage.Key;
63 import org.crosswire.jsword.passage.NoSuchKeyException;
64 import org.crosswire.jsword.passage.Passage;
65 import org.crosswire.jsword.passage.PreferredKey;
66 import org.crosswire.jsword.passage.Verse;
67
68
77 public class MultiBookPane extends JSplitPane implements BookDataDisplay {
78
81 public MultiBookPane() {
82 init();
83
84 bookList.setSelectedValue(Defaults.getDailyDevotional(), true);
86 }
87
88
91 private void init() {
92 display = BookDataDisplayFactory.createBookDataDisplay();
93
94 Component bookPicker = createBookPicker();
95
96 commentaryPicker = createCommentaryPicker();
97
98 dictionaryKeyScroller = createDictionaryPicker();
99
100 genBookKeyScroller = createGenBookPicker();
101
102 JScrollPane scrDisplay = new CWScrollPane(display.getComponent());
103
104 sptMain = new FixedSplitPane(false);
105 sptMain.setOrientation(JSplitPane.VERTICAL_SPLIT);
106 sptMain.setResizeWeight(0.2D);
108 sptMain.setTopComponent(new JPanel());
109 sptMain.setBottomComponent(scrDisplay);
110
111 this.setOrientation(JSplitPane.VERTICAL_SPLIT);
114 this.setTopComponent(bookPicker);
115 this.setBottomComponent(sptMain);
116 this.setBorder(null);
117
118 Object thisUI = this.getUI();
119 if (thisUI instanceof javax.swing.plaf.basic.BasicSplitPaneUI) {
120 ((javax.swing.plaf.basic.BasicSplitPaneUI) thisUI).getDivider().setBorder(null);
121 }
122 }
123
124
127 public void clearBookData() {
128 setBookData(null, null);
129 }
130
131
134 public void setBookData(Book[] books, Key key) {
135 display.setBookData(books, key);
136 }
137
138
141 public void setCompareBooks(boolean compare) {
142 display.setCompareBooks(compare);
143 }
144
145
148 public void refresh() {
149 display.refresh();
150 }
151
152
155 public Component getComponent() {
156 return this;
157 }
158
159
162 public void copy() {
163 display.copy();
164 }
165
166
169 public Key getKey() {
170 return (Key) dictionaryKeyList.getSelectedValue();
171 }
172
173
176 public void addKeyChangeListener(KeyChangeListener listener) {
177 display.addKeyChangeListener(listener);
178 }
179
180
183 public void removeKeyChangeListener(KeyChangeListener listener) {
184 display.removeKeyChangeListener(listener);
185 }
186
187
190 public void propertyChange(PropertyChangeEvent evt) {
191 display.propertyChange(evt);
192 }
193
194
197 public void addURIEventListener(URIEventListener listener) {
198 display.addURIEventListener(listener);
199 }
200
201
204 public void removeURIEventListener(URIEventListener listener) {
205 display.removeURIEventListener(listener);
206 }
207
208
211 public Book[] getBooks() {
212 return new Book[] {
213 book
214 };
215 }
216
217
220 public Book getFirstBook() {
221 return book;
222 }
223
224
229 public void setWord(String data) {
230 if (book == null) {
231 return;
232 }
233
234 try {
235 Key key = book.getKey(data);
236 dictionaryKeyList.setSelectedValue(key, true);
237 } catch (NoSuchKeyException ex) {
238 return;
239 }
240
241 }
242
243
246 public void setKey(Key key) {
247 if (key instanceof Passage) {
248 Passage ref = (Passage) key;
249 if (ref.countVerses() > 0) {
250 set.setVerse(ref.getVerseAt(0));
251 }
252 }
253
254 updateDisplay();
255 }
256
257
275
276 public void selectBook(Book selectedBook) {
277 bookList.setSelectedValue(selectedBook, true);
278 }
279
280
285 private Component createBookPicker() {
286 BookFilter filter = BookFilters.getNonBibles();
287 BooksComboBoxModel mdlBooks = new BooksComboBoxModel(filter);
288
289 bookList = new JList();
290 bookList.setVisibleRowCount(6);
291 bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
292 bookList.setModel(mdlBooks);
293 bookList.setCellRenderer(new BookListCellRenderer());
294 bookList.setPrototypeCellValue(BookListCellRenderer.PROTOTYPE_BOOK_NAME);
295 bookList.addListSelectionListener(new ListSelectionListener() {
296 public void valueChanged(ListSelectionEvent ev) {
297 if (ev.getValueIsAdjusting()) {
298 return;
299 }
300
301 newBook();
302 }
303 });
304
305 Component scroller = new CWScrollPane(bookList);
306 GuiUtil.applyDefaultOrientation(scroller);
307 return scroller;
308 }
309
310
313 private Component createCommentaryPicker() {
314 JComboBox cboBooks = new JComboBox();
315 JComboBox cboChaps = new JComboBox();
316 JComboBox cboVerse = new JComboBox();
317 set = new BibleComboBoxModelSet(cboBooks, cboChaps, cboVerse);
318
319 set.addActionListener(new ActionListener() {
320 public void actionPerformed(ActionEvent ev) {
321 updateDisplay();
322 }
323 });
324
325 JPanel panel = new JPanel();
326 panel.setLayout(new FlowLayout());
327 panel.add(cboBooks, null);
328 panel.add(cboChaps, null);
329 panel.add(cboVerse, null);
330
331 GuiUtil.applyDefaultOrientation(panel);
332
333 return panel;
334 }
335
336
339 private Component createDictionaryPicker() {
340 dictionaryKeyList = new JList();
341 dictionaryKeyList.addListSelectionListener(new ListSelectionListener() {
342 public void valueChanged(ListSelectionEvent ev) {
343 newEntry();
344 }
345 });
346 Component scroller = new CWScrollPane(dictionaryKeyList);
347 GuiUtil.applyDefaultOrientation(scroller);
348 return scroller;
349 }
350
351
354 private Component createGenBookPicker() {
355 genBookKeyTree = new JTree();
356 genBookKeyTree.setModel(new KeyTreeModel(null));
357 genBookKeyTree.setShowsRootHandles(true);
358 genBookKeyTree.setRootVisible(false);
359 genBookKeyTree.putClientProperty("JTree.lineStyle", "Angled");
360 genBookKeyTree.setCellRenderer(new KeyTreeCellRenderer());
361 genBookKeyTree.addTreeSelectionListener(new TreeSelectionListener() {
362 public void valueChanged(TreeSelectionEvent ev) {
363 selected();
364 }
365 });
366
367 Component scroller = new CWScrollPane(genBookKeyTree);
368 GuiUtil.applyDefaultOrientation(scroller);
369 return scroller;
370 }
371
372
375 final void newBook() {
376 if (book != null) {
379 KeyType currentCategory = book.getBookMetaData().getKeyType();
380 if (KeyType.LIST.equals(currentCategory)) {
381 dictionaryKeyList.ensureIndexIsVisible(0);
383 dictionaryKeyList.setModel(new KeyListListModel(null));
385 } else if (KeyType.TREE.equals(currentCategory)) {
386 genBookKeyTree.scrollRowToVisible(0);
388
389 KeyTreeModel model = new KeyTreeModel(null);
391 genBookKeyTree.setModel(model);
392 }
393 }
394 display.clearBookData();
396
397 Object selected = bookList.getSelectedValue();
398 if (selected != null) {
399 Book selectedBook = (Book) selected;
400 KeyType category = selectedBook.getBookMetaData().getKeyType();
401 int dividerLocation = sptMain.getDividerLocation();
404 if (KeyType.VERSE.equals(category)) {
405 updateDisplay();
406 sptMain.setTopComponent(commentaryPicker);
407 } else if (KeyType.LIST.equals(category)) {
408 book = selectedBook;
409 Key key = book.getGlobalKeyList();
410
411 KeyListListModel model = new KeyListListModel(key);
412 dictionaryKeyList.setModel(model);
413
414 if (book instanceof PreferredKey) {
415 PreferredKey pref = (PreferredKey) book;
416 Key prefkey = pref.getPreferred();
417
418 dictionaryKeyList.setSelectedValue(prefkey, true);
419 }
420
421 sptMain.setTopComponent(dictionaryKeyScroller);
422 } else { book = selectedBook;
424 Key key = book.getGlobalKeyList();
425
426 KeyTreeModel model = new KeyTreeModel(key);
427 genBookKeyTree.setModel(model);
428
429 sptMain.setTopComponent(genBookKeyScroller);
430 }
431
432 sptMain.setDividerLocation(dividerLocation);
433 }
434 }
435
436
439 final void updateDisplay() {
440 Book selectedBook = (Book) bookList.getSelectedValue();
441 if (selectedBook == null) {
442 log.warn("no selected book");
443 return;
444 }
445
446 Verse verse = set.getVerse();
447 display.setBookData(new Book[] {
448 selectedBook
449 }, verse);
450 }
451
452
455 final void newEntry() {
456 Key key = (Key) dictionaryKeyList.getSelectedValue();
457 if (key != null) {
458 display.setBookData(new Book[] {
459 book
460 }, key);
461 }
462 }
463
464
467 void selected() {
468 TreePath path = genBookKeyTree.getSelectionPath();
469
470 if (path != null) {
471 KeyTreeNode node = (KeyTreeNode) path.getLastPathComponent();
472 if (node != null) {
473 display.setBookData(new Book[] {
474 book
475 }, node.getKey());
476 }
477 }
478
479 }
480
481
488 private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
489 display = BookDataDisplayFactory.createBookDataDisplay();
491 book = null;
492 set = null;
493 is.defaultReadObject();
494 }
495
496
499 private transient BookDataDisplay display;
500 private transient Book book;
501 protected transient BibleComboBoxModelSet set;
502 private Component commentaryPicker;
503 private Component genBookKeyScroller;
504 private JTree genBookKeyTree;
505 private JList bookList;
506 private JSplitPane sptMain;
507 private Component dictionaryKeyScroller;
508 private JList dictionaryKeyList;
509
510
513 private static final Logger log = Logger.getLogger(MultiBookPane.class);
514
515
518 private static final long serialVersionUID = 3616449020667442997L;
519 }
520