001 /* JAPI - (Yet another (hopefully) useful) Java API 002 * 003 * Copyright (C) 2004-2006 Christian Hujer 004 * 005 * This program is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU General Public License as 007 * published by the Free Software Foundation; either version 2 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 * 02111-1307, USA. 019 */ 020 021 package net.sf.japi.swing.bookmarks; 022 023 import java.awt.BorderLayout; 024 import java.awt.dnd.DropTarget; 025 import java.awt.event.ActionEvent; 026 import java.io.File; 027 import java.io.IOException; 028 import java.util.ArrayList; 029 import java.util.Collections; 030 import java.util.Enumeration; 031 import java.util.Iterator; 032 import java.util.List; 033 import javax.swing.AbstractAction; 034 import javax.swing.Action; 035 import javax.swing.JComponent; 036 import javax.swing.JFrame; 037 import javax.swing.JMenu; 038 import javax.swing.JMenuBar; 039 import javax.swing.JMenuItem; 040 import static javax.swing.JOptionPane.ERROR_MESSAGE; 041 import static javax.swing.JOptionPane.QUESTION_MESSAGE; 042 import static javax.swing.JOptionPane.showInputDialog; 043 import static javax.swing.JOptionPane.showMessageDialog; 044 import javax.swing.JScrollPane; 045 import javax.swing.JToolBar; 046 import javax.swing.JTree; 047 import javax.swing.tree.MutableTreeNode; 048 import javax.swing.tree.TreeNode; 049 import javax.xml.parsers.DocumentBuilder; 050 import javax.xml.parsers.DocumentBuilderFactory; 051 import javax.xml.parsers.ParserConfigurationException; 052 import org.w3c.dom.DOMImplementation; 053 import org.w3c.dom.Document; 054 import org.w3c.dom.Element; 055 import org.w3c.dom.Node; 056 import org.w3c.dom.NodeList; 057 import org.w3c.dom.ls.DOMImplementationLS; 058 import org.xml.sax.SAXException; 059 import net.sf.japi.swing.ActionFactory; 060 import net.sf.japi.swing.IconManager; 061 import net.sf.japi.util.EmptyEnumeration; 062 063 /** Class for managing and displaying Bookmarks. 064 * Usage of this class works the following way: 065 * <ul> 066 * <li>implement the interface {@link Bookmarkable} and its methods</li> 067 * <li>instanciate this class once for each gruop / kind of bookmarks you want to manage. Normally, one instance is enough per application</li> 068 * <li>invoke {@link #createBookmarkMenu} to create your bookmarks menu</li> 069 * </ul> 070 * @author $Author: christianhujer $ 071 * @todo documentation 072 * @todo fix bookmark drag and drop indices 073 * @todo think about serialization of Actions 074 */ 075 public class BookmarkManager { 076 077 /** The Bookmarks. */ 078 private BookmarkFolder bookmarks = new BookmarkFolder(); 079 080 /** Action Factory. */ 081 private static final ActionFactory ACTION_FACTORY = ActionFactory.getFactory("net.sf.japi.swing.bookmarks"); 082 083 /** The ProgramFrame this BookmarkManager manages bookmarks for. */ 084 private Bookmarkable bookmarkable; 085 086 /** Create a new BookmarkManager. */ 087 public BookmarkManager(final Bookmarkable bookmarkable) { 088 this.bookmarkable = bookmarkable; 089 try { 090 load(); 091 save(); 092 } catch (final Exception e) { 093 e.printStackTrace(); 094 // TODO: improve dialog 095 showMessageDialog(bookmarkable.getBookmarkBlocker(), ACTION_FACTORY.getString("bookmarksCreated.message")); 096 } 097 } 098 099 /** Create a Bookmark ToolBar. 100 * @return toolBar for Bookmarks 101 */ 102 public JToolBar createBookmarkToolBar() { 103 // Variant 1: JToolBar with JMenuBar with one entry "Lesezeichen" 104 final JToolBar toolBar = new JToolBar(ACTION_FACTORY.getString("bookmarkToolBar.name")); 105 final JMenuBar mb = new JMenuBar(); 106 mb.add(bookmarks.createMenu()); 107 toolBar.add(mb); 108 return toolBar; 109 110 //// Variant 2: JToolBar with JMenus and JMenuItems (broken) 111 //JToolBar toolBar = new JToolBar(ACTION_FACTORY.getString("bookmarkToolBar.name")); 112 //for (Bookmark bookmark : bookmarks) { 113 // toolBar.add(bookmark.createMenu()); 114 //} 115 //return toolBar; 116 117 //// Variant 3: JToolBar with JMenuBar with JMenus and JMenuItems (JMenuItems don't hover) 118 //JToolBar toolBar = new JToolBar(ACTION_FACTORY.getString("bookmarkToolBar.name")); 119 //JMenuBar mb = new JMenuBar(); 120 //for (Bookmark bookmark : bookmarks) { 121 // mb.add(bookmark.createMenu()); 122 //} 123 //toolBar.add(mb); 124 //return toolBar; 125 126 //// Variant 4: JToolBar with a button activating a PopupMenu. 127 //// Doesn't work either, the popup menu is not correctly usable. 128 //JToolBar toolBar = new JToolBar(ACTION_FACTORY.getString("bookmarkToolBar.name")); 129 //final JPopupMenu menu = new JPopupMenu(ACTION_FACTORY.getString("bookmark.text")); 130 //menu.add(bookmarks.createMenu()); 131 //toolBar.add( 132 // new javax.swing.JButton( 133 // new AbstractAction() { 134 // public void actionPerformed(final ActionEvent e) { 135 // menu.setVisible(true); 136 // } 137 // } 138 // ) 139 //); 140 //return toolBar; 141 } 142 143 /** Create a Bookmark Menu. 144 * @return JMenu for Bookmarks 145 */ 146 public JMenu createBookmarkMenu() { 147 final JMenu menu = bookmarks.createMenu(); 148 menu.add(new JMenuItem(manageBookmarks)); 149 return menu; 150 } 151 152 /** Create a Bookmark ControlPanel. 153 * @return ControlPanel for Bookmarks 154 */ 155 public JComponent createBookmarkControlPanel() { 156 return new ControlPanel(); 157 } 158 159 /** Recursive attach method. 160 * @param menu JMenu to attach bookmarks to 161 * @param bookmarks Bookmarks to attach 162 */ 163 private static void attach(final JMenu menu, final BookmarkFolder bookmarks) { 164 for (final Bookmark bookmark : bookmarks) { 165 if (bookmark instanceof BookmarkFolder) { 166 final JMenu newMenu = new JMenu(bookmark); 167 attach(newMenu, (BookmarkFolder) bookmark); 168 } else { 169 assert bookmark instanceof BookmarkItem; 170 menu.add(new JMenuItem(bookmark)); 171 } 172 } 173 } 174 175 /** Action for managing the bookmarks. 176 * @serial include 177 */ 178 private Action manageBookmarks = ACTION_FACTORY.createAction(true, "manageBookmarks", this); 179 180 /** Action for managing the bookmarks. */ 181 public void manageBookmarks() { 182 final JFrame f = new JFrame(ACTION_FACTORY.getString("manageBookmarks_shortdescription")); 183 f.getContentPane().add(createBookmarkControlPanel()); 184 //f.getContentPane().add(new JScrollPane(new JTree(bookmarks))); 185 f.pack(); 186 f.setVisible(true); 187 } 188 189 /** Set the AddBookmark enabled state. 190 * @param enabled enabled state for AddBookmark action 191 */ 192 public void setAddBookmarkEnabled(final boolean enabled) { 193 bookmarks.setAddBookmarkEnabled(enabled); 194 } 195 196 /** Load bookmarks from default file. 197 * @throws IOException in case of I/O problems 198 * @throws ParserConfigurationException in case of XML configuration problems 199 * @throws SAXException in case of XML document problems 200 */ 201 public void load() throws IOException, ParserConfigurationException, SAXException { 202 load(new File(System.getProperty("user.home"), ".jeduca.bookmarks.xml").toURL().toString()); 203 } 204 205 /** Save bookmarks to default file. 206 * @throws IOException in case of I/O problems 207 * @throws ParserConfigurationException in case of XML configuration problems 208 */ 209 public void save() throws IOException, ParserConfigurationException { 210 save(new File(System.getProperty("user.home"), ".jeduca.bookmarks.xml").toURL().toString()); 211 } 212 213 /** Save bookmarks to a file. 214 * @param uri URI of file to save 215 * @throws IOException in case of I/O problems 216 * @throws ParserConfigurationException in case of XML configuration problems 217 */ 218 public void save(final String uri) throws IOException, ParserConfigurationException { 219 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 220 final DocumentBuilder db = dbf.newDocumentBuilder(); 221 final Document doc = db.newDocument(); 222 bookmarks.store(doc); 223 final DOMImplementation impl = doc.getImplementation(); 224 if (impl instanceof DOMImplementationLS) { 225 final DOMImplementationLS ls = (DOMImplementationLS) impl; 226 ls.createLSSerializer().writeToURI(doc, uri); 227 } 228 } 229 230 /** Load bookmarks from a file. 231 * @param uri URI of file to load 232 * @throws IOException in case of I/O problems 233 * @throws ParserConfigurationException in case of XML configuration problems 234 * @throws SAXException in case of XML document problems 235 */ 236 public void load(final String uri) throws IOException, ParserConfigurationException, SAXException { 237 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 238 final DocumentBuilder db = dbf.newDocumentBuilder(); 239 final Document doc = db.parse(uri); 240 bookmarks = new BookmarkFolder(doc); 241 } 242 243 244 /** Class for a ControlPanel to manage the bookmarks. 245 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 246 * @version $Id: BookmarkManager.java,v 1.2 2006/03/26 15:22:16 christianhujer Exp $ 247 */ 248 private class ControlPanel extends JComponent { 249 250 /** Serial Version. */ 251 private static final long serialVersionUID = 1L; 252 253 /** Create a new ControlPanel. */ 254 ControlPanel() { 255 setLayout(new BorderLayout()); 256 final JTree tree = new JTree(bookmarks, true); 257 tree.setRootVisible(false); 258 tree.setCellRenderer(new BookmarkTreeCellRenderer()); 259 //tree.setEditable(true); 260 tree.setDragEnabled(true); 261 final DropTarget dt = new DropTarget(tree, new BookmarkDropTargetAdapter()); 262 tree.setTransferHandler(new BookmarkTransferHandler()); 263 add(new JScrollPane(tree)); 264 } 265 266 } // class ControlPanel 267 268 269 /** Base class for bookmarks. 270 * There are two kinds of bookmarks: 271 * <ul> 272 * <li>{@link BookmarkItem}s for normal Bookmarks with title and url</li> 273 * <li>{@link BookmarkFolder}s for Folders within Bookmarks with a title and (possibly) contents</li> 274 * </ul> 275 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 276 * @version $Id: BookmarkManager.java,v 1.2 2006/03/26 15:22:16 christianhujer Exp $ 277 */ 278 public static abstract class Bookmark extends AbstractAction implements MutableTreeNode { 279 280 /** Title for Bookmark. 281 * @serial include 282 */ 283 private String title; 284 285 /** The folder (parent) of this bookmark. 286 * @serial include 287 */ 288 protected BookmarkFolder folder; 289 290 ///** Create a Bookmark without title. 291 // * Should only be used by {@link BookmarkFolder#BookmarkFolder()}. 292 // */ 293 //protected Bookmark() { 294 //} 295 296 /** Create a Bookmark. 297 * You must not forget to invoke {@link #setFolder(BookmarkFolder)} in order to make {@link #getParent()} for JTrees working. 298 * @param title title for Bookmark 299 */ 300 protected Bookmark(final String title) { 301 setTitle(title); 302 putValue(SMALL_ICON, IconManager.getDefaultIconManager().getIcon(ACTION_FACTORY.getString("bookmark.icon"))); 303 } 304 305 /** {@inheritDoc} 306 * @return title of this Bookmark 307 */ 308 public String toString() { 309 return title; 310 } 311 312 /** Get the folder (parent) of this bookmark. 313 * @return folder (parent) of this bookmark 314 */ 315 public BookmarkFolder getFolder() { 316 return folder; 317 } 318 319 /** Set the folder (parent) of this bookmark. 320 * @param folder parent folder of this bookmark 321 */ 322 public void setFolder(final BookmarkFolder folder) { 323 if (this.folder != null) { 324 this.folder.remove(this); 325 } 326 this.folder = folder; 327 } 328 329 /** Set this Bookmark's title. 330 * @param title new title for this Bookmark 331 */ 332 public void setTitle(final String title) { 333 this.title = title; 334 putValue(NAME, title); 335 } 336 337 /** Create a MenuItem for this Bookmark 338 * @return MenuItem for this Bookmark 339 */ 340 public abstract JMenuItem createMenu(); 341 342 /** Get this Bookmark's title. 343 * @return Bookmark title 344 */ 345 public String getTitle() { 346 return title; 347 } 348 349 /** Store bookmarks in an XML Document. 350 * @param n Node (Element or Document) to attach to 351 */ 352 public abstract void store(final Node n); 353 354 /** {@inheritDoc} */ 355 public Enumeration<Bookmark> children() { 356 return new EmptyEnumeration<Bookmark>(); 357 } 358 359 /** {@inheritDoc} */ 360 public boolean getAllowsChildren() { 361 return false; 362 } 363 364 /** {@inheritDoc} */ 365 public Bookmark getChildAt(final int childIndex) { 366 throw new IndexOutOfBoundsException(Integer.toString(childIndex)); 367 } 368 369 /** {@inheritDoc} */ 370 public int getChildCount() { 371 return 0; 372 } 373 374 /** {@inheritDoc} */ 375 public int getIndex(final TreeNode node) { 376 return 0; 377 } 378 379 /** {@inheritDoc} */ 380 public BookmarkFolder getParent() { 381 return getFolder(); 382 } 383 384 /** {@inheritDoc} */ 385 public boolean isLeaf() { 386 return true; 387 } 388 389 /** {@inheritDoc} */ 390 public void insert(final MutableTreeNode child, final int index) { 391 throw new IllegalStateException("A bookmark cannot have children"); 392 } 393 394 /** {@inheritDoc} */ 395 public void remove(final int index) { 396 throw new IllegalStateException("A bookmark has no children"); 397 } 398 399 /** {@inheritDoc} */ 400 public void remove(final MutableTreeNode child) { 401 throw new IllegalStateException("A bookmark has no children"); 402 } 403 404 /** {@inheritDoc} */ 405 public void removeFromParent() { 406 folder.remove(this); 407 } 408 409 /** {@inheritDoc} */ 410 public void setParent(final MutableTreeNode newParent) { 411 if (newParent instanceof BookmarkFolder) { 412 setFolder((BookmarkFolder)newParent); 413 } else { 414 throw new IllegalArgumentException("Parent must be a BookmarkFolder, but was : " + newParent.getClass().getName()); 415 } 416 } 417 418 /** {@inheritDoc} */ 419 public void setUserObject(final Object object) { 420 System.err.println("setUserObject was called but does not know what to do. Supplied object: " + object); 421 } 422 423 } // class Bookmark 424 425 426 /** Class for Bookmark Separator. 427 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 428 * @version $Id: BookmarkManager.java,v 1.2 2006/03/26 15:22:16 christianhujer Exp $ 429 */ 430 public static class BookmarkSeparator extends Bookmark { 431 432 /** Serial Version. */ 433 private static final long serialVersionUID = 1L; 434 435 /** Create a Bookmark Separator. */ 436 BookmarkSeparator() { 437 super("--------------------------------"); 438 } 439 440 /** {@inheritDoc} 441 * @return always <code>null</code> 442 */ 443 @Override public JMenuItem createMenu() { 444 return null; 445 } 446 447 /** {@inheritDoc} */ 448 @Override public void store(final Node n) { 449 final Element e = n.getOwnerDocument().createElement("separator"); 450 n.appendChild(e); 451 } 452 453 /** {@inheritDoc} */ 454 public void actionPerformed(final ActionEvent e) { 455 /* Do nothing */ 456 } 457 458 } // class BookmarkSeparator 459 460 461 /** Class for Bookmark Items. 462 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 463 * @version $Id: BookmarkManager.java,v 1.2 2006/03/26 15:22:16 christianhujer Exp $ 464 */ 465 public class BookmarkItem extends Bookmark { 466 467 /** Serial Version. */ 468 private static final long serialVersionUID = 1L; 469 470 /** URL of this Bookmark. 471 * @serial include 472 */ 473 private String url; 474 475 /** Create a BookmarkItem. 476 * @param title title for this BookmarkItem 477 * @param url URL for this BookmarkItem 478 */ 479 public BookmarkItem(final String title, final String url) { 480 super(title); 481 setURL(url); 482 } 483 484 /** Create a BookmarkItem from XML. 485 * @param el Element to create from 486 */ 487 BookmarkItem(final Element el) { 488 this(el.getAttribute("title"), el.getAttribute("href")); 489 } 490 491 /** Set this BookmarkItem's url. 492 * @param url new url for this BookmarkItem 493 */ 494 public void setURL(final String url) { 495 this.url = url; 496 putValue(SHORT_DESCRIPTION, url); 497 } 498 499 /** Get this BookmarkItem's url. 500 * @return BookmarkItem url 501 */ 502 public String getURL() { 503 return url; 504 } 505 506 /** {@inheritDoc} */ 507 @Override public JMenuItem createMenu() { 508 return new JMenuItem(this); 509 } 510 511 /** {@inheritDoc} */ 512 public void actionPerformed(final ActionEvent e) { 513 bookmarkable.load(url); 514 } 515 516 /** {@inheritDoc} */ 517 public void store(final Node n) { 518 final Element e = n.getOwnerDocument().createElement("bookmark"); 519 e.setAttribute("title", getTitle()); 520 e.setAttribute("href", getURL()); 521 n.appendChild(e); 522 } 523 524 } // class BookmarkItem 525 526 527 /** Class for Bookmark folders. 528 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a> 529 * @version $Id: BookmarkManager.java,v 1.2 2006/03/26 15:22:16 christianhujer Exp $ 530 */ 531 public class BookmarkFolder extends Bookmark implements Iterable<Bookmark> { 532 533 /** Serial Version. */ 534 private static final long serialVersionUID = 1L; 535 536 /** The bookmarks in this folder. 537 * @serial include 538 */ 539 private List<Bookmark> bookmarks = new ArrayList<Bookmark>(); 540 541 /** The Menus created for this folder. 542 * @serial include 543 */ 544 private List<JMenu> menus = new ArrayList<JMenu>(); 545 546 /** Create a BookmarkFolder without a title. 547 * This should only be used for the basic BookmarkFolder containing all other BookmarkItems and BookmarkFolders. 548 */ 549 public BookmarkFolder() { 550 super(ACTION_FACTORY.getString("bookmark_text")); 551 } 552 553 /** Create a BookmarkFolder. 554 * @param title title for BookmarkFolder 555 */ 556 public BookmarkFolder(final String title) { 557 super(title); 558 addBookmark.putValue(ACCELERATOR_KEY, null); 559 newBookmarkFolder.putValue(ACCELERATOR_KEY, null); 560 } 561 562 /** Create a BookmarkFolder from XML. 563 * @param doc Document to create from 564 */ 565 BookmarkFolder(final Document doc) { 566 this(); 567 readNodes(doc.getDocumentElement()); 568 } 569 570 /** Create a BookmarkFolder from XML. 571 * @param el Element to create from 572 */ 573 BookmarkFolder(final Element el) { 574 this(el.getAttribute("title")); 575 readNodes(el); 576 } 577 578 /** Read nodes from XML. 579 * @param el XML Element to read nodes from 580 */ 581 private void readNodes(final Element el) { 582 final NodeList children = el.getChildNodes(); 583 for (int i = 0; i < children.getLength(); i++) { 584 final Node n = children.item(i); 585 if (n instanceof Element) { 586 final Element e = (Element) n; 587 if ("bookmark".equals(e.getNodeName())) { 588 add(new BookmarkItem(e)); 589 } else if ("bookmarks".equals(e.getNodeName())) { 590 add(new BookmarkFolder(e)); 591 } else if ("separator".equals(e.getNodeName())) { 592 add(new BookmarkSeparator()); 593 } 594 } 595 } 596 } 597 598 /** {@inheritDoc} */ 599 public Iterator<Bookmark> iterator() { 600 return bookmarks.iterator(); 601 } 602 603 /** Add a Bookmark to this BookmarkFolder. 604 * @param bookmark Bookmark to add 605 */ 606 public void add(final Bookmark bookmark) { 607 final int pos = bookmarks.size(); 608 bookmarks.add(bookmark); 609 bookmark.setFolder(this); 610 for (JMenu menu : menus) { 611 menu.insert(bookmark.createMenu(), pos); 612 } 613 try { 614 save(); 615 } catch (final Exception e) { 616 showMessageDialog(bookmarkable.getBookmarkBlocker(), e, "Bookmarks-Fehler", ERROR_MESSAGE); 617 System.err.println(e); 618 e.printStackTrace(); 619 } 620 } 621 622 /** Insert a Bookmark into this BookmarkFolder. 623 * @param bookmark Bookmark to add 624 * @param index desired index 625 */ 626 public void insert(final Bookmark bookmark, final int index) { 627 if (index < 0 || index > bookmarks.size()) { 628 throw new IllegalArgumentException("Invalid index: " + index + " (size: " + bookmarks.size() + ")"); 629 } 630 bookmark.setFolder(this); 631 bookmarks.add(index, bookmark); 632 for (JMenu menu : menus) { 633 menu.insert(bookmark.createMenu(), index); 634 } 635 try { 636 save(); 637 } catch (final Exception e) { 638 showMessageDialog(bookmarkable.getBookmarkBlocker(), e, "Bookmarks-Fehler", ERROR_MESSAGE); 639 System.err.println(e); 640 e.printStackTrace(); 641 } 642 } 643 644 /** Remove a Bookmark from this BookmarkFolder. 645 * @param bookmark Bookmark to remove 646 */ 647 public void remove(final Bookmark bookmark) { 648 if (bookmarks.contains(bookmark)) { 649 remove(bookmarks.indexOf(bookmark)); 650 } else { 651 for (final Bookmark folder : bookmarks) { 652 if (folder instanceof BookmarkFolder) { 653 ((BookmarkFolder)folder).remove(bookmark); 654 } 655 } 656 } 657 } 658 659 /** Remove a Bookmark from this BookmarkFolder. 660 * @param index Index of Bookmark to remove 661 */ 662 @Override public void remove(final int index) { 663 final Bookmark bookmark = bookmarks.remove(index); 664 bookmark.folder = null; 665 for (JMenu menu : menus) { 666 menu.remove(index); 667 } 668 } 669 670 /** {@inheritDoc} */ 671 @Override public JMenu createMenu() { 672 final JMenu menu = new JMenu(getTitle()); 673 menu.setName(getTitle()); 674 for (Bookmark bookmark : bookmarks) { 675 if (bookmark instanceof BookmarkSeparator) { 676 menu.addSeparator(); 677 } else { 678 menu.add(bookmark.createMenu()); 679 } 680 } 681 menu.addSeparator(); 682 menu.add(new JMenuItem(addBookmark)); 683 menu.add(new JMenuItem(newBookmarkFolder)); 684 menus.add(menu); 685 return menu; 686 } 687 688 /** {@inheritDoc} */ 689 public void actionPerformed(final ActionEvent e) { 690 /* Do nothing */ 691 } 692 693 /** Action for adding a bookmark. 694 * @serial include 695 */ 696 private Action addBookmark = ACTION_FACTORY.createAction(true, "addBookmark", this); 697 698 /** Action for creating a new bookmark folder. 699 * @serial include 700 */ 701 private Action newBookmarkFolder = ACTION_FACTORY.createAction(true, "newBookmarkFolder", this); 702 703 /** Add a bookmark for the currently selected Question from the currently selected QuestionCollection . */ 704 public void addBookmark() { 705 if (bookmarkable.isBookmarkPossible()) { 706 add(new BookmarkItem(bookmarkable.getBookmarkTitle(), bookmarkable.getBookmarkURL())); 707 } 708 } 709 710 /** Create a new BookmarkFolder. */ 711 public void newBookmarkFolder() { 712 final String folderName = showInputDialog(bookmarkable.getBookmarkBlocker(), "Name für Lesezeichen", "Neuer Lesezeichen-Ordner", QUESTION_MESSAGE); 713 if (folderName == null) { 714 return; 715 } 716 add(new BookmarkFolder(folderName)); 717 } 718 719 /** Set the AddBookmark enabled state. 720 * @param enabled enabled state for AddBookmark action 721 */ 722 public void setAddBookmarkEnabled(final boolean enabled) { 723 addBookmark.setEnabled(enabled); 724 for (Bookmark folder : bookmarks) { 725 if (folder instanceof BookmarkFolder) { 726 ((BookmarkFolder)folder).setAddBookmarkEnabled(enabled); 727 } 728 } 729 } 730 731 /** {@inheritDoc} */ 732 @Override public void store(final Node n) { 733 final Element e = (n instanceof Document ? (Document) n : n.getOwnerDocument()).createElement("bookmarks"); 734 e.setAttribute("title", getTitle()); 735 n.appendChild(e); 736 for (Bookmark bookmark : bookmarks) { 737 bookmark.store(e); 738 } 739 } 740 741 /** {@inheritDoc} */ 742 public Enumeration<Bookmark> children() { 743 return Collections.enumeration(bookmarks); 744 } 745 746 /** {@inheritDoc} */ 747 @Override public boolean getAllowsChildren() { 748 return true; 749 } 750 751 /** {@inheritDoc} */ 752 @Override public Bookmark getChildAt(final int childIndex) { 753 return bookmarks.get(childIndex); 754 } 755 756 /** {@inheritDoc} */ 757 @Override public int getChildCount() { 758 return bookmarks.size(); 759 } 760 761 /** {@inheritDoc} */ 762 @Override public int getIndex(final TreeNode node) { 763 return bookmarks.indexOf(node); 764 } 765 766 /** {@inheritDoc} */ 767 @Override public boolean isLeaf() { 768 return false; 769 } 770 771 /** {@inheritDoc} */ 772 @Override public void insert(final MutableTreeNode child, final int index) { 773 if (child instanceof Bookmark) { 774 insert((Bookmark)child, index); 775 } else { 776 throw new IllegalArgumentException("Children of BookmarkFolders must be instance of Bookmark but was " + child.getClass().getName()); 777 } 778 } 779 780 ///** {@inheritDoc} */ 781 //public void remove(final int index) { 782 // remove(index); 783 //} 784 785 /** {@inheritDoc} */ 786 @Override public void remove(final MutableTreeNode child) { 787 if (child instanceof Bookmark) { 788 remove((Bookmark)child); 789 } else { 790 throw new IllegalArgumentException("Node " + child + " not child of this BookmarkFolder."); 791 } 792 } 793 794 } // class BookmarkFolder 795 796 } // class BookmarkManager