Viele der augenfälligsten Neuerungen von jadice 5 betreffen die Bedienung und die
        Benutzeronerfläche der Views, zuvorderst dabei sicher die Klasse PageView. Die Views
        selbst steuern dabei jedoch nur einen begrenzten Teil des Verhaltens bei. Der weitaus
        größere Teil wird von unabhängigen Komponenten bereitgestellt, die an Views angedockt werden
        können, um deren Funktionsumfang zu erweitern oder anzupassen. In jadice 4 existierte
        bereits ein API, das eine ganz ähnliche Aufgabenbenbeschreibung hatte,
        nämlich das Gespann aus EditEventListener und
          EditPane. Jadice 5 stellt hierfür eine grundlegende überarbeitete
          API zur Verfügung, die mächtiger und einfacher zu verwenden ist – das
            Tool-API.
Das Tool
Die Klasse Tool ist zentrale Basis für Werkzeuge und hat vier wesentliche
          Aufgabenbereiche: 
die Verarbeitung von Eingabeereignissen
das Anreichern der Darstellung des Views mit eigenen Elementen, das heißt die Teilname am Rendering des Views
das Beitragen von Kontextmenüelementen
die Teilnahme an der Zustandsverwaltung im Zusammenspiel mit dem
ToolManager
Bis auf den letzten Punkt sind alle Aufgaben optional. Tools müssen nicht auf
          Eingaben reagieren oder visuelle Beiträge zur Oberfläche liefern.
Auch die Erstellung eigener Tools ist recht einfach durch Erweiterung der abstrakten
          Klasse Tool möglich. 
Tools werden von den zugehörigen Views mit Eingabeereignissen versorgt, wodurch
            sie die Möglichkeit erhalten, auf Eingaben zu reagieren. Die von
            AWT/Swing bekannte Klassenhierarchie für Ereignisse
              (InputEvent und die davon abgeleiteten Klassen) bildet die
            Basis für die Eingabeereignisse. Allerdings werden diese nicht direkt verwendet, da
            Tools für ihre Arbeit in der Regel weitere Kontextinformationen, wie die betroffene
            Seite (Page), die aktuellen RenderControls und ähnliches benötigen. Aus diesem
            Grund stellt jadice den InputEvents eine analoge
            Klassenhierarchie unterhalb der abstrakten Klasse EditEvent zur
            Seite: KeyEditEvent, MouseEditEvent und
              MouseWheelEditEvent. Jedes EditEvent
            bietet immer auch den Zugriff auf den usprünglich auslösenden
              InputEvent. EditEvents beziehen sich oft
            auf eine Page, zum Beispiel dann, wenn sich der Mauszeiger in der Nähe oder über der
            Darstellung einer Seite befindet. Allerdings können die Ereignisse auch ohne
            Seitenkontext auftreten, weshalb Tools mit diesem Umstand umgehen können
            müssen.
In der Praxis treten bei der Ereignisverarbeitung im Zusammenhang mit in Views
            dargestellten Seiten immer wieder ähnliche Anforderungen zutage. Die EditEvents
            versuchen hierbei die häufigsten Anforderungen auf komfortable Weise abzudecken.
            Beispielsweise bietet das MouseEditEvent fünf verschiedene
            Methoden zum Zugriff auf die Koordinaten der Maus: 
getInputEvent().getPoint()entspricht den von AWT/Swing gewohnten Koordinaten in Pixeln, bezogen auf die obere linke Ecke des Views.getPoint()liefert die Bildschirmkoordinaten (Pixel) bezogen auf die obere linke Ecke der Seite, auf die sich das Event bezieht.getConstrainedPoint()liefert die gleichen Werte wiegetPoint(), allerdings werden diese, wenn sich die Maus außerhalb einer Seite befindet, so begrenzt, dass der nächstgelegene Punkt innerhalb der nächstgelegenen Seite geliefert wird.getDocumentPoint()liefert die Dokumentkoordinaten, das heißt Koordinaten in Einheiten vonDocument.BASE_RESOLUTION, bezogen auf die obere linke Ecke der nächstgelegenen Seite.getConstrainedDocumentPoint()entspricht wiedergetConstrainedPoint(), allerdings findet hier erneut das »Einfangen« der Koordinaten wie beigetConstrainedPoint()statt.
Die Klasse Tool nutzt für die Übergabe von EditEvents
            zunächst die Methode handleEditEvent(...). Die
            Standardimplementierung dieser Methode nimmt eine Verteilung an eventspezifische
            Template-Methoden wie keyPressed, mouseClicked und so weiter, vor. Nachfahren der Klasse
            Tool können so sehr komfortabel selektiv nur diejenigen Ereignismethoden
            überschreiben, die das Tool tatsächlich benötigt.
