SWT Jface Eclipse Java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.CoolBarManager;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
/**
 * This class keeps track of you library, and who you've loaned books to
 */
public class Librarian extends ApplicationWindow {
  // A static instance to the running application
  private static Librarian APP;
  // Table column names/properties
  public static final String TITLE = "Title";
  public static final String CHECKED_OUT = "?";
  public static final String WHO = "By Whom";
  public static final String[] PROPS = { TITLE, CHECKED_OUT, WHO };
  // The viewer
  private TableViewer viewer;
  // The current library
  private Library library;
  // The actions
  private NewAction newAction;
  private OpenAction openAction;
  private SaveAction saveAction;
  private SaveAsAction saveAsAction;
  private ExitAction exitAction;
  private AddBookAction addBookAction;
  private RemoveBookAction removeBookAction;
  private AboutAction aboutAction;
  private ShowBookCountAction showBookCountAction;
  /**
   * Gets the running application
   */
  public static final Librarian getApp() {
    return APP;
  }
  /**
   * Librarian constructor
   */
  public Librarian() {
    super(null);
    APP = this;
    // Create the data model
    library = new Library();
    // Create the actions
    newAction = new NewAction();
    openAction = new OpenAction();
    saveAction = new SaveAction();
    saveAsAction = new SaveAsAction();
    exitAction = new ExitAction();
    addBookAction = new AddBookAction();
    removeBookAction = new RemoveBookAction();
    aboutAction = new AboutAction();
    showBookCountAction = new ShowBookCountAction();
    addMenuBar();
    addCoolBar(SWT.NONE);
    addStatusLine();
  }
  /**
   * Runs the application
   */
  public void run() {
    // Don't return from open() until window closes
    setBlockOnOpen(true);
    // Open the main window
    open();
    // Dispose the display
    Display.getCurrent().dispose();
  }
  /**
   * Configures the shell
   * 
   * @param shell
   *            the shell
   */
  protected void configureShell(Shell shell) {
    super.configureShell(shell);
    // Set the title bar text
    shell.setText("Librarian");
  }
  /**
   * Creates the main window's contents
   * 
   * @param parent
   *            the main window
   * @return Control
   */
  protected Control createContents(Composite parent) {
    Composite composite = new Composite(parent, SWT.NONE);
    composite.setLayout(new GridLayout(1, false));
    viewer = new TableViewer(composite, SWT.FULL_SELECTION | SWT.BORDER);
    Table table = viewer.getTable();
    table.setLayoutData(new GridData(GridData.FILL_BOTH));
    // Set up the viewer
    viewer.setContentProvider(new LibraryContentProvider());
    viewer.setLabelProvider(new LibraryLabelProvider());
    viewer.setInput(library);
    viewer.setColumnProperties(PROPS);
    viewer.setCellEditors(new CellEditor[] { new TextCellEditor(table),
        new CheckboxCellEditor(table), new TextCellEditor(table) });
    viewer.setCellModifier(new LibraryCellModifier());
    // Set up the table
    for (int i = 0, n = PROPS.length; i < n; i++)
      new TableColumn(table, SWT.LEFT).setText(PROPS[i]);
    table.setHeaderVisible(true);
    table.setLinesVisible(true);
    // Add code to hide or display the book count based on the action
    showBookCountAction
        .addPropertyChangeListener(new IPropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent event) {
            // The value has changed; refresh the view
            refreshView();
          }
        });
    // Rfresh the view to get the columns right-sized
    refreshView();
    return composite;
  }
  /**
   * Creates the menu for the application
   * 
   * @return MenuManager
   */
  protected MenuManager createMenuManager() {
    // Create the main menu
    MenuManager mm = new MenuManager();
    // Create the File menu
    MenuManager fileMenu = new MenuManager("File");
    mm.add(fileMenu);
    // Add the actions to the File menu
    fileMenu.add(newAction);
    fileMenu.add(openAction);
    fileMenu.add(saveAction);
    fileMenu.add(saveAsAction);
    fileMenu.add(new Separator());
    fileMenu.add(exitAction);
    // Create the Book menu
    MenuManager bookMenu = new MenuManager("Book");
    mm.add(bookMenu);
    // Add the actions to the Book menu
    bookMenu.add(addBookAction);
    bookMenu.add(removeBookAction);
    // Create the View menu
    MenuManager viewMenu = new MenuManager("View");
    mm.add(viewMenu);
    // Add the actions to the View menu
    viewMenu.add(showBookCountAction);
    // Create the Help menu
    MenuManager helpMenu = new MenuManager("Help");
    mm.add(helpMenu);
    // Add the actions to the Help menu
    helpMenu.add(aboutAction);
    return mm;
  }
  /**
   * Creates the toolbar for the application
   */
  protected ToolBarManager createToolBarManager(int style) {
    // Create the toolbar manager
    ToolBarManager tbm = new ToolBarManager(style);
    // Add the file actions
    tbm.add(newAction);
    tbm.add(openAction);
    tbm.add(saveAction);
    tbm.add(saveAsAction);
    // Add a separator
    tbm.add(new Separator());
    // Add the book actions
    tbm.add(addBookAction);
    tbm.add(removeBookAction);
    // Add a separator
    tbm.add(new Separator());
    // Add the show book count, which will appear as a toggle button
    tbm.add(showBookCountAction);
    // Add a separator
    tbm.add(new Separator());
    // Add the about action
    tbm.add(aboutAction);
    return tbm;
  }
  /**
   * Creates the coolbar for the application
   */
  protected CoolBarManager createCoolBarManager(int style) {
    // Create the coolbar manager
    CoolBarManager cbm = new CoolBarManager(style);
    // Add the toolbar
    cbm.add(createToolBarManager(SWT.FLAT));
    return cbm;
  }
  /**
   * Creates the status line manager
   */
  protected StatusLineManager createStatusLineManager() {
    return new StatusLineManager();
  }
  /**
   * Adds a book
   */
  public void addBook() {
    library.add(new Book("[Enter Title]"));
    refreshView();
  }
  /**
   * Removes the selected book
   */
  public void removeSelectedBook() {
    Book book = (Book) ((IStructuredSelection) viewer.getSelection())
        .getFirstElement();
    if (book != null)
      library.remove(book);
    refreshView();
  }
  /**
   * Opens a file
   * 
   * @param fileName
   *            the file name
   */
  public void openFile(final String fileName) {
    if (checkOverwrite()) {
      // Disable the actions, so user can't change library while loading
      enableActions(false);
      library = new Library();
      try {
        // Launch the Open runnable
        ModalContext.run(new IRunnableWithProgress() {
          public void run(IProgressMonitor progressMonitor) {
            try {
              progressMonitor.beginTask("Loading",
                  IProgressMonitor.UNKNOWN);
              library.load(fileName);
              progressMonitor.done();
              viewer.setInput(library);
              refreshView();
            } catch (IOException e) {
              showError("Can't load file " + fileName + "\r"
                  + e.getMessage());
            }
          }
        }, true, getStatusLineManager().getProgressMonitor(),
            getShell().getDisplay());
      } catch (InterruptedException e) {
      } catch (InvocationTargetException e) {
      } finally {
        // Enable actions
        enableActions(true);
      }
    }
  }
  /**
   * Creates a new file
   */
  public void newFile() {
    if (checkOverwrite()) {
      library = new Library();
      viewer.setInput(library);
    }
  }
  /**
   * Saves the current file
   */
  public void saveFile() {
    String fileName = library.getFileName();
    if (fileName == null) {
      fileName = new SafeSaveDialog(getShell()).open();
    }
    saveFileAs(fileName);
  }
  /**
   * Saves the current file using the specified file name
   * 
   * @param fileName
   *            the file name
   */
  public void saveFileAs(final String fileName) {
    // Disable the actions, so user can't change file while it's saving
    enableActions(false);
    try {
      // Launch the Save runnable
      ModalContext.run(new IRunnableWithProgress() {
        public void run(IProgressMonitor progressMonitor) {
          try {
            progressMonitor.beginTask("Saving",
                IProgressMonitor.UNKNOWN);
            library.save(fileName);
            progressMonitor.done();
          } catch (IOException e) {
            showError("Can't save file " + library.getFileName()
                + "\r" + e.getMessage());
          }
        }
      }, true, getStatusLineManager().getProgressMonitor(), getShell()
          .getDisplay());
    } catch (InterruptedException e) {
    } catch (InvocationTargetException e) {
    } finally {
      // Enable the actions
      enableActions(true);
    }
  }
  /**
   * Shows an error
   * 
   * @param msg
   *            the error
   */
  public void showError(String msg) {
    MessageDialog.openError(getShell(), "Error", msg);
  }
  /**
   * Refreshes the view
   */
  public void refreshView() {
    // Refresh the view
    viewer.refresh();
    // Repack the columns
    for (int i = 0, n = viewer.getTable().getColumnCount(); i < n; i++) {
      viewer.getTable().getColumn(i).pack();
    }
    getStatusLineManager().setMessage(
        showBookCountAction.isChecked() ? "Book Count: "
            + library.getBooks().size() : "");
  }
  /**
   * Checks the current file for unsaved changes. If it has unsaved changes,
   * confirms that user wants to overwrite
   * 
   * @return boolean
   */
  public boolean checkOverwrite() {
    boolean proceed = true;
    if (library.isDirty()) {
      proceed = MessageDialog
          .openConfirm(getShell(), "Are you sure?",
              "You have unsaved changes--are you sure you want to lose them?");
    }
    return proceed;
  }
  /**
   * Sets the current library dirty
   */
  public void setLibraryDirty() {
    library.setDirty();
  }
  /**
   * Closes the application
   */
  public boolean close() {
    if (checkOverwrite())
      return super.close();
    return false;
  }
  /**
   * Enables or disables the actions
   * 
   * @param enable
   *            true to enable, false to disable
   */
  private void enableActions(boolean enable) {
    newAction.setEnabled(enable);
    openAction.setEnabled(enable);
    saveAction.setEnabled(enable);
    saveAsAction.setEnabled(enable);
    exitAction.setEnabled(enable);
    addBookAction.setEnabled(enable);
    removeBookAction.setEnabled(enable);
    aboutAction.setEnabled(enable);
    showBookCountAction.setEnabled(enable);
  }
  /**
   * The application entry point
   * 
   * @param args
   *            the command line arguments
   */
  public static void main(String[] args) {
    new Librarian().run();
  }
}
/**
 * This class holds all the books in a library. It also handles loading from and
 * saving to disk
 */
