zu www.bildungsgueter.de zur Inhaltsübersicht des Kapitels vorheriger Abschnitt

Elementare Grafikfunktionen in JavaFX


Verwendung einer größenveränderlichen Canvas

Die dringlichste Verbesserung ist natürlich die Bereitstellung eines größenveränderlichen Darstellungselements. Diese Ver­bes­se­rung verlangt die Definition einer Unterklasse, die einige Instanzmethoden von Canvas überschreibt.

Die wesentlichen Änderungen sind hier:

package main;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * Das Beispiel zeigt die Verwendung einer Instanz von PaintArea.
 * Es wird ein umrandetes Rechteck gezeichnet.
 * Die Instanz von PaintArea ist größenveränderlich.
 * Das Zeichnen in die PaintArea wird an eine Instanz delegiert,
 * die die Schnittstelle PaintModel bereitstellt. In diesem
 * Beispiel stellt FXGraphicsDemo02 die Schnittstelle PaintModel
 * bereit.
 * @author
 */
public class FXGraphicsDemo01 extends Application
                              implements PaintModel {
    
    @Override
    public void start(Stage primaryStage) {
        PaintArea c = new PaintArea(this);
        VBox container = new VBox(c);
        VBox.setVgrow(c, Priority.ALWAYS);
        
        Scene scene = new Scene(container, 250, 250);
        primaryStage.setTitle("Graphics Demo");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
    * Die Methode ist einziges Element der Schnittstelle PaintModel. Sie wird
    * aus einer Instanz von PaintArea aufgerufen und erhält den Grafikkontext
    * der aufrufenden Instanz.
    * Die Methode hat die Aufgabe, den Inhalt der aufrufenden Instanz zu zeichnen.
    * Da der Grafikkontext seine Canvas mitteilen kann und es so möglich ist,
    * die Abmessungen der Zeichenfläche über den Grafikkontext zu
    * erfragen, ist es ausreichend, den Grafikkontext zu übergeben. 
    */
    @Override
    public void paint(GraphicsContext gc) {
        double w = gc.getCanvas().getWidth();
        double h = gc.getCanvas().getHeight();
        gc.clearRect(0, 0, w, h);
           //  ohne clearRect entstehen beim Verkleinern des
           //  Darstellungselements Schmiereffekte.
        gc.setFill(Color.DARKGOLDENROD);
        gc.fillRect(10, 10, w - 20, h - 20);
        gc.setStroke(Color.GREEN);
        gc.setLineWidth(5.0);
        gc.strokeRect(10, 10, w - 20, h - 20);
    }
    
    /**
     * Der Einstiegspunkt des Programms.
     * @param args Die Argumente der Kommandozeile
     */
    public static void main(String[] args) {
        launch(args);
    }
}

In diesem Beispiel wurde entschieden, dass der Inhalt der Zeichenfläche von einer Instanzmethode der Klasse FXGraphicsDemo01 gezeichnet werden soll. Die Trennung der Zuständigkeiten wird wie folgt realisiert:

Die Definition der Schnittstelle PaintModel:

package main;

import javafx.scene.canvas.GraphicsContext;

/**
 * Diese Schnittstelle ist von einer Instanz bereitzustellen, die in
 * eine PaintArea zeichnen soll.
 * @author
 */
public interface PaintModel {
    public void paint(GraphicsContext gc);
}

In der Definition der Ansicht sind verschiedene Methoden der Basisklassen neu zu definieren, um die Größenveränderlichkeit des Anzeige­elements herzustellen. Es sind dies die Methoden isResizable, resize, minHeight, minWidth, maxHeight, maxWidth.

package main;

import javafx.scene.canvas.Canvas;

/**
 * PaintArea ist ein größenveränderliches Darstellungselement, das von
 * Canvas abgeleitet ist und alle Funktionen von Canvas bereitstellt.
 * @author 
 */
public class PaintArea extends Canvas {
   
    private final PaintModel model;
    public PaintArea (PaintModel m) {
        model = m;
    }
    
    private void paint() {
        model.paint(this.getGraphicsContext2D());
    }
    
    /** Canvas ist nicht größenveränderlich. Die folgenden ueberschriebenen
     * Methoden erlauben dem Layoutmanager eine Groessenaenderung.
     * @return Immer true, weil die Groessenaenderung immer
     * 	    erlaubt ist.
     */
    @Override
    public boolean isResizable() {
            return true;
    }

    @Override
    public void resize(double width, double height) {
            super.resize(width, height);
            setWidth(width);
            setHeight(height);
            paint();
    }

    @Override
    public double maxHeight(double arg0) {
            return Double.MAX_VALUE;
    }

    @Override
    public double maxWidth(double arg0) {
            return Double.MAX_VALUE;
    }

    @Override
    public double minHeight(double arg0) {
            return 1;
    }

    @Override
    public double minWidth(double arg0) {
            return 1;
    } 
}

Archivdatei mit diesem Beispiel: FXGraphicsDemo02.zip.


vorheriger Abschnitt zur Inhaltsübersicht des Kapitels