Da zu einer View häufig mehr als ein Tool registriert ist, ist es wichtig, die
              Reihenfolge, in der die verschiedenen Tools mit Ereignissen versorgt werden,
              beeinflussen zu können. Tools können weitgehend selbst steuern, wie früh oder spät
              in der Reihenfolge sie mit Ereignissen versorgt werden. Die Methode
                getDispatchPriority() des Tools muss hierzu einen Wert
              zwischen Tool.MIN_PRIORITY und
                Tool.MAX_PRIORITY zurückgeben. Je näher an
                MAX_PRIORITY der Wert ist, desto früher wird das Tool mit
              Ereignissen versorgt. 
Hat ein Tool ein Ereignis erhalten und hat es sich dafür entschieden, darauf zu
              reagieren, ist es oft sinnvoll dafür zu sorgen, dass keine anderen Tools mehr auf
              das Ereignis reagieren. Hierzu genügt es, beim Verarbeiten des Ereignisses dessen
                consume()-Methode aufzurufen. Sobald ein Ereignis konsumiert
              wurde, wird es nicht mehr an weitere Tools zur Verarbeitung übergeben. Im
              Umkehrschluss bedeutet dies auch, dass Tools nicht explizit prüfen müssen, ob ein
              Ereignis bereits konsumiert wurde, da sie dieses sonst überhaupt nicht erhalten
              hätten. 
Nachdem Views die Seitendarstellungen gerendert haben, erhalten Tools die
            Gelegenheit, eigene visuelle Elemente beizutragen. Für jede sichtbare Seite wird zu
            diesem Zweck die Tool-Methode render(...) aufgerufen, die ein
            Parameterobjekt (RenderParameters) sowie die Information, ob das
            Tool gerade aktiv ist, übergeben bekommt. Die RenderParameters
            enthalten alle Kontextinformationen, die zum Rendering benötigt werden, zum Beispiel den
            Zielgrafikkontext (Graphics2D), die Seite, den Bereich, in den die
            Seite gerendert wurde und so weiter.
Wie es eine Dispatch-Reihenfolge für die Verteilung von Ereignissen gibt,
              existiert eine separate Reihenfolge für das Zeichnen der Tools. Über
                getRenderPriority() kann ein Tool festlegen, wie früh oder
              spät es beim Rendering zum Zug kommen will. In der Regel sollten die Dispatch- und
              Renderreihenfolge in einer inversen Beziehung zueinander stehen. Tools können
              konzeptionell wie Ebenen betrachtet werden können: je weiter ›oben‹, desto früher
              werden Ereignisse verteilt und desto später wird gerendert. Die Methode
                getRenderPriority() kann Werte zwischen
                Tool.MIN_PRIORITY und Tool.MAX_PRIORITY
              zurückgeben. Die Standardimplementierung von getRenderPriority()
              gibt den Wert DEFAULT_PRIORITY zurück, der ein Mittelwert
              zwischen Tool.MIN_PRIORITY und
                Tool.MAX_PRIORITY ist.
Die Verwaltung des Zustandes von Tools obliegt dem ToolManager. Der
            Zustandsraum von Tools umfasst dabei folgende Freiheitsgrade:
- registriert/nicht registriert
 Tools, die (noch) nicht bei einem bestimmten
ToolManagerregistriert wurden, können in keiner Weise mit ihrem View interagieren. Erst durch die Registrierung werden sie dazu in die Lage versetzt. Bei der Registrierung wird die MethodesetManager(ToolManager)desTools aufgerufen.- eingeschaltet/ausgeschaltet (enabled/disabled)
 Bereits bei der Registrierung eines