class Library {
  private static final String SEP = "|";
  // The filename
  private String filename;
  // The books
  private Collection books;
  // The dirty flag
  private boolean dirty;
  /**
   * Library constructor Note the signature :-)
   */
  public Library() {
    books = new LinkedList();
  }
  /**
   * Loads the library from a file
   * 
   * @param filename
   *            the filename
   * @throws IOException
   */
  public void load(String filename) throws IOException {
    BufferedReader in = new BufferedReader(new LineNumberReader(
        new FileReader(filename)));
    String line;
    while ((line = in.readLine()) != null) {
      StringTokenizer st = new StringTokenizer(line, SEP);
      Book book = null;
      if (st.hasMoreTokens())
        book = new Book(st.nextToken());
      if (st.hasMoreTokens())
        book.checkOut(st.nextToken());
      if (book != null)
        add(book);
    }
    in.close();
    this.filename = filename;
    dirty = false;
  }
  /**
   * Saves the library to a file
   * 
   * @param filename
   *            the filename
   * @throws IOException
   */
  public void save(String filename) throws IOException {
    BufferedWriter out = new BufferedWriter(new FileWriter(filename));
    for (Iterator itr = books.iterator(); itr.hasNext();) {
      Book book = (Book) itr.next();
      out.write(book.getTitle());
      out.write('|');
      out.write(book.getCheckedOutTo() == null ? "" : book
          .getCheckedOutTo());
      out.write('\r');
    }
    out.close();
    this.filename = filename;
    dirty = false;
  }
  /**
   * Adds a book
   * 
   * @param book
   *            the book to add
   * @return boolean
   */
  public boolean add(Book book) {
    boolean added = books.add(book);
    if (added)
      setDirty();
    return added;
  }
  /**
   * Removes a book
   * 
   * @param book
   *            the book to remove
   */
  public void remove(Book book) {
    books.remove(book);
    setDirty();
  }
  /**
   * Gets the books
   * 
   * @return Collection
   */
  public Collection getBooks() {
    return Collections.unmodifiableCollection(books);
  }
  /**
   * Gets the file name
   * 
   * @return String
   */
  public String getFileName() {
    return filename;
  }
  /**
   * Gets whether this file is dirty
   * 
   * @return boolean
   */
  public boolean isDirty() {
    return dirty;
  }
  /**
   * Sets this file as dirty
   */
  public void setDirty() {
    dirty = true;
  }
}
/**
 * This action class deletes a book
 */
