... | ... | @@ -2,7 +2,7 @@ This page tries to give information about which concepts one should respect when |
|
|
|
|
|
# Writing your own view for ATHEN on the example of the CorefView
|
|
|
|
|
|
We go through the details of creating your own view, using the CoreferenceView. At first one needs to be able to get your own view displayed by ATHEN, this is covered in a different tutorial. If you want to archive this, please refer to - [ATHEN - Integrating your own view](ATHEN - how to integrate your own view)
|
|
|
We go through the details of creating your own view, using the CoreferenceView. At first one needs to be able to get your own view displayed by ATHEN, this is covered in a different tutorial. If you want to achieve this, please refer to - [ATHEN - Integrating your own view](ATHEN - how to integrate your own view)
|
|
|
|
|
|
So this page assumes you are able to display your own view already, and have it listening and reacting to the main editor. The following section describes how to properly (as of my **current** opinion) structure your view.
|
|
|
|
... | ... | @@ -12,7 +12,7 @@ So this page assumes you are able to display your own view already, and have it |
|
|
Your view (which is the class that is displayed) should always have its own project!
|
|
|
Furthermore, you need to understand my intention of a view like this:
|
|
|
|
|
|
The class of the view serves as the glue between the layout of the view and the editor. The view class itself should therefore only contain a single UI reference (the actual view). The class now server the purpose of a **controller** between the view (the UI Element) and the model (which is the CAS object, accessible using the editor) This process id depicted as follows:
|
|
|
The class of the view serves as the glue between the layout of the view and the editor. The view class itself should therefore only contain a single UI reference (the actual view). The class now serves the purpose of a **controller** between the view (the UI Element) and the model (which is the CAS object, accessible using the editor) This process is depicted as follows:
|
|
|
|
|
|
|
|
|
|
... | ... | @@ -63,7 +63,7 @@ All the code does, is to create a new widget (the corefViewComposite), and set i |
|
|
corefViewComposite.setInput(this);
|
|
|
```
|
|
|
|
|
|
So the view can store this reference of the controller and communicate with it. The next step is to actually write the UI Element. In this tutorial i am only going to address this using eclipse SWT, but it should be equally possible using AWT,Swing or JavaFX.
|
|
|
So the view can store this reference of the controller and communicate with it. The next step is to actually write the UI Element. In this tutorial i am only going to address this using eclipse SWT, but it should be equally possible using AWT, Swing or JavaFX.
|
|
|
|
|
|
|
|
|
```java
|
... | ... | @@ -120,7 +120,7 @@ The snippet shows the implementation of the UI element, let us elaborate it a bi |
|
|
public class CorefViewComposite extends Composite {
|
|
|
```
|
|
|
|
|
|
Then we got the fields that are stored in this view. As you can see, there is a reference to the controller object. The next three variables present new Composites (aka UI parts) themselfes. Separating them in this way keeps the code clean, as well as it helps you to have an easy understanding of the layout in which those elements are arranged (it is very easy to order three elements, managing all at once is extremely difficult sometimes). In this view we got three sub-composites. If you go back to the image of the result, the first is the block with all the buttons. The second one contains just two checkboxes. And the last one contains the table and its header.
|
|
|
Then we got the fields that are stored in this view. As you can see, there is a reference to the controller object. The next three variables present new Composites (aka UI parts) themselves. Separating them in this way keeps the code clean, as well as it helps you to have an easy understanding of the layout in which those elements are arranged (it is very easy to order three elements, managing all at once is extremely difficult sometimes). In this view we got three sub-composites. If you go back to the image of the result, the first is the block with all the buttons. The second one contains just two checkboxes. And the last one contains the table and its header.
|
|
|
|
|
|
```java
|
|
|
private CorefView part;
|
... | ... | @@ -160,7 +160,7 @@ I usually split the method setInput into 3 parts. The first saves the arguments, |
|
|
}
|
|
|
```
|
|
|
|
|
|
This is followed by the actual implementation of the initLayout-method. Thisattaches a layout to ourselfes and creates the three contained Composites, as well as sets their input in exactly the same way.
|
|
|
This is followed by the actual implementation of the initLayout-method. This attaches a layout to ourselves and creates the three contained Composites, as well as sets their input in exactly the same way.
|
|
|
|
|
|
```java
|
|
|
private void initLayout() {
|
... | ... | @@ -189,11 +189,11 @@ Last but not least, a refresh method is created, which is invoked by the control |
|
|
}
|
|
|
```
|
|
|
|
|
|
With this, the first part of the UI is done, we can now check a sub component. (this tutorial does not go thorugh all of the code, it just does this until all principles are introduced once)
|
|
|
With this, the first part of the UI is done, we can now check a sub component. (this tutorial does not go through all of the code, it just does this until all principles are introduced once)
|
|
|
|
|
|
### The Button Composite *CorefViewButtonComposite*
|
|
|
|
|
|
Since so far, there was no example of how to actually communicate with the controller we take a look at the button composite
|
|
|
Since so far, there was no example of how to actually communicate with the controller. We take a look at the button composite
|
|
|
|
|
|
```java
|
|
|
public class CorefViewButtonComposite extends Composite {
|
... | ... | @@ -284,7 +284,7 @@ public class CorefViewButtonComposite extends Composite { |
|
|
|
|
|
```
|
|
|
|
|
|
This class follows strictly the previously introduced concept of having a method to set the input, to init the layout, a another one to register the handler to the UI elements. The last method is the focus of this current discussion. As you can see, structuring your code this way, makes it very easy to read and clean. Since all of those buttons are active all the time and completely independent of the current state of the model, we do not need a refresh method in here. Lets take a closer look at the method to register the event handler:
|
|
|
This class follows strictly the previously introduced concept of having a method to set the input, to init the layout, and another one to register the handler to the UI elements. The last method is the focus of this current discussion. As you can see, structuring your code this way, makes it very easy to read and clean. Since all of those buttons are active all the time and completely independent of the current state of the model, we do not need a refresh method in here. Lets take a closer look at the method to register the event handler:
|
|
|
|
|
|
```java
|
|
|
private void initEventHandler() {
|
... | ... | @@ -306,10 +306,10 @@ This class follows strictly the previously introduced concept of having a method |
|
|
|
|
|
```
|
|
|
|
|
|
On all those buttons, a selectionlistener is added. Thanks to Java8 this can be done in a very clean fashion. And all those handler should do, is to call a method in the controller! The controller takes care of the rest.
|
|
|
On all those buttons, a selectionlistener is added. Thanks to Java8 this can be done in a very clean fashion. What all those handler should do, is to call a method in the controller! The controller takes care of the rest.
|
|
|
|
|
|
Following this paradigm, the model will never appear in the UI composites, and the UI only delegates everything that needs some thinking right to the controller. I encourage you to make use of Java8 to register your Listener.
|
|
|
This does not only save code, but also keeps the code clean. Another use-case where you can see its advantage is when you create a table and add its columns. The code is usually extremely long. But thanks to java8 (and its possibility ot pass methods as parameters) you can create table columsn like this:
|
|
|
This does not only save code, but also keeps the code clean. Another use-case where you can see its advantage is when you create a table and add its columns. The code is usually extremely long. But thanks to java8 (and its possibility to pass methods as parameters) you can create table columns like this:
|
|
|
|
|
|
```java
|
|
|
private void createColumns(TableViewer viewer) {
|
... | ... | @@ -377,7 +377,7 @@ By definition, this class needs to implement two methods (as defined by its supe |
|
|
|
|
|
We saw already how to implement one of them, and will now go into detail on how to implement the method to initialize the types we need in our view.
|
|
|
|
|
|
Additionally, you should implement three more methods to ensure that your view intefrates nicely into the communication framework with the editor. Sadly it is not possible to (or i dont know how to) get those calls in the super class to fully ease up this process. The eclipse framework does not use **abstract** classes for inheritance, instead makes use of annotations (@Inject, @Postconstruct, @Focus). This relatively new concept allows inheritance without the class to even know its abstract superclass, and therefore decouples them almost entirely. The bad news is that the "parent" class now needs to know all its children. The eclipse framework however only knows those classes that are part of the application model, and this is specified in the **application.e4xmi**. We cannot specifiy the abstract class in there and this is why the calls need to be done in every view.
|
|
|
Additionally, you should implement three more methods to ensure that your view intefrates nicely into the communication framework with the editor. Sadly it is not possible to (or I dont know how to) get those calls in the super class to fully ease up this process. The eclipse framework does not use **abstract** classes for inheritance, instead makes use of annotations (@Inject, @Postconstruct, @Focus). This relatively new concept allows inheritance without the class to even know its abstract superclass, and therefore decouples them almost entirely. The bad news is that the "parent" class now needs to know all its children. The eclipse framework however only knows those classes that are part of the application model, and this is specified in the **application.e4xmi**. We cannot specifiy the abstract class in there and this is why the calls need to be done in every view.
|
|
|
|
|
|
```java
|
|
|
@Inject
|
... | ... | @@ -402,7 +402,7 @@ Additionally, you should implement three more methods to ensure that your view i |
|
|
}
|
|
|
```
|
|
|
|
|
|
We now focus this tutorial on the second method **initTypes()**. Its purpose is to access the required type and feature information of the CAS to be able to add new annotations or change them. This method shoudl as well be used, to assign a given style to the types and feature you use. With the upcoming changes to ATHEN (this does not work currently), the method could look like this:
|
|
|
We now focus this tutorial on the second method **initTypes()**. Its purpose is to access the required type and feature information of the CAS to be able to add new annotations or change them. This method should as well be used, to assign a given style to the types and features you use. With the upcoming changes to ATHEN (this does not work currently), the method could look like this:
|
|
|
|
|
|
```java
|
|
|
@Override
|
... | ... | @@ -414,7 +414,7 @@ We now focus this tutorial on the second method **initTypes()**. Its purpose is |
|
|
|
|
|
```
|
|
|
|
|
|
This method looks yet again extremely clean, since it only has a single method, and guess what you dont even need to implement this function since it is already there. If we want to elaborate on this method we need to understand the concepts and the power of annotations.
|
|
|
This method looks yet again extremely clean, since it only has a single method, and guess what you don't even need to implement this function since it is already there. If we want to elaborate on this method we need to understand the concepts and the power of annotations.
|
|
|
|
|
|
TODO since the implementation is not finished yet!
|
|
|
|
... | ... | |