Tools kann angegeben werden, ob dasTooldanach ein- oder ausgeschaltet (enabled/disabled) sein soll. EnabledTools sind demToolManagerzwar bekannt, sie erhalten aber weder Ereignisse, noch die Gelegenheit zum Rendering. Ob einToolenabled ist, kann durch die MethodesetEnabled(Class<? extends Tool>, boolean)gesteuert werden.- aktiv/inaktiv
 In manchen Situationen kann es notwendig sein, dass ein
Tool, obwohl es in der Dispatch-Reihenfolge eigentlich nicht an erster Stelle steht, temporär vorrangig vor allen anderenTools die Gelegenheit zur Verabeitung von Ereignissen erhält. Dies kann beispielsweise dann nützlich sein, wenn eine Programmoberfläche implementiert werden soll, die dem Nutzer verschiedene Bearbeitungsmodi, die von Tools realisiert werden, anbietet. Die Umschaltung zwischen diesen Modi würde dann durch das Aktivieren des entsprechenden (Modus-)Tools verwirklicht werden.Im
ToolManagerwird diese Auszeichnung als aktivesToolverwaltet. EinToolkann aktiv gesetzt werden mithilfe der Methodeactivate(...). Es kann immer nur einToolgleichzeitig aktiv sein, daher führt ein Aufruf der Methodeactivate(...)immer auch zum Inaktivieren des letzten aktivenTools, sofern es ein solches gab.Neben dieser ›manuellen‹ Art
Tools zu aktivieren, kann eineToolActivationPolicydie Auswahl des jeweils aktivenTools automatisieren. Dazu kann imToolManagerdie gewünschteToolActivationPolicymit der MethodesetActivationPolicy(ToolActivationPolicy)gesetzt werden. Vor der Ereignisverarbeitung erhält die Policy eine Liste aller Tools, die sich um Aktivierung ›bewerben‹. Sie wählt daraus, welches Tool den Zuschlag bekommt und das Ereignis vorrangig verarbeiten darf.- exklusiv
 Es kann sinnvoll sein, bestimmten
Tools für einen begrenzten Zeitraum die alleinige Kontrolle zu überlassen, um Konflikte mit anderenTools während komplexer Operationen zu vermeiden. Diese Exklusivität greift zum Beispiel bei der Annotationsbearbeitung, während Annotationen in der Größe verändert oder verschoben werden, sowie während der Texteditor aktiv ist. Der Exklusivmodus sorgt dafür, dass lediglich das exklusiveToolmit Ereignissen versorgt wird und Gelegenheit zum Rendering erhält. In der Regel ist es dasToolselbst, das den Exklusivmodus mittelsToolManager.setExclusive(Class<? extends Tool>)aktiviert. Bei der Verwendung des Exklusivmodus ist es entscheidend, dafür zu sorgen, dass dieser auch zuverlässig wieder zu verlassen wird, da sonst gegebenenfalls die Funktion aller anderenTools dauerhaft blockiert wird.
Der ToolManager
Einen Teil der Funktionen des ToolManagers haben wir oben bereits kennen gelernt,
          insbesondere diejenigen aus Sicht des Tools. Für die Integration stellt sich aber
          zunächst natürlich die Frage, wie auf ToolManager überhaupt zugegriffen werden kann,
          und welche Funktionen er bereitstellt. 
ToolManager leben immer in enger Symbiose mit einer ViewComponent: Jeder
          ToolManager hat immer genau eine ViewComponent und jede ViewComponent hat immer
          einen ToolManager. Derzeit existieren zwei konkrete Implementierungen von
          ViewComponent: PageView und ThumbnailView. Der ToolManager einer
          ViewComponent kann mit ViewComponent.getToolManager() erfragt
          werden. Einige der häufigsten Idiome bei der Arbeit mit dem ToolManager sind im
          folgenden Code-Beispiel aufgeführt.
ViewComponent viewComponent = ...; // Registrieren eines Tools viewComponent.getToolManager().register(MyTool.class, true); // Erfragen und Konfigurieren eines Tools if(viewComponent.getToolManager().hasTool(MyTool.class)) viewComponent.getToolManager().getTool(MyTool.class).setSomeOption(true); // Aktivieren/Deaktivieren eines Tools viewComponent.getToolManager().setEnabled(myTool.class, enabled); // Deregistrieren eines Tools viewComponent.getToolManager().deregister(MyTool.class);


