Child pages
  • The Plug-in Architecture of Eclipse

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Create a class TapeViewPart in a new package de.cau.cs.rtprak.login.simple.views that extends the ViewPart class. (make sure that in the New Java Class wizard, the option Inherited abstract methods is checked.)
  2. Add a private field tableViewer of type TableViewer.
  3. Your TableViewPart contains a still empty method createPartControl. This method will be responsible for creating the user interface components of your view. Add the following code to create the table we want to display:

    Code Block
    languagejava
    titlecreatePartControl(...)
    Table table = new Table(parent, SWT.BORDER);
    TableColumn column = new TableColumn(table, SWT.NONE);
    column.setWidth(80);
    tableViewer = new TableViewer(table);
  4. The setFocus method controls what happens when your part gets the focus. Make sure the focus will then automatically be set to the table by adding the following code:

    setFocus(...)
    Code Block
    title
    tableViewer.getControl().setFocus();

...

  1. Create a class TuringTape in a new package de.cau.cs.rtprak.login.simple.model with the following fields:

    Code Block
    languagejava
    titleFields
    private int headPosition = 1;
    private StringBuffer text = new StringBuffer();

    Also add corresponding getter and setter methods. (You can simply right-click somewhere in the class and choose Source -> Generate Getters and Setters.)

  2. Add two constants to the class:

    Code Block
    languagejava
    titleConstants
    public static final char START_CHAR = '\u25b7';
    public static final char BLANK_CHAR = '\u25fb';
  3. Add a method getCharacter(int pos) that calculates the tape character at position pos as follows:
    • For pos == 0, return the character START_CHAR.
    • For pos > text.length(), return the character BLANK_CHAR.
    • Otherwise, return the text character at index pos - 1.
  4. Add a private field tape of type TuringTape to TapeViewPart and initialize it with a new instance.
  5. Create a class TapeData in de.cau.cs.rtprak.login.simple.model with two fields int index and char character, and add a constructor for initialization as well as corresponding getter methods.
  6. Create a class TapeContentProvider in the de.cau.cs.rtprak.login.simple.views package that implements IStructuredContentProvider.
    • The methods dispose() and inputChanged() may remain empty.
    • The method getElements() must return an array of objects, where each object must contain all necessary data to be displayed in a single row of the table. The number of returned objects corresponds to the number of rows.
    • Suppose the input element is an instance of TuringTape. The result of getElements() shall be an array of TapeData elements. The size of the array shall be one more than the maximum of the tape head position and the length of the tape text. The index and character of each tape data element shall be filled with i and the result of turingTape.getCharacter(i), respectively, where i is the array index of the element.
  7. Create a class TapeLabelProvider in the de.cau.cs.rtprak.login.simple.views package that extends BaseLabelProvider and implements ITableLabelProvider.
    • Add a private field tape of type TuringTape that is initialized from the constructor.
    • Add fields presentImage and absentImage of type Image.
    • Initialize each image using the following code, where path_to_image is icons/head_present.gif and icons/head_absent.gif, respectively:

      Code Block
      languagejava
      image = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "path_to_image").createImage();
    • Override the implementation of dispose() in TapeLabelProvider to dispose both images after calling super.dispose(). (Right-click in the source-code and click Source -> Override/Implement Methods.)
    • In getColumnImage() and getColumnText(), first check whether the element is an instance of TapeData and the column index is 0, and return null otherwise. If the check passes, return the following:
      • getColumnImage(): presentImage if the index given by the tape data element equals the current value of tape.getHeadPosition(), absentImage otherwise.
      • getColumnText(): a String containing the character of the tape data element.
  8. Add the following lines to createPartControl() in TapeViewPart:

    Code Block
    tableViewer.setContentProvider(new TapeContentProvider());
    tableViewer.setLabelProvider(new TapeLabelProvider(tape));
    tableViewer.setInput(tape);

...

Use Simple Text Editor as Tape View Input

We will now add code to make the Tape view display the content of a currently active Simple Text Editor.

  1. Add the following methods to SimpleEditorPart:

    Code Block
    languagejava
    /*
     * Returns the text that is currently displayed in the editor.
     * @return the currently displayed text
     */
    public String getText() {
        return getDocumentProvider().getDocument(getEditorInput()).get();
    }
    /** The listener that is currently registered for this editor. */
    private IDocumentListener registeredListener;
    /**
     * Registers the given runnable as listener for changes to the text
     * of this editor.
     * @param runnable a runnable to register as text listener
     */
    public void registerTextListener(final Runnable runnable) {
        registeredListener = new IDocumentListener() {
            public void documentAboutToBeChanged(DocumentEvent event) {}
            public void documentChanged(DocumentEvent event) {
                runnable.run();
            }
        };
        getDocumentProvider().getDocument(getEditorInput())
                .addDocumentListener(registeredListener);
    }
    /**
     * Removes the last registered text listener.
     */
    public void disposeTextListener() {
        if (registeredListener != null) {
            if (getDocumentProvider() != null) {
                getDocumentProvider().getDocument(getEditorInput())
                        .removeDocumentListener(registeredListener);
            }
            registeredListener = null;
        }
    }
  2. Add the following code to TapeViewPart:

    Code Block
    languagejava
    /** The editor part that is currently set as input for the viewer. */
    private SimpleEditorPart currentInput;
    /**
     * Sets the displayed text of the given editor part as input of the
     * viewer, if the editor part is a SimpleEditorPart.
     * @param part workbench part to set as input
     */
    private void setInput(final IWorkbenchPart part) {
        if (part instanceof SimpleEditorPart && part != currentInput) {
            if (currentInput != null) {
                currentInput.disposeTextListener();
            }
            currentInput = (SimpleEditorPart) part;
            Runnable runnable = new Runnable() {
                public void run() {
                    tape.setText(new StringBuffer(currentInput.getText()));
                    tableViewer.refresh();
                }
            };
            runnable.run();
            currentInput.registerTextListener(runnable);
        }
    }
  3. Add the following code to createPartControl():

    Code Block
    languagejava
    IWorkbenchWindow workbenchWindow = getSite().getWorkbenchWindow();
    IWorkbenchPage activePage = workbenchWindow.getActivePage();
    if (activePage != null) {
        setInput(activePage.getActivePart());
    }
    workbenchWindow.getPartService().addPartListener(new IPartListener() {
            public void partActivated(final IWorkbenchPart part) {
                setInput(part);
            }
            public void partDeactivated(final IWorkbenchPart part) {}
            public void partBroughtToTop(final IWorkbenchPart part) {}
            public void partClosed(final IWorkbenchPart part) {}
            public void partOpened(final IWorkbenchPart part) {}
    });

Create Actions to Move the Tape Head

If we want to add buttons to the view's tool bar, we will have to ask its IToolbarManager to do that for us:

  1. Get the tool bar manager using the following code:

    Code Block
    languagejava
    IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
  2. Add two actions to the toolbar manager by extending the class Action and implementing the run()method.
    • It is convenient to add actions as anonymous nested classes.
    • The first action shall have the text "L". When it is run, it shall move the head to the left (to the top in the table viewer), if the head is not already at position 0.
    • The second action shall have the text "R". When it is run, it shall move the head to the right.
    • You should call tableViewer.refresh() after any change to the tape.headPosition variable.

Test the View

If you open an instance of the simple text editor and open the Tape view, the view should correctly display the editor's text on a tape, and the L and R buttons should move the tape head.

Creating an Extension Point

...