Upload
hanguyet
View
237
Download
0
Embed Size (px)
Citation preview
Seite 1
RCP TutorialTh Letschert
© Th Letschert
Seite 2
RCP-Anwendung
Th Letschert
RCP-Anwendungen
Eclipse
Plattform für EntwicklungswerkzeugeAb 2.1: auch Plattform für Desktop- (Rich-Client-) -Anwendungen
Anwendung auf Basis der Eclipse-Plattform
RCP-Anwendung = Anwendungslogik als Plugin(s) + Eclipse-RCP (“Basis-Eclipse“)
RCP-Anwendung erstellen:
Plugin(s) entwickeln und testen (mit Eclipse)
als RCP-Anwendnung exportieren
Basiert auf: - http://www.vogella.de/articles/RichClientPlatform/article.html - http://www.vogella.de/articles/EclipseDataBinding/index.html - B. Daum, Rich-Client-Entwicklung mit Eclipse 3.3
Seite 3
RCP-Anwendung erstellen und auführen
Th Letschert
Eine erste RCP-Anwendung erstellen
Plugin-Projekt anlegenNew Project ~> Plugin Project z.B.: MyFirstRCPApp
Rich Client Application ? ~> yes !
Template ~> Hello RPC
Add Branding ? ~> yes !
In Application.java einfügen:public static final String PLUGIN_ID = "MyFirstRCPApp";
TestenHauptfenster des Projekts (MyFirstRCPApp):
~> Overview Tab (unten) :Testing : Launch an Eclipse Application
Applikation erstellenplugin.xml -> Run As -> Run Configurations
Tab Arguments: -consoleLog hinzufügen
File ~> new ~> Product Configuration: Filename angeben
File ~> Export ~> Plugin Development ~> Eclipse Product: Zielverzeichnis angeben
Im Zielverzeichnis ist die Anwendung im Verzeichnis eclipse als ausführbare Datei
Seite 4
RCP Beispiel SimpleMath
Th Letschert
RCP-Beispiel-Anwendung SimpleMath erstellen
Plugin-Projekt anlegenNew Project ~> Plugin Project: SimpleMath
Rich Client Application ? ~> yes !
Template ~> RCP Application with a View
Add Branding ? ~> yes !
Das Plugin wird die Eclipse-Workbench mit einer View-Komponente erweitern
In Application.java einfügen:public static final String PLUGIN_ID = "SimpleMath";
Plugin.xml anklicken:Zeigt Informationen zur Applikation (Tabs am unteren Rand beachten)Tab Overview auswählen => allgeime Info / Einstieg in spezielle ThemenAufbereitung der Konfigurationsdateien
plugin.xmlManifest.MF
Die RCP-Anwendung SimpleMath basiert auf Eclipse Core zu der sie ein Plugin als anwednungsspezifische Erweiterung beisteuert.
Seite 5
RCP
Th Letschert
Plugin-Struktur:
Extensions Points und Extensions
Seite 6
RCP Beispiel: plugin.xml / zentrale Konfiguration
Th Letschert
Starten
View
plugin.xml
Seite 7
Extensions
Th Letschert
Extension Points und Extensions: Beispiel org.eclipse.core.runtime.applications
Plugins können Extension-Points definieren. Der Extension-Point org.eclipse.core.runtime.applications ist in Eclipse Core definiert.Zum Extension-Point org.eclipse.core.runtime.applications gehört das Interface org.eclipse.equinox.app.IApplication An einen Extension-Point wird eine Extension angedockt. Dazu wird eine Klasse zur Verfügung gestellt, die das Interface implementiert.
Eclipse Core
Extension-Point
PluginExtension
<plugin> <extension id="application" point="org.eclipse.core.runtime.applications"> <application> <run class="simplemath.Application"> </run> </application> </extension> ···</plugin>
plugin.xml, Konfigurationsdatei des Plugins, definiert die von diesem Plugin definierten Extensions. Eine Extension ist: Die Klasse simplemath.Application
implementiert das Interface das mit dem Extension-Pointorg.eclipse.core.runtime.applications verbunden ist
IApplication
Application
<<implements>>
implementiert
aktiviert
Definiert Interface
Implementiert Interface
Seite 8
Extensions
Extension Point und Extension
Im Tab Extensions finden sich die von diesem Plugin definierten Extensionsunter den Extension Points denen sie zugeordnet sind.
Extension Points, an die dieses Plugin „andockt“
Extension Info zum ausgewählten
Extension Point
Seite 9
Extension-Points
Extension-Points Übersicht
Das Plugin erweitert die Eclipse-Plattform und dockt dabei an folgende wichtige Extension-Points an:
org.eclipse.core.runtime.applications Primärer Einstiegspunkt in die Applikation
org.eclipse.ui.perspective Perspektiven der Anwendung. Perspektive: Anordnung von Komponenten in
der Workbench
org.eclipse.ui.views Views der Anwendung definieren
org.eclipse.core.runtime.products Spezielle Konfiguration(en) der Applikationen als Produkt.
Seite 10
Extension-Points
Extension-Point ···.core.runtime.applications
Dieser Extension-Point muss von jeder RCP-Anwendung mit einer Extension versehen werden. Für die Eclipse-Plattform ist es der Eintrittspunkt in die Applikation.
Die Klasse simpleMath.Application wurde als Einstiegspunkt generiert.
Seite 11
Extensions: ···core.runtime.applications ~> Application
public class Application implements IApplication {
public Object start(IApplicationContext context) { Display display = PlatformUI.createDisplay(); try { int returnCode = PlatformUI.createAndRunWorkbench(
display, new ApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART) {return IApplication.EXIT_RESTART;
} return IApplication.EXIT_OK; } finally { display.dispose();}}
public void stop() {...}}
UserInterface erzeugen
Workbench erzeugen, starten und disply zuordnen
Workbench konfigurieren
Seite 12
Extensions: Application ~> ApplicationWorkbenchAdvisor
public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
private static final String PERSPECTIVE_ID = "SimpleMath.perspective";
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {return new ApplicationWorkbenchWindowAdvisor(configurer);
}
public String getInitialWindowPerspectiveId() {return PERSPECTIVE_ID;
}
}
Die (initiale) Persektive wird definiert als Klasse mit der ID SimpleMath.perspectivePerspektiven sind definierte Erweiterungen, die Id ist in plugin.xml definiert und einer Klasse
zugeordnet.
Delegation der Fensterkonfiguration an eine weitere Klasse.
Seite 13
Extensions: ApplicationWorkbenchAdvisor ~> ApplicationWorkbenchWindowAdvisor
public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {super(configurer);
}
public ActionBarAdvisor createActionBarAdvisor( IActionBarConfigurer configurer) {
return new ApplicationActionBarAdvisor(configurer); }
public void preWindowOpen() {IWorkbenchWindowConfigurer configurer = getWindowConfigurer();configurer.setInitialSize(new Point(400, 300));configurer.setShowCoolBar(false);configurer.setShowStatusLine(false);
}}
ApplikationWorkbenchWindowAdvisor: Konfiguration einzelner Fenster.
Delegation der ActionBar-Konfiguration an eine weitere Klasse.
Seite 14
Extensions: ApplicationWorkbenchWindowAdvisor ~>ApplicationActionBarAdvisor
public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
// Actions - important to allocate these only in makeActions, and then use them// in the fill methods. This ensures that the actions aren't recreated// when fillActionBars is called with FILL_PROXY.private IWorkbenchAction exitAction;
public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) { super(configurer);}
protected void makeActions(final IWorkbenchWindow window) { // Creates the actions and registers them. // Registering is needed to ensure that key bindings work. // The corresponding commands keybindings are defined in the plugin.xml file. // Registering also provides automatic disposal of the actions whenthe window is closed. exitAction = ActionFactory.QUIT.create(window); register(exitAction);}
protected void fillMenuBar(IMenuManager menuBar) { MenuManager fileMenu = new MenuManager(
"&File", IWorkbenchActionConstants.M_FILE); menuBar.add(fileMenu); fileMenu.add(exitAction);}}
Seite 15
Extension-Points
Extension-Point ···.ui.perspectives
Dieser Extension-Point erlaubt es Perspektiven in die Workbench einzubringen. Eine Perspektive definiert ein spezifisches Layout der Oberfläche.
Eine Perspective wird als Extension am Extension-Point org.eclipse.ui.perspective definiert.
Zu jeder Perspektive muss eine Klasse angegeben werden die das Interface org.eclipse.ui.IPerspectiveFactory implementiert.
Diese Klasse gestaltet die Perspektive.
Seite 16
Extensions: ···ui.perspectives
Definierende Klasse
package simplemath;
public class Perspective implements IPerspectiveFactory {
public void createInitialLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); layout.setEditorAreaVisible(false); layout.setFixed(true);
layout.addStandaloneView(View.ID,false, IPageLayout.LEFT, 1.0f, editorArea);}}
View anzeigen
Seite 17
Extension-Points
Extension-Point ···.ui.views
Dieser Extension-Point erlaubt es Views in die Workbench einzubringen. Eine View ist ein Bestandteil der Oberfläche mit der Informationen dargestellt werden. Views und Editoren sind die beiden Grundbestandteile einer Workbench.
Eine View wird als Extension am Extension-Point org.eclipse.ui.views definiert.
Zu jeder View muss eine Klasse angegeben werden die das Interface org.eclipse.ui.IViewPart implementiert.
Üblicherweise wird das Interface nicht direkt implementiert, sondern die abstrakte Klasse org.eclipse.ui.part.ViewPart erweitert.
Seite 18
Extensions: ···ui.views
Extension-Point
Extension
package simpleMath;public class View extends ViewPart { public static final String ID = "SimpleMath.view"; ····}
View
Seite 19
Activator
ActivatorDie Klasse Activator kontrolliert den Lebenszyklus des Plugins, z.B. Start und Stop.
Instanzen dieser Klasse werden vom Framework erzeugt. Ebenso werden ihre Methoden von dort aktiviert. Ein Activator muss Plugin erweitern.
<<interface>>BundleActivator
Plugin
AbstractUIPlugin
Activator
<<implements>>
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: SimpleMath Plug-inBundle-SymbolicName: SimpleMath; singleton:=trueBundle-Version: 1.0.0Bundle-Activator: simplemath.ActivatorBundle-Vendor: FH-GiessenRequire-Bundle: org.eclipse.ui, org.eclipse.core.runtimeBundle-RequiredExecutionEnvironment: JavaSE-1.6Bundle-ActivationPolicy: lazy
Manifest.MF
Seite 20
Extensions : Übersicht
Plugin-Kontrolle
Seite 21
RCP / JFace
Th Letschert
Model und View
Seite 22
View
ViewPart Views werden als Erweiterung von org.eclipse.ui.part.ViewPart definiert
CreatePartControlDie Methode public void createPartControl(Composite parent) baut die
Grafik des Views auf.Extension Point org.eclipse.ui.views
Views werden als Extensions am Extension-Point org.eclipse.ui.views definiert
Seite 23
View: Extension-Point
Extension Point org.eclipse.ui.views
Der Extension-Point org.eclipse.ui.views hat die Struktur:
<extension point="org.eclipse.ui.views"><category id=“···“ name="···"></category><view id="····" name="···" category="····" class="····" icon="···"> </view>
···</extension>
Category: Einteilung der Views in Kategorien
View: Definition eines Views➢ id : eindeutige ID (muss in der View-Klasse als ID definiert sein!)➢ name: Name des Views➢ category: optinale Kategorie➢ class: View-Klasse➢ icon: optionales Icon, das den View repräsentiert
Seite 24
View Beispiel : Id und Name modifizieren
Modifikation des Views im Beispiel SimpleViewIm Beispiel sollen innerhalb des Views einfache Berechnungen ausgeführt
werden. View-Id und Klassen-Namen werden entsprechend angepasst:name : ComputeView
id : SimpleMath.ComputeView
Klassenname : ComputeView
<extension point="org.eclipse.ui.views"> <view name="ComputeView" class="simplemath.ComputeView" id="SimpleMath.ComputeView"> </view> </extension>
public class ComputeView extends ViewPart {public static final String ID =
"SimpleMath.ComputeView";···
}
plugin.xml
ComputeView.java(vorher View.java)
Seite 25
View Beispiel : ComputeView
ComputeView füllenDie View-Klasse ComputeView muss jetzt an ihre Aufgabe angepasst
werden. Zwei Methoden sind dafür mit Code zu füllen:createPartControl
erzeugt die „Controls“ des Views. Im generierten Beispiel wird ein org.eclipse.jface.viewers.TableViewer
erzeugt. Controls sind Widgets die als GUI-Elemente der Zielplattform realisiert
werden.setFocus
setzt den Fokus
Seite 26
SWT / JFace / TableViewer
TableViewer
Die Klasse TableViewer ist eine JFace-Klasse. SWT – Standard Widget Toolkit
SWT ist eine GUI-Bibliothek, die graphische Elemente der Java-Applikation möglichst direkt in solche der Plattform umsetzt.
SWT wird von allen RCP-Anwendungen genutztJFace
JFace ist ein auf SWT-basierendes Framework das die erstellung von GUI erleichtert. (http://wiki.eclipse.org/The_Official_Eclipse_FAQs#JFace)
TableViewerEin TableViewer ist eine JFace-Viewer-Klasse.Viewer gibt es in zwei Grundvarianten:
➢ Text Viewer➢ List oriented Viewers
Der TableViewer gehört zu den Listen-orientierten Viewern mit den Listen Bäume und Tabellen erzeugt werden können.
Viewer
ContentViewer
StructuredViewer
ContentViewer
ColumnViewer
AbstractTableViewer
TableViewer
Seite 27
JFace Viewer / ContentViewer
Viewer
Die abstrakte Klasse Viewer ist die Basisklasse diverser Viewer. Ein Viewer realisiert die V-Komponente des MVC-Musters. Sie ist also dazu da, die Informationen eines Modells darzustellen und dem Benutzer Zugriff auf die Funktionalität einer GUI zu geben.
setInput( Object input ) Viewer-Methode: Übergibt den darzustellenden Inhalt an den Viewer
ContentViewerDie abstrakte Klasse ContentViewer bietet zwei Methoden, mit denen dem Viewer
jeweils ein Konfigurator übergeben wird:
setContentProvider( IContentProvider contentProvider ) Übergabe einer Helfer-Klasse zur Vermittlung zwischen dem Modell und dem
View
setLabelProvider( IBaseLabelProvider labelProvider ) Übergabe einer Helfer-Klasse die ein Element des Modells auf einen Text-String
oder ein Icon abbildetEin ContentViewer hat also genau die Aufgabe, die seinem Namen entspricht: er
vermittelet also generell zwischen dem Modell und seiner Darstellung.
Seite 28
JFace TableViewer Beispiel
TableViewer
Eignet sich zur Darstellung von Tabellen.
Beispiel Model
Ein TableViewer erwartet, dass ihm das Modell als Array präsentiert wird. Ein Element wird als Zeile dargestellt.
Mediator-KlassenViewLabelProvider
extends LabelProvider implements ITableLabelProvider
ViewContentProvider implements IStructuredContentProvider
TableViewer
setInputsetContentProvidersetLabelProvider
ComputeView
setInputsetContentProvidersetLabelProvider
ViewContentProvider
getElements
ViewLabelProvider
getColumnText
IStructuredContentProviderITableLabelProvider LabelProviderIBaseLabelProvider
Model
<<use>><<use>>
Seite 29
JFace TableViewer Beispiel
public class ComputeView extends ViewPart { public static final String ID = "SimpleMath.ComputeView";
private TableViewer viewer;
class Model {...}; Model model = new Model();
class ViewContentProvider implements IStructuredContentProvider {public void inputChanged(Viewer v, Object oldInput, Object newInput) {}public void dispose() {}public Object[] getElements(Object parent) {return model.toArray();}
} class ViewLabelProvider extends LabelProvider implements
ITableLabelProvider {public String getColumnText(Object obj, int index) {···}public Image getColumnImage(Object obj, int index) {return null;}public Image getImage(Object obj) {return null;}
} public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);viewer.setContentProvider(new ViewContentProvider());viewer.setLabelProvider(new ViewLabelProvider());viewer.setInput(model);
} public void setFocus() { viewer.getControl().setFocus(); }}
Grundstruktur TableViewer mit Model
Seite 30
JFace TableViewer Beispiel / Model
TableViewer Beispiel Model-Komponente
TabelViewer behandlen typischerweise Kollektionen. Unser Modell besteht also aus einer Kollektion.
Die Elemente der Kollektion sind Berechnungen, die der Einfachheit halber als String-Verknüpfungen definiert werden:
package simplemath.model;
public class Computation { private String operand_1; private String operand_2; private char operator; private String result;
public Computation(String operand_1, String operand_2, char operator){this.operand_1 = operand_1;this.operand_2 = operand_2;this.operator = operator;computeResult();
}
private void computeResult() {result = operand_1+operator+operand_2;
}}
Seite 31
JFace TableViewer Beispiel / Model
TableViewer Beispiel : Model
Die gesamte Kollektion wird als Singleton definiert:
package simplemath.model;
import java.util.ArrayList;import java.util.List;
public class ComputationsControl { private static ComputationsControl singleInstance
= new ComputationsControl(); List<Computation> computationList = new ArrayList<Computation>();
public synchronized static ComputationsControl getInstance() {return singleInstance;
} public static void addComputation(String operand_1,
String operand_2, char op){ getInstance().computationList.add(
new Computation(operand_1, operand_2, op)); } public List<Computation> getComputationList() { return computationList; }}
Seite 32
JFace TableViewer Beispiel / ContentProvider
TableViewer Beispiel / ContentProvider
Der ContentProvider vermittelt zwischen dem Model und dem View: Er füllt das Model mit Daten und bietet einen Zugriff auf die Daten.
package simplemath.model;
import org.eclipse.jface.viewers.IStructuredContentProvider;import org.eclipse.jface.viewers.Viewer;
public class ComputationsContentProvider implements IStructuredContentProvider {
public ComputationsContentProvider() {ComputationsControl.getInstance().addComputation("1", "2", '+');ComputationsControl.getInstance().addComputation("3", "4", '-');ComputationsControl.getInstance().addComputation("5", "6", '*');ComputationsControl.getInstance().addComputation("7", "8", '/');
}
public void inputChanged(Viewer v, Object oldInput, Object newInput) {} public void dispose() {}
public Object[] getElements(Object parent) {return ComputationsControl.getInstance().getComputationList().toArray();
}}
Seite 33
JFace TableViewer Beispiel / ContentProvider
TableViewer Beispiel / ContentProvider
Der neue ContentProvider wird in ComputeView verwendet. Die generierte innere Klasse kann gelöscht werden.
public class ComputeView extends ViewPart { public static final String ID = "SimpleMath.ComputeView";
private TableViewer viewer;
···
public void createPartControl(Composite parent) {···viewer.setContentProvider(new ComputationsContentProvider());···
} ···}
Seite 34
JFace TableViewer Beispiel / LabelProvider
TableViewer Beispiel / LabelProvider
Ein LabelProvider ist dafür verantwortlich den sichtbaren Inhalt der einzelnen Zeilen zu erzeugen. Jede Zeile hat dazu für jede Spalte (column) einen sichtbaren Bestandteil (ein Label) zu liefern.
package simplemath.model;
import org.eclipse.jface.viewers.ITableLabelProvider;import org.eclipse.jface.viewers.LabelProvider;import org.eclipse.swt.graphics.Image;
public class ComputationsLabelProvider extends LabelProvider implements ITableLabelProvider {
public String getColumnText(Object obj, int index) {switch (index) {case 0: return (((Computation) obj).getOperand_1());case 1: return (((Computation) obj).getOperand_2());case 2: return (((Computation) obj).getOperator()+"");case 3: return (((Computation) obj).getResult());
} return null; } public Image getColumnImage(Object obj, int index) { return null;} public Image getImage(Object obj) { return null; }}
Zu jeder Komponente/ Spalte wird der Inhalt als String zurück gegeben.
Seite 35
JFace TableViewer Beispiel / LabelProvider
TableViewer Beispiel / LabelProvider
Der LabelProvider wird an TableView übergeben
public class ComputeView extends ViewPart { public static final String ID = "SimpleMath.ComputeView";
private TableViewer viewer;
···
public void createPartControl(Composite parent) {···viewer.setContentProvider(new ComputationsContentProvider());viewer.setLabelProvider(new ComputationsLabelProvider());···
} ···}
Seite 36
JFace TableViewer Beispiel / Table, TableColumn
TableViewer Beispiel / Table anpassen
Ein TableViewer enthält eine Instanz des SWT-Widgets Table. Diese muss so angepasst werden, dass die Tabelle mit allen Spalten und Spaltenüberschriften angezeigt wird.
TableViewer viewer;
viewer.getTable();
TableColumn column = new TableColumn(viewer.getTable(),
SWT.NONE);
column.setWidth(75);
column.setText("Op 1");
SWT-Tabelle extrahieren
Spalte erzeugen und an die Tabelle anfügen
Spaltenbreite und Überschrift setzen
Seite 37
JFace TableViewer Beispiel / View
package simplemath;import ····public class ComputeView extends ViewPart { public static final String ID = "SimpleMath.ComputeView"; private TableViewer viewer;
public void createPartControl(Composite parent) {viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);viewer.setContentProvider(new ComputationsContentProvider());viewer.setLabelProvider(new ComputationsLabelProvider());
TableColumn column = new TableColumn(viewer.getTable(),SWT.NONE);column.setWidth(75);column.setText("Op 1");
column = new TableColumn(viewer.getTable(),SWT.NONE);column.setWidth(75);column.setText("Op 2");
column = new TableColumn(viewer.getTable(),SWT.NONE);column.setWidth(50);column.setText("Op");
column = new TableColumn(viewer.getTable(),SWT.NONE);column.setWidth(100);column.setText("Result");
viewer.setInput(getViewSite());
viewer.getTable().setLinesVisible(true);viewer.getTable().setHeaderVisible(true);
} public void setFocus() { viewer.getControl().setFocus(); }}
Seite 38
JFace TableViewer Beispiel / View
Seite 39
JFace TableViewer Beispiel aufräumen
Paket-Struktur
Die Provider gehören nicht direkt zum Modell, sie werden daum in eine eigenes Paket „provider“ verlaget.
Seite 40
RCP / JFace
Th Letschert
Tabellen-Einträge editieren
Seite 41
JFace TableViewer Beispiel / EditingSupport
EditingSupport org.eclipse.jface.viewers.EditingSupport
Die abstrakte Klasse EditingSupport kann verwendet werden, um Editier-Operationen auf den Zellen eines ColumnViewers zu definieren.
Damit die Tabelleneinträge editierbar werden, definieren wir einen entsprechenden EditingSupport.
package simplemath.provider;
import org.eclipse.jface.viewers.CellEditor;import org.eclipse.jface.viewers.ColumnViewer;import org.eclipse.jface.viewers.EditingSupport;
public class ComputationEditingSupport extends EditingSupport {
··· diverse Methoden ···
}
generierte Vorlage der EditingSupport-Klasse
Seite 42
JFace TableViewer Beispiel / EditingSupport
EditingSupport Konstruktor / canEdit
Die beiden ersten Spalten enthalten die Operanden, sie sollen editierbar sein. wir definieren einen Konstruktor, der die Information über die Spalte annimmt und
überschreiben die Methode canEdit
public class ComputationEditingSupport extends EditingSupport {
private int column;
public ComputationEditingSupport(ColumnViewer viewer, int column) {super(viewer);this.column = column;
}
@Override protected boolean canEdit(Object element) {
switch (this.column) {case 0: return true;case 1: return true;default: return false;}
} ···
Seite 43
JFace TableViewer Beispiel / EditingSupport
EditingSupport Text-Editor
Jetzt wird ein TextEditor für die ersten beiden Spalten gesetzt:
public class ComputationEditingSupport extends EditingSupport {
private int column; private CellEditor editor;
public ComputationEditingSupport(ColumnViewer viewer, int column) {super(viewer);this.column = column;switch (column) {case 0: case 1:
editor = new TextCellEditor(((TableViewer) viewer).getTable());
break; default: editor = null; } } ··· @Override protected CellEditor getCellEditor(Object element) { return editor; } ···}
Seite 44
JFace TableViewer Beispiel / EditingSupport
EditingSupport Methoden die das Model befragen bzw. verändern:
@Overrideprotected Object getValue(Object element) {Computation computation = (Computation) element; switch (this.column) { case 0: return computation.getOperand_1(); case 1: return computation.getOperand_2(); case 2: return computation.getOperator()+""; case 3: return computation.getResult(); } return null;}@Overrideprotected void setValue(Object element, Object value) {Computation computation = (Computation) element; switch (this.column) { case 0: computation.setOperand_1((String)value); break; case 1: computation.setOperand_2((String)value); break; case 2: String s = (String)value; if ( s.equals("+")) computation.setOperator('+'); else if ( s.equals("-")) computation.setOperator('-'); else if ( s.equals("*")) computation.setOperator('*'); else if ( s.equals("/")) computation.setOperator('/'); break; case 3: computation.setResult((String)value); break; } getViewer().update(element, null);}
Seite 45
JFace TableViewer Beispiel / EditingSupport: View anpassen
package simplemath;import ····public class ComputeView extends ViewPart { public static final String ID = "SimpleMath.ComputeView"; private TableViewer viewer;
public void createPartControl(Composite parent) {viewer = new TableViewer(parent,
SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
viewer.setContentProvider(new ComputationsContentProvider());viewer.setLabelProvider(new ComputationsLabelProvider());
TableColumn column = new TableColumn(viewer.getTable(),SWT.NONE);···
} public void setFocus() { viewer.getControl().setFocus(); }}
EditingSupport TableViewer konfigurieren
Der TableViewer wird mit dem Flag SWT.FULL_SELECTION erzeugt Die Spalten werden als Instanzen von TableViewerColumn erzeugt und konfiguriertDer LabelProvider wird Zellenweise und nicht für die ganze Tabelle gesetzt
ersetzt durch:TableViewerColumn
org.eclipse.jface.viewers Class TableViewerColumn
ViewerColumn implementation for TableViewer to enable column-specific label providers and editing support.
Seite 46
JFace TableViewer Beispiel / EditingSupport: View anpassen
public class ComputeView extends ViewPart { public static final String ID = "SimpleMath.ComputeView"; private TableViewer viewer;
public void createPartControl(Composite parent) {viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION );viewer.setContentProvider(new ComputationsContentProvider());
TableViewerColumn column = new TableViewerColumn(viewer,SWT.NONE);column.getColumn().setWidth(75);column.getColumn().setText("Op 1");column.getColumn().setWidth(75);column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { return ((Computation) element).getOperand_1(); }});column.setEditingSupport(new ComputationEditingSupport(viewer, 0));
column = new TableViewerColumn(viewer,SWT.NONE);column.getColumn().setWidth(75);column.getColumn().setText("Op 2");column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { return ((Computation) element).getOperand_2(); }});column.setEditingSupport(new ComputationEditingSupport(viewer, 1));
Jede Spalte bekommt ihren LabelProvider und ihren Editor
Seite 47
JFace TableViewer Beispiel / EditingSupport: View anpassen
column = new TableViewerColumn(viewer,SWT.NONE);column.getColumn().setWidth(50);column.getColumn().setText("Op");column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { return ((Computation) element).getOperator()+""; }});column.setEditingSupport(new ComputationEditingSupport(viewer, 2));
column = new TableViewerColumn(viewer,SWT.NONE);column.getColumn().setWidth(100);column.getColumn().setText("Result");column.setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { return ((Computation) element).getResult(); }});column.setEditingSupport(new ComputationEditingSupport(viewer, 3));
viewer.setInput(getViewSite());
viewer.getTable().setLinesVisible(true);viewer.getTable().setHeaderVisible(true);}
public void setFocus() {viewer.getControl().setFocus();
}}
Seite 48
JFace TableViewer Beispiel / EditingSupport: Model anpassen
Modell informierenDas Modell muss jetzt nur noch über die Benutzeringaben informiert werden.Für den Aufruf der set···-Operationen haben wir in
ComputationEditingSupport.setvalue
schon gesorgt. Die set-Operationen können das Modell komplett an den neuen Wert anpassen.
public class Computation {
private String operand_1; private String operand_2; private char operator; private String result; ···
public void setOperand_1(String operand_1) {this.operand_1 = operand_1;computeResult();
} public void setOperand_2(String operand_2) {
this.operand_2 = operand_2;computeResult();
} private void computeResult() { result = operand_1+operator+operand_2; } ···}
Seite 49
JFace TableViewer Beispiel Einträge in Spalte 1 und 2 sind editierbar
Seite 50
RCP / JFace
Th Letschert
Tabellen-Eintrag mit Combo-Box editieren
Seite 51
JFace TableViewer Beispiel / EditingSupport: Combo-Box
Combo-Box Um die Operatoren in der Tabelle durch eine Combox-Box auswählbar zu machen, nutzen wir einen ComboBoxCellEditor. Get/set im EditiongSupport müssen an die Combo-Box angepasst werden.
public class ComputationEditingSupport extends EditingSupport {
private int column; private CellEditor editor; private String[] operatorSign = { "+", "-", "*", "/" };
public ComputationEditingSupport(ColumnViewer viewer, int column) { super(viewer); this.column = column;
switch (column) { case 0: case 1: editor = new TextCellEditor( ((TableViewer) viewer).getTable()); break; case 2: editor = new ComboBoxCellEditor( ((TableViewer) viewer).getTable(), operatorSign); break; default: editor = null; } } ···
Die dritte Spalte enthält den Operator
Seite 52
JFace TableViewer Beispiel / EditingSupport: Combo-Box
Die dritte Spalte enthält den Operator und ist jetzt editierbar.
··· @Override protected void setValue(Object element, Object value) { Computation computation = (Computation) element; switch (this.column) { case 0: computation.setOperand_1((String)value); break; case 1: computation.setOperand_2((String)value); break; case 2: Integer i = (Integer)value;
if ( i == 0) { computation.setOperator('+');} else if ( i == 1) { computation.setOperator('-');} else if ( i == 2) { computation.setOperator('*');} else if ( i == 0) { computation.setOperator('/'); }break;
case 3: computation.setResult((String)value); break; } getViewer().update(element, null); } ··· @Override protected boolean canEdit(Object element) { switch (this.column) { case 0: return true; case 1: return true; case 2: return true; default: return false; } } ···}
Seite 53
JFace TableViewer Beispiel / EditingSupport: Model anpassen
Modell anpassenDer Operator ist jetzt editierbar. Wir passen das Modell an und lassen es jetzt auch
„richtig“ rechnen.
public class Computation {
···
public void setOperator(char operator) {this.operator = operator;computeResult();
}
private void computeResult() {int o1 = Integer.parseInt(operand_1);int o2 = Integer.parseInt(operand_2);switch(operator) {case '+': result = ""+(o1+o2); break;case '-': result = ""+(o1-o2); break;case '*': result = ""+(o1*o2); break;case '/': result = ""+(o1/o2); break;}
}
···}
Seite 54
RCP / JFace
Th Letschert
Kommandos
Seite 55
JFace TableViewer Beispiel / Command
Kommandos: Extension org.eclipse.ui.commandsFür Kommandos wird die Extension org.eclipse.ui.commands benötigt.
plugin.xml ~> Extensions ~> Add
Seite 56
JFace TableViewer Beispiel / Command
Kommando definierenAm Extension-Point org.eclipse.ui.commands
definieren wir ein neues Kommando (rechtsKlick ~> new ~> command)
Id:simpleMath.AddComputation
DefaultHandler:simplemath.commands.AddComutation
Seite 57
JFace TableViewer Beispiel / Command
Kommando definieren: Kommando-KlasseDie ausführende Klasse ist zunächst nur eine Hülle
public class AddComutation extends AbstractHandler implements IHandler {
@Override public Object execute(ExecutionEvent event) throws ExecutionException {
System.out.println("AddComutation called");return null;
}
}
Seite 58
JFace TableViewer Beispiel / Command
Kommando zur Toolbar hinzufügenUm Kommando zur Toobar hinzugefügen zu können, darf ComputeView nicht standalone
sein.Die Klasse Persective.java ist dazu zu ändern in:
public class Perspective implements IPerspectiveFactory {
public void createInitialLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); layout.setEditorAreaVisible(false); layout.setFixed(true);
//layout.addStandaloneView(ComputeView.ID, false, IPageLayout.LEFT, // 1.0f, editorArea);
layout.addView(ComputeView.ID, IPageLayout.LEFT, 1.0f, editorArea); }
}
Seite 59
JFace TableViewer Beispiel / Command
Kommando zur Toolbar hinzufügenDer Extension-Point org.eclipse.ui.menus muss hinzugefügt werden.
plugin.xml ~> Extensions ~> Add : org.eclipse.ui.menus
Dieser Extension-Point wird um eine „contribution“ erweitetorg.eclipse.ui.menus ~rechtsKlick~> Add menue Contribution
locationURI: toolbar:SimpleMath.ComputeView
Die „Contribution“ erhält ein neues Kommando:toolbar:SimpleMath.ComputeView ~> new command:
CommandID: SimpleMath.addComputationLabel: Add
Seite 60
JFace TableViewer Beispiel / Command
Seite 61
JFace TableViewer Beispiel / Command
Kommando definieren: Kommando-KlasseDas Kommando modifiziert das Modell, es hängt eine weitere Berechnung an die Liste
der Berechnungen an. Wir führen eine entsprechende Aktion im Modell ein und aktivieren sie im Handler.
public class AddComputation extends AbstractHandler implements IHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException {
simplemath.model.ComputationsControl.getInstance().addComputation("0", "0", '+');
return null; }}
public class ComputationsControl {
····· public void addComputation(String operand_1, String operand_2, char op){
getInstance().computationList.add(new Computation(operand_1, operand_2, op)); }}
Seite 62
JFace TableViewer Beispiel / Data-Binding
Data-Binding : org.eclipse.core.databindingDamit die Änderung am Modell in der View-Komponente sichtbar werden kann, sind
eigene Arbeiten erforderlich. Das JFace-Framework unterstützt die Modifikation der einzelnen Elemente, die Modifikation der gesamten Liste muss aber durch eigenen Code organisiert werden.
Der View muss zum Beobachter des Modells werden. Eclipse bietet dazu ein Framework als plugins org.eclipse.core.databinding das wir als erstes einbinden:
plugin.xml ~> Depedencies (Tab) ~> Add: org.eclipse.core.databinding
Seite 63
JFace TableViewer Beispiel / Data-Binding
Observable, die beobachtete Klasse / AbstractObservableDie beobachtete Klasse ist ComputationsControl (nur Änderungen des gesamten Model
sind unbehandelt), wir machen sie beobachtbar:
import java.util.List;import java.util.ArrayList;import org.eclipse.core.databinding.observable.AbstractObservable;import org.eclipse.core.databinding.observable.Realm;
public class ComputationsControl extends AbstractObservable{
public ComputationsControl(Realm realm) {super(realm);
}
public ComputationsControl() {this(Realm.getDefault());
}
private static ComputationsControl singleInstance = new ComputationsControl();
Seite 64
JFace TableViewer Beispiel / Data-Binding
Observable, die beobachtete Klasse(fortgesetzt)
public synchronized static ComputationsControl getInstance() { return singleInstance; }
public void addComputation(String operand_1, String operand_2, char op){ getInstance().computationList.add(
new Computation(operand_1, operand_2, op)); fireChange(); }
public List<Computation> getComputationList() { return computationList; }
@Override public boolean isStale() {
return false; }}
Änderung melden!
Seite 65
JFace TableViewer Beispiel / Data-Binding
Beobachter, die beobachtende Klasse: IChangeListenerDie View-Klasse beobachtet die Änderungen im Modell:
public class ComputeView extends ViewPart implements IChangeListener {
public static final String ID = "SimpleMath.ComputeView"; private TableViewer viewer; ··· simplemath.model.ComputationsControl.getInstance().addChangeListener(this); ··· private void refreshView() {
viewer.refresh(); }
@Override public void handleChange(ChangeEvent event) {
refreshView(); }
}
Seite 66
JFace TableViewer Beispiel / Data-Binding
Add vergrößert die Tabelle!