// Importaciones necesarias de JavaFX
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class UD02T01_Lienzo extends Application {

    // Definimos constantes para el tamaño de la cuadrícula y de las celdas
    private static final int GRID_SIZE = 100;     // 100 x 100 celdas
    private static final int CELL_SIZE = 6;       // tamaño visual de cada celda en píxeles

    // Propiedad de color actual (por simplicidad, Color)
    private Color colorActual = Color.WHITE;

    // Borde para el botón seleccionado (gris) y “sin borde”
    private static final String BORDER_SELECTED = "-fx-border-color: #888; -fx-border-width: 3; -fx-border-radius: 3;";
    private static final String BORDER_CLEAR = "-fx-border-color: transparent; -fx-border-width: 0;";

    // Bandera que indica si el usuario está “pintando” (ratón pulsado)
    private boolean pintando = false;

    @Override
    public void start(Stage stage) {
        // Creamos el título superior
        Label titulo = new Label("lienzo de pintar");
        titulo.setStyle("-fx-font-size: 20px; -fx-font-weight: bold; -fx-text-fill: #1f3a5f;");

        // Creamos los 4 botones de color
        Button btnRojo = new Button("Rojo");
        Button btnVerde = new Button("Verde");
        Button btnAzul = new Button("Azul");
        Button btnAmarillo = new Button("Amarillo");

        // Asignamos un estilo base a los botones (tamaño, color de fondo)
        btnRojo.setStyle(BORDER_CLEAR + " -fx-background-color: #e53935; -fx-text-fill: white; -fx-font-weight: bold;");
        btnVerde.setStyle(BORDER_CLEAR + " -fx-background-color: #43a047; -fx-text-fill: white; -fx-font-weight: bold;");
        btnAzul.setStyle(BORDER_CLEAR + " -fx-background-color: #1e88e5; -fx-text-fill: white; -fx-font-weight: bold;");
        btnAmarillo.setStyle(BORDER_CLEAR + " -fx-background-color: #fdd835; -fx-text-fill: #333; -fx-font-weight: bold;");

        // Definimos tamaños de los botones de color
        btnRojo.setPrefSize(90, 32);
        btnVerde.setPrefSize(90, 32);
        btnAzul.setPrefSize(90, 32);
        btnAmarillo.setPrefSize(90, 32);

        // Creamos un contenedor para los botones de color
        HBox barraColores = new HBox(10);
        barraColores.setAlignment(Pos.CENTER);
        barraColores.getChildren().addAll(btnRojo, btnVerde, btnAzul, btnAmarillo);

        // Manejador para actualizar selección visual y colorActual
        Runnable limpiarBordes = () -> {
            btnRojo.setStyle(btnRojo.getStyle().replace(BORDER_SELECTED, BORDER_CLEAR));
            btnVerde.setStyle(btnVerde.getStyle().replace(BORDER_SELECTED, BORDER_CLEAR));
            btnAzul.setStyle(btnAzul.getStyle().replace(BORDER_SELECTED, BORDER_CLEAR));
            btnAmarillo.setStyle(btnAmarillo.getStyle().replace(BORDER_SELECTED, BORDER_CLEAR));
        };

        // Asignamos eventos de selección de color
        btnRojo.setOnAction(e -> {
            limpiarBordes.run();
            btnRojo.setStyle(BORDER_SELECTED + btnRojo.getStyle().replace(BORDER_CLEAR, ""));
            colorActual = Color.RED;
        });
        btnVerde.setOnAction(e -> {
            limpiarBordes.run();
            btnVerde.setStyle(BORDER_SELECTED + btnVerde.getStyle().replace(BORDER_CLEAR, ""));
            colorActual = Color.GREEN;
        });
        btnAzul.setOnAction(e -> {
            limpiarBordes.run();
            btnAzul.setStyle(BORDER_SELECTED + btnAzul.getStyle().replace(BORDER_CLEAR, ""));
            colorActual = Color.BLUE;
        });
        btnAmarillo.setOnAction(e -> {
            limpiarBordes.run();
            btnAmarillo.setStyle(BORDER_SELECTED + btnAmarillo.getStyle().replace(BORDER_CLEAR, ""));
            colorActual = Color.YELLOW;
        });

        // Creamos el GridPane que actuará como lienzo 100x100
        GridPane lienzo = new GridPane();
        lienzo.setHgap(0);
        lienzo.setVgap(0);
        lienzo.setGridLinesVisible(false); // puede ponerse true para ver rejilla
        lienzo.setAlignment(Pos.CENTER);

        // Añadimos padding alrededor del lienzo
        lienzo.setPadding(new Insets(10));

        // Creamos las 10.000 celdas como Rectangles
        for (int fila = 0; fila < GRID_SIZE; fila++) {
            for (int col = 0; col < GRID_SIZE; col++) {
                // Creamos una celda tipo Rectangle
                Rectangle cell = new Rectangle(CELL_SIZE, CELL_SIZE, Color.WHITE);
                cell.setStroke(null); // sin borde para mejor rendimiento/estética

                cell.setOnMouseEntered(eh -> {
                    if (pintando) {
                        cell.setFill(colorActual);
                    }
                });
                // Añadimos la celda a la posición (col, fila)
                lienzo.add(cell, col, fila);
            }
        }

        lienzo.setOnMouseClicked(eh -> {
            pintando = !pintando;
        });

        // Contenedor principal: título + barra de colores + lienzo
        VBox root = new VBox(12);
        root.setPadding(new Insets(16));
        root.setAlignment(Pos.TOP_CENTER);
        root.getChildren().addAll(titulo, barraColores, lienzo);

        // Ajuste visual del fondo del área principal
        root.setBackground(new Background(new BackgroundFill(Color.web("#f7f9fc"), new CornerRadii(8), Insets.EMPTY)));

        // Creamos la escena y la mostramos
        Scene scene = new Scene(root, 600, 600);
        stage.setTitle("Lienzo de pintar");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Última modificación: domingo, 23 de novembro de 2025, 6:46 PM