/************************************************** * Author: Morrison * Date: 26 Oct 202020 **************************************************/ import javafx.application.Application; import javafx.application.Platform; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.MenuBar; import javafx.scene.control.ColorPicker; import javafx.scene.paint.Color; import java.util.ArrayList; public class Coordinated extends Application { private Stage primary; private Canvas canvas; private GraphicsContext pen; private Color currentColor; private Color bgColor; private ArrayList shapes; private ArrayList redoBoneyard; private ShapeType currentShape; public Coordinated() { canvas = new Canvas(800,600); pen = canvas.getGraphicsContext2D(); currentColor = Color.BLACK; shapes = new ArrayList<>(); redoBoneyard = new ArrayList<>(); bgColor = Color.WHITE; currentShape = ShapeType.SQUARE; } @Override public void init() { } @Override public void start(Stage primary) { this.primary = primary; BorderPane bp = new BorderPane(); bp.setCenter(canvas); refresh(); bp.setTop(buildMenus()); canvas.setOnMouseClicked( e -> { Drawable s = null; switch(currentShape) { case SQUARE: s = new Square(currentColor, e.getX(), e.getY(), 100); break; case CIRCLE: s = new Circle(currentColor, e.getX(), e.getY(), 100); break; case TRIANGLE: s = new Triangle(currentColor, e.getX(), e.getY(), 100); break; } shapes.add(s); s.draw(pen); }); primary.setScene(new Scene(bp)); primary.show(); } private MenuBar buildMenus() { MenuBar mbar = new MenuBar(); Menu colorMenu = new Menu("Color"); Menu backgroundMenu = new Menu("Background"); Menu undoRedoMenu = new Menu("Undo/Redo"); Menu shapeMenu = new Menu("Shape"); MenuItem undoItem = new MenuItem("Undo"); MenuItem redoItem = new MenuItem("Redo"); MenuItem squareItem = new MenuItem("Square"); MenuItem circleItem = new MenuItem("Circle"); MenuItem triangleItem = new MenuItem("Triangle"); squareItem.setOnAction( e -> { currentShape = ShapeType.SQUARE; }); circleItem.setOnAction( e -> { currentShape = ShapeType.CIRCLE; }); triangleItem.setOnAction( e -> { currentShape = ShapeType.TRIANGLE; }); shapeMenu.getItems().addAll(squareItem, circleItem, triangleItem); undoRedoMenu.getItems().addAll(undoItem, redoItem); undoItem.setOnAction( e -> { if(!shapes.isEmpty()) { redoBoneyard.add(shapes.remove(shapes.size() - 1)); refresh(); } }); redoItem.setOnAction( e -> { if(!redoBoneyard.isEmpty()) { shapes.add(redoBoneyard.remove(redoBoneyard.size() - 1)); refresh(); } }); mbar.getMenus().addAll(undoRedoMenu, backgroundMenu, colorMenu, shapeMenu); colorMenu.getItems().addAll( new ColorMenuItem(Color.RED, "red"), new ColorMenuItem(Color.BLUE, "blue"), new ColorMenuItem(Color.GREEN, "green"), new ColorMenuItem(Color.ORANGE, "orange"), new ColorMenuItem(Color.rgb(0, 0x1a, 0x57), "dook") ); MenuItem customColor = new MenuItem("custom..."); colorMenu.getItems().add(customColor); customColor.setOnAction( choose -> { Stage popup = new Stage(); Pane p = new Pane(); popup.setScene(new Scene(p)); ColorPicker cp = new ColorPicker(); p.getChildren().add(cp); popup.show(); cp.setOnAction( e -> { currentColor = cp.getValue(); popup.close(); }); }); backgroundMenu.getItems().addAll( new BgMenuItem(Color.PINK, "pink"), new BgMenuItem(Color.LIGHTBLUE, "light blue"), new BgMenuItem(Color.WHITE, "white"), new BgMenuItem(Color.BLACK, "black") ); return mbar; } public void refresh() { pen.setFill(bgColor); pen.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); for(Drawable s: shapes) { s.draw(pen); } } @Override public void stop() { } public static void main(String[] args) { Application.launch(); } /********************** Aliens *************************/ class ColorMenuItem extends MenuItem { private final Color color; public ColorMenuItem(Color color, String name) { super(name); this.color = color; setOnAction( e -> { currentColor = color; }); } } class BgMenuItem extends MenuItem { private final Color color; public BgMenuItem(Color color, String name) { super(name); this.color = color; setOnAction( e -> { bgColor = color; refresh(); }); } } enum ShapeType{SQUARE, CIRCLE, TRIANGLE}; }