Last active
June 27, 2023 19:50
-
-
Save james-d/f7a87a6499f5f9183bbf to your computer and use it in GitHub Desktop.
Demo of event handling and consuming events. Double click to add a rectangle. Selected rectangles have a gold border. Drag a rectangle to move it; drag on empty space to select.
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
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.stream.Collectors; | |
import javafx.application.Application; | |
import javafx.beans.property.ObjectProperty; | |
import javafx.beans.property.SimpleObjectProperty; | |
import javafx.collections.FXCollections; | |
import javafx.collections.ListChangeListener.Change; | |
import javafx.collections.ObservableList; | |
import javafx.geometry.Point2D; | |
import javafx.scene.Scene; | |
import javafx.scene.control.ColorPicker; | |
import javafx.scene.control.ScrollPane; | |
import javafx.scene.input.MouseEvent; | |
import javafx.scene.layout.BorderPane; | |
import javafx.scene.layout.Pane; | |
import javafx.scene.paint.Color; | |
import javafx.scene.shape.Rectangle; | |
import javafx.stage.Stage; | |
public class RectangleDrawing extends Application { | |
private Pane pane; | |
private ObservableList<Rectangle> selectedRects; | |
private List<Rectangle> allRects; | |
@Override | |
public void start(Stage primaryStage) { | |
pane = new Pane(); | |
pane.setMinSize(400, 400); | |
selectedRects = FXCollections.observableArrayList(); | |
selectedRects.addListener((Change<? extends Rectangle> c) -> { | |
allRects.forEach(r -> { | |
if (selectedRects.contains(r)) { | |
r.setStroke(Color.GOLD); | |
} else { | |
r.setStroke(Color.TRANSPARENT); | |
} | |
}); | |
}); | |
allRects = new ArrayList<>(); | |
ColorPicker picker = new ColorPicker(); | |
picker.setValue(Color.BLUE); | |
picker.setOnAction(e -> selectedRects.forEach(r -> r.setFill(picker.getValue()))); | |
pane.setOnMouseClicked(e -> { | |
if (e.getClickCount() == 2) { | |
addNewRectangle(e.getX(), e.getY(), picker.getValue()); | |
} | |
}); | |
Rectangle selectionRect = new Rectangle(); | |
selectionRect.setFill(Color.TRANSPARENT); | |
selectionRect.setStroke(Color.BLACK); | |
ObjectProperty<Point2D> mouseAnchor = new SimpleObjectProperty<>(); | |
pane.setOnMousePressed(e -> { | |
mouseAnchor.set(new Point2D(e.getX(), e.getY())); | |
selectionRect.setX(e.getX()); | |
selectionRect.setY(e.getY()); | |
selectionRect.setWidth(0); | |
selectionRect.setHeight(0); | |
}); | |
pane.setOnMouseDragged(e -> { | |
selectionRect.setX(Math.min(e.getX(), mouseAnchor.get().getX())); | |
selectionRect.setY(Math.min(e.getY(), mouseAnchor.get().getY())); | |
selectionRect.setWidth(Math.abs(e.getX() - mouseAnchor.get().getX())); | |
selectionRect.setHeight(Math.abs(e.getY() - mouseAnchor.get().getY())); | |
}); | |
pane.setOnMouseReleased(e -> { | |
selectedRects.setAll( | |
allRects.stream() | |
.filter(r -> r.getBoundsInParent().intersects(selectionRect.getBoundsInParent())) | |
.collect(Collectors.toList())); | |
selectionRect.setWidth(0); | |
selectionRect.setHeight(0); | |
}); | |
pane.getChildren().add(selectionRect); | |
ScrollPane scroller = new ScrollPane(pane); | |
BorderPane root = new BorderPane(scroller); | |
root.setTop(picker); | |
Scene scene = new Scene(root, 400, 400); | |
primaryStage.setScene(scene); | |
primaryStage.show(); | |
} | |
private void addNewRectangle(double x, double y, Color color) { | |
Rectangle rect = new Rectangle(x, y, 50, 50); | |
rect.setFill(color); | |
rect.setStroke(Color.TRANSPARENT); | |
rect.setStrokeWidth(2); | |
pane.getChildren().add(pane.getChildren().size() - 1, rect); | |
allRects.add(rect); | |
ObjectProperty<Point2D> mouseAnchor = new SimpleObjectProperty<>(); | |
rect.setOnMouseDragged(e -> { | |
double deltaX = e.getX() - mouseAnchor.get().getX(); | |
double deltaY = e.getY() - mouseAnchor.get().getY(); | |
rect.setX(rect.getX() + deltaX); | |
rect.setY(rect.getY() + deltaY); | |
mouseAnchor.set(new Point2D(e.getX(), e.getY())); | |
e.consume(); | |
}); | |
rect.setOnMousePressed(e -> { | |
mouseAnchor.set(new Point2D(e.getX(), e.getY())); | |
e.consume(); | |
}); | |
rect.setOnMouseReleased(MouseEvent::consume); | |
selectedRects.setAll(rect); | |
} | |
public static void main(String[] args) { | |
launch(args); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment