"Processing, for me, has always been just the most wonderful thing ever. It’s given me a mission and a passion, to bring computation to everyone: artists, designers, musicians, biologists, doctors, dancers, animators, bankers, photographers, librarians, fashion designers, architects, psychologists, journalists, and writers, just to name a few. Writing code can be scary, something many mistakenly think is reserved for computer scientists and engineers. Processing has helped eliminate that fear, making programming accessible to a wider audience, particularly artists.”
Fonte: Wikipedia
Ou seja, ele encontrou em processing uma forma de levar programação a mais pessoas. Com JavaFX não é diferente, é possível programar e criar aplicações sem ser um mestre Java - mas, a linguagem ainda aparece as vezes como um empecilho. Eu escrevo esse blog há 4 anos e estou "mexendo" com JavaFX desde a primeira versão, uns 8 anos já e vejo isso acontecendo.
Mas por que o blog então não é sobre Processing? O motivo é que Java é super importante para o mercado e "brincando" com JavaFX você exercita Java também, mas é necessário o equilibrio para que a linguagem Java não seja um empecilho.
Resumindo, criei uma classe que estou usando em aplicações visuais que "imita" o processing - mas é claro que o Processing é um universo a parte, a ideia é tirar partes repetitivas para que se tenha o foco na aplicação visual. O nome da classe é "DrawingApp", como já visto no post sobre as flores e no post sobre o algoritmo Metaballs.
Veja abaixo o exemplo de uma aplicação simples (bolas coloridas) que usa a DrawingApp e o código da classe DrawingApp.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.fxapps.drawingfx; | |
import javafx.scene.paint.Color; | |
public class BouncingBalls extends DrawingApp { | |
Ball[] balls = new Ball[20]; | |
public static void main(String[] args) { | |
launch(); | |
} | |
@Override | |
void setup() { | |
title = "Bouncing Ball Example"; | |
width = 800; | |
height = 600; | |
for (int i = 0; i < balls.length; i++) { | |
balls[i] = new Ball(width / 2, height / 2); | |
} | |
} | |
@Override | |
void draw() { | |
ctx.setFill(Color.LIGHTGRAY); | |
ctx.fillRect(0, 0, width, height); | |
for (Ball ball : balls) { | |
ball.update(); | |
ball.show(); | |
} | |
} | |
class Ball { | |
int x, y, r, speedX, speedY; | |
Color c; | |
public Ball(int x, int y) { | |
this.x = x; | |
this.y = y; | |
this.c = Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255)); | |
r = random.nextInt(100); | |
speedX = 40 - random.nextInt(40) - 20; | |
speedY = random.nextInt(40) - 20; | |
} | |
void update() { | |
this.x+= speedX; | |
this.y+= speedY; | |
if(x < 0 || x > width) { | |
speedX *= -1; | |
} | |
if(y < 0 || y > height) { | |
speedY *= -1; | |
} | |
} | |
void show() { | |
ctx.setFill(c); | |
ctx.fillOval(x, y, r, r); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.fxapps.drawingfx; | |
import static java.lang.Math.pow; | |
import static java.lang.Math.sqrt; | |
import java.util.Random; | |
import javafx.animation.KeyFrame; | |
import javafx.animation.Timeline; | |
import javafx.application.Application; | |
import javafx.scene.Scene; | |
import javafx.scene.canvas.Canvas; | |
import javafx.scene.canvas.GraphicsContext; | |
import javafx.scene.input.KeyEvent; | |
import javafx.scene.input.MouseEvent; | |
import javafx.scene.layout.StackPane; | |
import javafx.stage.Stage; | |
import javafx.util.Duration; | |
/** | |
* | |
* Class to quick start drawing with JavaFX. Just extend this class and create your application! | |
* | |
* @author wsiqueir | |
* | |
*/ | |
public abstract class DrawingApp extends Application { | |
public int frames = 10; | |
public String title = "My App"; | |
public static int width = 600; | |
public static int height = 400; | |
public static Random random = new Random(); | |
Canvas canvas = new Canvas(); | |
GraphicsContext ctx = canvas.getGraphicsContext2D(); | |
@Override | |
public void start(Stage stage) throws Exception { | |
setup(); | |
canvas.setHeight(height); | |
canvas.setWidth(width); | |
canvas.setOnMouseClicked(this::mouseCliked); | |
canvas.setOnMouseDragged(this::mouseDragged); | |
canvas.setOnMouseMoved(this::mouseMoved); | |
canvas.setOnMouseEntered(this::mouseEntered); | |
canvas.setOnMouseExited(this::mouseExited); | |
canvas.setOnKeyPressed(this::keyPressed); | |
canvas.setOnKeyTyped(this::keyTyped); | |
canvas.setOnKeyReleased(this::keyReleased); | |
StackPane raiz = new StackPane(canvas); | |
stage.setTitle(title); | |
stage.setScene(new Scene(raiz, width, height)); | |
stage.show(); | |
canvas.requestFocus(); | |
KeyFrame frame = new KeyFrame(Duration.millis(1000 / frames), e -> draw()); | |
Timeline timeline = new Timeline(frame); | |
timeline.setCycleCount(Timeline.INDEFINITE); | |
timeline.play(); | |
} | |
// classical setup and draw methods from Processing | |
void setup() { | |
} | |
void draw() { | |
} | |
// event listeners - if user override the method with event, the method | |
// without event won't be called | |
public void mouseCliked(MouseEvent e) { | |
mouseCliked(); | |
} | |
public void mouseDragged(MouseEvent e) { | |
mouseDragged(); | |
} | |
public void mouseMoved(MouseEvent e) { | |
mouseMoved(); | |
} | |
public void mouseEntered(MouseEvent e) { | |
mouseEntered(); | |
} | |
public void mouseExited(MouseEvent e) { | |
mouseExited(); | |
} | |
public void keyPressed(KeyEvent e) { | |
keyPressed(); | |
} | |
public void keyTyped(KeyEvent e) { | |
keyTyped(); | |
} | |
public void keyReleased(KeyEvent e) { | |
keyReleased(); | |
} | |
public void mouseCliked() { | |
} | |
public void mouseDragged() { | |
} | |
public void mouseMoved() { | |
} | |
public void mouseEntered() { | |
} | |
public void mouseExited() { | |
} | |
public void keyPressed() { | |
} | |
public void keyTyped() { | |
} | |
public void keyReleased() { | |
} | |
/* | |
* Utility methods | |
*/ | |
public double distance(double x, double y, double x2, double y2) { | |
return sqrt(pow(x2 - x, 2) + pow(y2 - y, 2)); | |
} | |
} |
Nenhum comentário:
Postar um comentário