class RemoveBookAction extends Action {
  /**
   * RemoveBookAction constructor
   */
  public RemoveBookAction() {
    super("&Remove Book@Ctrl+X", ImageDescriptor.createFromFile(
        RemoveBookAction.class, "/images/removeBook.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        RemoveBookAction.class, "/images/disabledRemoveBook.gif"));
    setToolTipText("Remove");
  }
  /**
   * Removes the selected book after confirming
   */
  public void run() {
    if (MessageDialog.openConfirm(Librarian.getApp().getShell(),
        "Are you sure?",
        "Are you sure you want to remove the selected book?")) {
      Librarian.getApp().removeSelectedBook();
    }
  }
}
/**
 * This action class responds to requests open a file
 */
class OpenAction extends Action {
  /**
   * OpenAction constructor
   */
  public OpenAction() {
    super("&Open...@Ctrl+O", ImageDescriptor.createFromFile(
        OpenAction.class, "/images/open.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        OpenAction.class, "/images/disabledOpen.gif"));
    setToolTipText("Open");
  }
  /**
   * Opens an existing file
   */
  public void run() {
    // Use the file dialog
    FileDialog dlg = new FileDialog(Librarian.getApp().getShell(), SWT.OPEN);
    String fileName = dlg.open();
    if (fileName != null) {
      Librarian.getApp().openFile(fileName);
    }
  }
}
/**
 * This action class adds a book
 */
class AddBookAction extends Action {
  /**
   * AddBookAction constructor
   */
  public AddBookAction() {
    super("&Add Book@Ctrl+B", ImageDescriptor.createFromFile(
        AddBookAction.class, "/images/addBook.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        AddBookAction.class, "/images/disabledAddBook.gif"));
    setToolTipText("Add");
  }
  /**
   * Adds a book to the current library
   */
  public void run() {
    Librarian.getApp().addBook();
  }
}
/**
 * This action class exits the application
 */
class ExitAction extends Action {
  /**
   * ExitAction constructor
   */
  public ExitAction() {
    super("E&xit@Alt+F4");
    setToolTipText("Exit");
  }
  /**
   * Exits the application
   */
  public void run() {
    Librarian.getApp().close();
  }
}
/**
 * This action class reponds to requests for a new file
 */
class NewAction extends Action {
  /**
   * NewAction constructor
   */
  public NewAction() {
    super("&New@Ctrl+N", ImageDescriptor.createFromFile(NewAction.class,
        "/images/new.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        NewAction.class, "/images/disabledNew.gif"));
    setToolTipText("New");
  }
  /**
   * Creates a new file
   */
  public void run() {
    Librarian.getApp().newFile();
  }
}
/**
 * This action class responds to requests to save a file
 */
class SaveAction extends Action {
  /**
   * SaveAction constructor
   */
  public SaveAction() {
    super("&Save@Ctrl+S", ImageDescriptor.createFromFile(SaveAction.class,
        "/images/save.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        SaveAction.class, "/images/disabledSave.gif"));
    setToolTipText("Save");
  }
  /**
   * Saves the file
   */
  public void run() {
    Librarian.getApp().saveFile();
  }
}
/**
 * This action class responds to requests to save a file as . . .
 */
class SaveAsAction extends Action {
  /**
   * SaveAsAction constructor
   */
  public SaveAsAction() {
    super("Save As...", ImageDescriptor.createFromFile(SaveAsAction.class,
        "/images/saveAs.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        SaveAsAction.class, "/images/disabledSaveAs.gif"));
    setToolTipText("Save As");
  }
  /**
   * Saves the file
   */
  public void run() {
    SafeSaveDialog dlg = new SafeSaveDialog(Librarian.getApp().getShell());
    String fileName = dlg.open();
    if (fileName != null) {
      Librarian.getApp().saveFileAs(fileName);
    }
  }
}
/**
 * This action class determines whether to show the book count
 */
class ShowBookCountAction extends Action {
  public ShowBookCountAction() {
    super("&Show Book Count@Ctrl+C", IAction.AS_CHECK_BOX);
    setChecked(true);
    setImageDescriptor(ImageDescriptor.createFromFile(
        ShowBookCountAction.class, "/images/count.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        ShowBookCountAction.class, "/images/disabledCount.gif"));
  }
}
/**
 * This action class shows an About box
 */
class AboutAction extends Action {
  /**
   * AboutAction constructor
   */
  public AboutAction() {
    super("&About@Ctrl+A", ImageDescriptor.createFromFile(
        AboutAction.class, "/images/about.gif"));
    setDisabledImageDescriptor(ImageDescriptor.createFromFile(
        AboutAction.class, "/images/disabledAbout.gif"));
    setToolTipText("About");
  }
  /**
   * Shows an about box
   */
  public void run() {
    MessageDialog.openInformation(Librarian.getApp().getShell(), "About",
        "Librarian--to manage your books");
  }
}
/**
 * This class provides a facade for the "save" FileDialog class. If the selected
 * file already exists, the user is asked to confirm before overwriting.
 */
class SafeSaveDialog {
  // The wrapped FileDialog
  private FileDialog dlg;
  /**
   * SafeSaveDialog constructor
   * 
   * @param shell
   *            the parent shell
   */
  public SafeSaveDialog(Shell shell) {
    dlg = new FileDialog(shell, SWT.SAVE);
  }
  public String open() {
    // We store the selected file name in fileName
    String fileName = null;
    // The user has finished when one of the
    // following happens:
    // 1) The user dismisses the dialog by pressing Cancel
    // 2) The selected file name does not exist
    // 3) The user agrees to overwrite existing file
    boolean done = false;
    while (!done) {
      // Open the File Dialog
      fileName = dlg.open();
      if (fileName == null) {
        // User has cancelled, so quit and return
        done = true;
      } else {
        // User has selected a file; see if it already exists
        File file = new File(fileName);
        if (file.exists()) {
          // The file already exists; asks for confirmation
          MessageBox mb = new MessageBox(dlg.getParent(),
              SWT.ICON_WARNING | SWT.YES | SWT.NO);
          // We really should read this string from a
          // resource bundle
          mb.setMessage(fileName
              + " already exists. Do you want to replace it?");
          // If they click Yes, we're done and we drop out. If
          // they click No, we redisplay the File Dialog
          done = mb.open() == SWT.YES;
        } else {
          // File does not exist, so drop out
          done = true;
        }
      }
    }
    return fileName;
  }
  public String getFileName() {
    return dlg.getFileName();
  }
  public String[] getFileNames() {
    return dlg.getFileNames();
  }
  public String[] getFilterExtensions() {
    return dlg.getFilterExtensions();
  }
  public String[] getFilterNames() {
    return dlg.getFilterNames();
  }
  public String getFilterPath() {
    return dlg.getFilterPath();
  }
  public void setFileName(String string) {
    dlg.setFileName(string);
  }
  public void setFilterExtensions(String[] extensions) {
    dlg.setFilterExtensions(extensions);
  }
  public void setFilterNames(String[] names) {
    dlg.setFilterNames(names);
  }
  public void setFilterPath(String string) {
    dlg.setFilterPath(string);
  }
  public Shell getParent() {
    return dlg.getParent();
  }
  public int getStyle() {
    return dlg.getStyle();
  }
  public String getText() {
    return dlg.getText();
  }
  public void setText(String string) {
    dlg.setText(string);
  }
}
/**
 * This class represents a book
 */
class Book {
  private String title;
  private String checkedOutTo;
  /**
   * Book constructor
   * 
   * @param title
   *            the title
   */
  public Book(String title) {
    setTitle(title);
  }
  /**
   * Sets the title
   * 
   * @param title
   *            the title
   */
  public void setTitle(String title) {
    this.title = title;
  }
  /**
   * Gets the title
   * 
   * @return String
   */
  public String getTitle() {
    return title;
  }
  /**
   * Check out
   * 
   * @param who
   *            the person checking this book out
   */
  public void checkOut(String who) {
    checkedOutTo = who;
    if (checkedOutTo.length() == 0)
      checkedOutTo = null;
  }
  public boolean isCheckedOut() {
    return checkedOutTo != null && checkedOutTo.length() > 0;
  }
  public void checkIn() {
    checkedOutTo = null;
  }
  /**
   * Gets who this book is checked out to
   * 
   * @return String
   */
  public String getCheckedOutTo() {
    return checkedOutTo;
  }
}
/**
 * This class provides the labels for the library table
 */
class LibraryLabelProvider implements ITableLabelProvider {
  private Image checked;
  private Image unchecked;
  /**
   * LibraryLabelProvider constructor
   */
  public LibraryLabelProvider() {
    // Create the check mark images
    checked = new Image(null, LibraryLabelProvider.class
        .getResourceAsStream("/images/checked.gif"));
    unchecked = new Image(null, LibraryLabelProvider.class
        .getResourceAsStream("/images/unchecked.gif"));
  }
  /**
   * Gets the column image
   * 
   * @param element
   *            the book
   * @param columnIndex
   *            the column index
   * @return Image
   */
  public Image getColumnImage(Object element, int columnIndex) {
    // For the "Checked Out" column, return the check mark
    // if the book is checked out
    if (columnIndex == 1)
      return ((Book) element).isCheckedOut() ? checked : unchecked;
    return null;
  }
  /**
   * Gets the column text
   * 
   * @param element
   *            the book
   * @param columnIndex
   *            the column index
   * @return String
   */
  public String getColumnText(Object element, int columnIndex) {
    Book book = (Book) element;
    String text = null;
    switch (columnIndex) {
    case 0:
      text = book.getTitle();
      break;
    case 2:
      text = book.getCheckedOutTo();
      break;
    }
    return text == null ? "" : text;
  }
  /**
   * Adds a listener
   */
  public void addListener(ILabelProviderListener listener) {
    // Ignore
  }
  /**
   * Disposes any resources
   */
  public void dispose() {
    if (checked != null)
      checked.dispose();
    if (unchecked != null)
      unchecked.dispose();
  }
  /**
   * Gets whether this is a label property
   * 
   * @param element
   *            the book
   * @param property
   *            the property
   * @return boolean
   */
  public boolean isLabelProperty(Object element, String property) {
    return false;
  }
  /**
   * Removes a listener
   * 
   * @param listener
   *            the listener
   */
  public void removeListener(ILabelProviderListener listener) {
    // Ignore
  }
}
/**
 * This class provides the content for the library table
 */
class LibraryContentProvider implements IStructuredContentProvider {
  /**
   * Gets the books
   * 
   * @param inputElement
   *            the library
   * @return Object[]
   */
  public Object[] getElements(Object inputElement) {
    return ((Library) inputElement).getBooks().toArray();
  }
  /**
   * Disposes any resources
   */
  public void dispose() {
    // Do nothing
  }
  /**
   * Called when the input changes
   * 
   * @param viewer
   *            the viewer
   * @param oldInput
   *            the old library
   * @param newInput
   *            the new library
   */
  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    // Ignore
  }
}
/**
 * This class is the cell modifier for the Librarian program
 */
class LibraryCellModifier implements ICellModifier {
  /**
   * Gets whether the specified property can be modified
   * 
   * @param element
   *            the book
   * @param property
   *            the property
   * @return boolean
   */
  public boolean canModify(Object element, String property) {
    return true;
  }
  /**
   * Gets the value for the property
   * 
   * @param element
   *            the book
   * @param property
   *            the property
   * @return Object
   */
  public Object getValue(Object element, String property) {
    Book book = (Book) element;
    if (Librarian.TITLE.equals(property))
      return book.getTitle();
    else if (Librarian.CHECKED_OUT.equals(property))
      return Boolean.valueOf(book.isCheckedOut());
    else if (Librarian.WHO.equals(property))
      return book.getCheckedOutTo() == null ? "" : book.getCheckedOutTo();
    else
      return null;
  }
  /**
   * Modifies the element
   * 
   * @param element
   *            the book
   * @param property
   *            the property
   * @param value
   *            the new value
   */
  public void modify(Object element, String property, Object value) {
    if (element instanceof Item)
      element = ((Item) element).getData();
    Book book = (Book) element;
    if (Librarian.TITLE.equals(property))
      book.setTitle((String) value);
    else if (Librarian.CHECKED_OUT.equals(property)) {
      boolean b = ((Boolean) value).booleanValue();
      if (b)
        book.checkOut("[Enter Name]");
      else
        book.checkIn();
    } else if (Librarian.WHO.equals(property))
      book.checkOut((String) value);
    // Refresh the view
    Librarian.getApp().refreshView();
    // Set the library dirty
    Librarian.getApp().setLibraryDirty();
  }
}