Friday, July 15, 2016

100. Sequential Transition

In SequentialTransition, we can have many animations in sequence.


Here we have a pause of 100 ms, and then two translate animations, one for the top and one for the bottom rectangle.


package ex100;

import javafx.animation.Animation;
import javafx.animation.PauseTransition;
import javafx.animation.SequentialTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Ex100 extends Application {
    
    @Override
    public void start(Stage stage) {
        
        Rectangle rect1 = new Rectangle(50, 50);
        rect1.setFill(Color.RED);
        rect1.setLayoutY(50);
        Rectangle rect2 = new Rectangle(50, 50);
        rect2.setFill(Color.GREEN);
        rect2.setLayoutY(350);
        
        TranslateTransition trans1 = new TranslateTransition();
        trans1.setNode(rect1);
        trans1.setFromX(0);
        trans1.setToX(400);
        trans1.setDuration(Duration.seconds(1));
        
        TranslateTransition trans2 = new TranslateTransition();
        trans2.setNode(rect2);
        trans2.setFromX(0);
        trans2.setToX(400);
        trans2.setDuration(Duration.seconds(2));
        
        SequentialTransition seqTransition = new SequentialTransition();
        seqTransition.setCycleCount(Animation.INDEFINITE);
        seqTransition.setAutoReverse(true);
        seqTransition.getChildren().addAll(
                new PauseTransition(Duration.millis(100)),
                trans1,
                trans2);
        
        Button button = new Button("Start");
        button.setPrefWidth(250);
        button.setOnAction(e -< {
            seqTransition.play();
            button.setVisible(false);
        });
        
        Group root = new Group(rect1, rect2, button); 
        
        Scene scene = new Scene(root, 450, 450, Color.LIGHTSKYBLUE);
        stage.setTitle("Example 100. Sequential Transition");
        
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}


This is the output during the animation:


Wednesday, July 13, 2016

99. Path Transition

A node can travel along a Path. Our path is 4 lines near the 4 sides of the window.


The node is a Rectangle and it moves over the path in 5 seconds.


package ex99;
 
import javafx.animation.Interpolator;
import javafx.animation.PathTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
 
public class Ex99 extends Application {
 
    @Override
    public void start(Stage primaryStage) {
 
        Rectangle rect = new Rectangle(50, 50, 20, 20);
        rect.setFill(Color.RED);
        
        Path path = new Path(new MoveTo(50, 50),
            new LineTo(350, 50),
            new LineTo(350, 350),
            new LineTo(50, 350),
            new ClosePath());
        
        PathTransition pathTransition = new PathTransition();
        pathTransition.setDuration(Duration.seconds(5));
        pathTransition.setNode(rect);
        pathTransition.setPath(path);
        pathTransition.setAutoReverse(true);
        pathTransition.setCycleCount(Timeline.INDEFINITE);
        pathTransition.setInterpolator(Interpolator.LINEAR);
        
        Group root = new Group(rect);
        Scene scene = new Scene(root, 400, 400);
        
        pathTransition.play();
        
        primaryStage.setTitle("Example 99. PathTransition");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

This is the output during the animation (on the left side):


Monday, July 11, 2016

98. Scale Transition

We can scale a node using ScaleTransition.


The Rectangle rect is scaled up 20% in x and y, in 5 seconds after the button is clicked.


package ex98;

import javafx.animation.ScaleTransition;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Ex98 extends Application {
  
    @Override
    public void start(Stage stage) {
        
        DropShadow dropShadow = new DropShadow();
        dropShadow.setOffsetX(5);
        dropShadow.setOffsetY(5);
        dropShadow.setColor(Color.GOLD);
        
        Rectangle rect = new Rectangle(300, 100, Color.RED);
        rect.setStrokeWidth(5);
        rect.setArcWidth(30);
        rect.setArcHeight(30);
        rect.setStroke(Color.BLUE);
        rect.setEffect(dropShadow);

        Text text = new Text("ScaleTransition");
        text.setFont(Font.font("Geogia", 32));
        
        StackPane stackPane = new StackPane(rect, text);
        
        ScaleTransition scaleTransition = 
                new ScaleTransition(Duration.seconds(5), rect);
        
        scaleTransition.setToX(1.2);
        scaleTransition.setToY(1.2);
        
        Button button = new Button("Start");
        button.setOnAction(e -> { 
            scaleTransition.play();
            button.setVisible(false);
        });
        
        VBox vbox = new VBox(50, stackPane, button); 
        vbox.setAlignment(Pos.CENTER);
        vbox.setStyle("-fx-background-color: gray");

        Scene scene = new Scene(vbox, 400, 300);
        stage.setTitle("Example 98. ScaleTransition");
        
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

This is the output during the animation:


Friday, July 8, 2016

97. Stroke Transition

With stroke transition we can change the border color.


The stroke around a rectangle is changed from blue to green, in 5 seconds.


package ex97;

import javafx.animation.StrokeTransition;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Ex97 extends Application {
  
    @Override
    public void start(Stage stage) {
        
        DropShadow dropShadow = new DropShadow();
        dropShadow.setOffsetX(5);
        dropShadow.setOffsetY(5);
        dropShadow.setColor(Color.GOLD);
        
        Rectangle rect = new Rectangle(300, 100, Color.RED);
        rect.setStrokeWidth(5);
        rect.setArcWidth(30);
        rect.setArcHeight(30);
        rect.setStroke(Color.BLUE);
        rect.setEffect(dropShadow);

        Text text = new Text("StrokeTransition");
        text.setFont(Font.font("Geogia", 32));
        
        StackPane stackPane = new StackPane(rect, text);
        
        StrokeTransition strokeTransition = 
                new StrokeTransition(Duration.seconds(5), rect);
        
        strokeTransition.setToValue(Color.GREEN);
        
        Button button = new Button("Start");
        button.setOnAction(e -> { 
            strokeTransition.play();
            button.setVisible(false);
        });
        
        VBox vbox = new VBox(50, stackPane, button); 
        vbox.setAlignment(Pos.CENTER);
        vbox.setStyle("-fx-background-color: gray");

        Scene scene = new Scene(vbox, 400, 300);
        stage.setTitle("Example 97. StrokeTransition");
        
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

This is the output during the animation:


Wednesday, July 6, 2016

96. Fill Transition

Pressing the Start button will start the Transition to a fill color of green.


The initial color is red, so after 5 seconds it turns to green, and it will interpolate in between. The button becomes invisible after it is clicked.


package ex96;

import javafx.animation.FillTransition;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Ex96 extends Application {
  
    @Override
    public void start(Stage stage) {
        
        DropShadow dropShadow = new DropShadow();
        dropShadow.setOffsetX(5);
        dropShadow.setOffsetY(5);
        dropShadow.setColor(Color.GOLD);
        
        Rectangle rect = new Rectangle(200, 100, Color.RED);
        rect.setStrokeWidth(5);
        rect.setArcWidth(30);
        rect.setArcHeight(30);
        rect.setStroke(Color.BLUE);
        rect.setEffect(dropShadow);

        Text text = new Text("FillTransition");
        text.setFont(Font.font("Geogia", 32));
        
        StackPane stackPane = new StackPane(rect, text);
        
        FillTransition fillTransition = 
                new FillTransition(Duration.seconds(5), rect);
        fillTransition.setToValue(Color.GREEN);
        
        Button button = new Button("Start");
        button.setOnAction(e -> { 
            fillTransition.play();
            button.setVisible(false);
        });
        
        VBox vbox = new VBox(50, stackPane, button); 
        vbox.setAlignment(Pos.CENTER);
        vbox.setStyle("-fx-background-color: gray");

        Scene scene = new Scene(vbox, 400, 300);
        stage.setTitle("Example 96. FillTransition");
        
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

This is the output during the animation:


Monday, July 4, 2016

95. Snapshot

We can save an image of a Node (here a StackPane) to a file.


We have to create a WritableImage using node.snapshot() method.


package ex95;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javax.imageio.ImageIO;

public class Ex95 extends Application {
        public static void main(String[] args) {
               Application.launch(args);
        }

        @Override
        public void start(Stage stage) {
            VBox root = new VBox(50);
            StackPane stackPane = new StackPane();
            
            DropShadow dropShadow = new DropShadow();
            dropShadow.setOffsetX(10);
            dropShadow.setOffsetY(6);
            dropShadow.setColor(Color.BLUE);

            Rectangle rect = new Rectangle(200, 200);
            rect.setArcWidth(175);
            rect.setArcHeight(200);
            rect.setFill(Color.LIME);
                                          
            Text text = new Text("   The\nSnapshot");
            text.setFont(Font.font("Georgia", 32));
            text.setLayoutX(150);
            text.setLayoutY(150);
            
            rect.setEffect(dropShadow);
            text.setEffect(dropShadow);
            stackPane.getChildren().addAll(rect, text);
            
            Button button = new Button("Take Snapshot");
            button.setOnAction(e -> takeSnapshot(stackPane));

            root.getChildren().addAll(stackPane, button);
            root.setAlignment(Pos.CENTER);
            
            Scene scene = new Scene(root,300,400);
            stage.setScene(scene);
            stage.setTitle("Example 95. Snapshot");
            stage.show();
        }

        private void takeSnapshot(Node node) {
               SnapshotParameters params = new SnapshotParameters();
               WritableImage image = node.snapshot(params, null);
               BufferedImage buffImage = 
                       SwingFXUtils.fromFXImage(image, null);
               File file = new File("ex95.png");
            try {
                ImageIO.write(buffImage, "png", file);
            } catch (IOException ex) {
            }
        }
}

This is the output:



When the button (Take Snapshot) is clicked, this is the saved image:


Saturday, July 2, 2016

94. Cropping

An image is read into a byte array (buffer).


A portion of the image, which starts at an offset, is then written to a WritableImage and then viewed using an ImageView.


The portion which is read depends on mouse click. We also check if the region will indeed contain data.


package ex94;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Ex94 extends Application {
    
    int width = 420, height = 524;
    int ulx = 100, uly = 100, w = 80, h = 80;
    int offset;
    Rectangle rectInside;
    PixelWriter pixelWriter;
    byte[] buffer;
    
    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(Stage stage) {
        String imageFile = "president_official_portrait_lores.jpg";
        Image image = new Image(imageFile, width, height, false, false);
        ImageView imageView = new ImageView(image);
        imageView.setOnMouseClicked(this::handleClick);
        
        PixelReader pixelReader = image.getPixelReader();
        buffer = new byte[width * height * 4];
        pixelReader.getPixels(0, 0,
            width, height,
            PixelFormat.getByteBgraInstance(),
            buffer,
            0,
            4*width);
        
        WritableImage writableImage = new WritableImage(width, height);
        pixelWriter = writableImage.getPixelWriter();
        offset = 4*(ulx+width*uly);
        drawImage();
        
        VBox vbox = new VBox(new ImageView(writableImage));
        
        rectInside = new Rectangle(uly, uly, w,h);
        rectInside.setFill(Color.TRANSPARENT);
        rectInside.setStroke(Color.LIME);
        rectInside.setStrokeWidth(1);
        rectInside.setOnMouseClicked(this::handleClick);
        vbox.setLayoutY(height);
        
        Group root = new Group(imageView, rectInside, vbox);
        Scene scene = new Scene(root,width,height+200);
        stage.setScene(scene);
        stage.setTitle("Example 94. Cropping");
        stage.show();
    }
    
    private void handleClick(MouseEvent e) {
        ulx = (int) e.getX()-w/2;
        uly = (int) e.getY()-h/2;
        if ((ulx>0) && (uly>0) && (ulx<(width-w)) && (uly<(height-h))) {
            rectInside.setX(ulx);
            rectInside.setY(uly);
            offset = 4*(ulx+width*uly);
            drawImage();
        }
    }
    
    private void drawImage() {
        pixelWriter.setPixels( 160, 50, w, h,
                PixelFormat.getByteBgraInstance(),
                buffer, offset, 4*width);
    }
}

This is the output when face pixels are selected: