...
- Create a class
TapeViewPart
in a new packagede.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.) - Add a private field
tableViewer
of type TableViewer. Your
TableViewPart
contains a still empty methodcreatePartControl
. 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 language java title createPartControl(...) Table table = new Table(parent, SWT.BORDER); TableColumn column = new TableColumn(table, SWT.NONE); column.setWidth(80); tableViewer = new TableViewer(table);
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:Code Block title setFocus(...)tableViewer.getControl().setFocus();
...
Create a class
TuringTape
in a new packagede.cau.cs.rtprak.login.simple.model
with the following fields:Code Block language java title Fields 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.)
Add two constants to the class:
Code Block language java title Constants public static final char START_CHAR = '\u25b7'; public static final char BLANK_CHAR = '\u25fb';
- Add a method
getCharacter(int pos)
that calculates the tape character at positionpos
as follows:- For
pos == 0
, return the characterSTART_CHAR
. - For
pos > text.length()
, return the characterBLANK_CHAR
. - Otherwise, return the text character at index
pos - 1
.
- For
- Add a private field tape of type
TuringTape
toTapeViewPart
and initialize it with a new instance. - Create a class
TapeData
inde.cau.cs.rtprak.login.simple.model
with two fieldsint index
andchar character
, and add a constructor for initialization as well as corresponding getter methods. - Create a class
TapeContentProvider
in thede.cau.cs.rtprak.login.simple.views
package that implements IStructuredContentProvider.- The methods
dispose()
andinputChanged()
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 ofgetElements()
shall be an array ofTapeData
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 withi
and the result ofturingTape.getCharacter(i)
, respectively, wherei
is the array index of the element.
- The methods
- Create a class
TapeLabelProvider
in thede.cau.cs.rtprak.login.simple.views
package that extends BaseLabelProvider and implements ITableLabelProvider.- Add a private field
tape
of typeTuringTape
that is initialized from the constructor. - Add fields
presentImage
andabsentImage
of type Image. Initialize each image using the following code, where
path_to_image
isicons/head_present.gif
andicons/head_absent.gif
, respectively:Code Block language java image = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "path_to_image").createImage();
- Override the implementation of
dispose()
inTapeLabelProvider
to dispose both images after callingsuper.dispose()
. (Right-click in the source-code and click Source -> Override/Implement Methods.) - In
getColumnImage()
andgetColumnText()
, first check whether the element is an instance ofTapeData
and the column index is 0, and returnnull
otherwise. If the check passes, return the following:getColumnImage()
:presentImage
if the index given by the tape data element equals the current value oftape.getHeadPosition()
,absentImage
otherwise.getColumnText()
: aString
containing the character of the tape data element.
- Add a private field
Add the following lines to
createPartControl()
inTapeViewPart
: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.
Add the following methods to
SimpleEditorPart
:Code Block language java /* * 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; } }
Add the following code to
TapeViewPart
:Code Block language java /** 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); } }
Add the following code to
createPartControl()
:Code Block language java 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:
Get the tool bar manager using the following code:
Code Block language java IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
- 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 thetape.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
...