From 8f3a4ef2ee2b5da6585b5fe78994f5b3e5c07590 Mon Sep 17 00:00:00 2001 From: arnaudlabourel <arnaud.labourel@univ-amu.fr> Date: Mon, 23 Oct 2023 17:23:10 +0200 Subject: [PATCH] new template for project --- build.gradle | 2 +- src/main/java/App.java | 51 ------- src/main/java/FirefighterApplication.java | 55 +++++++ src/main/java/Grid.java | 60 -------- src/main/java/Model.java | 105 ------------- src/main/java/controller/Controller.java | 126 ++++++++++++++++ .../controller/PersistentToggleGroup.java | 34 +++++ src/main/java/model/Board.java | 11 ++ src/main/java/model/FirefighterBoard.java | 134 +++++++++++++++++ src/main/java/model/ModelElement.java | 5 + src/main/java/model/Position.java | 5 + src/main/java/view/FirefighterGrid.java | 73 +++++++++ src/main/java/view/Grid.java | 14 ++ src/main/java/view/ViewElement.java | 11 ++ src/main/resources/view/DarkTheme.css | 142 ++++++++++++++++++ src/main/resources/view/view.fxml | 27 ++++ 16 files changed, 638 insertions(+), 217 deletions(-) delete mode 100644 src/main/java/App.java create mode 100644 src/main/java/FirefighterApplication.java delete mode 100644 src/main/java/Grid.java delete mode 100644 src/main/java/Model.java create mode 100644 src/main/java/controller/Controller.java create mode 100644 src/main/java/controller/PersistentToggleGroup.java create mode 100644 src/main/java/model/Board.java create mode 100644 src/main/java/model/FirefighterBoard.java create mode 100644 src/main/java/model/ModelElement.java create mode 100644 src/main/java/model/Position.java create mode 100644 src/main/java/view/FirefighterGrid.java create mode 100644 src/main/java/view/Grid.java create mode 100644 src/main/java/view/ViewElement.java create mode 100644 src/main/resources/view/DarkTheme.css create mode 100644 src/main/resources/view/view.fxml diff --git a/build.gradle b/build.gradle index 8ab23f1..ba8d575 100644 --- a/build.gradle +++ b/build.gradle @@ -28,5 +28,5 @@ test { } application { - mainClass.set("App") + mainClass.set("FirefighterApplication") } \ No newline at end of file diff --git a/src/main/java/App.java b/src/main/java/App.java deleted file mode 100644 index 10dda1d..0000000 --- a/src/main/java/App.java +++ /dev/null @@ -1,51 +0,0 @@ -import javafx.application.Application; -import javafx.scene.Group; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; -import javafx.stage.Stage; - -import static java.lang.Thread.sleep; - - -public class App extends Application { - - public static void main(String[] args) { - launch(args); - } - - @Override - public void start(Stage primaryStage) throws InterruptedException { - Group root = new Group(); - Button restart = new Button("Restart"); - VBox buttons = new VBox(); - HBox total = new HBox(); - Grid grid = new Grid(1000,1000,20,20); - - root.getChildren().add(total); - total.getChildren().add(buttons); - total.getChildren().add(grid); - buttons.getChildren().add(restart); - restart.setOnMouseClicked(grid::restart); - primaryStage.setScene(new Scene(root)); - primaryStage.show(); - grid.repaint(); - new Thread(new Runnable() { - @Override - public void run() { - while(true){ - try { - sleep(50); - grid.model.activation(); - grid.repaint(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - } - }).start(); - } -} - diff --git a/src/main/java/FirefighterApplication.java b/src/main/java/FirefighterApplication.java new file mode 100644 index 0000000..b666b63 --- /dev/null +++ b/src/main/java/FirefighterApplication.java @@ -0,0 +1,55 @@ +import controller.Controller; +import javafx.application.Application; +import javafx.application.Platform; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; +import model.FirefighterBoard; + +import java.io.IOException; +import java.net.URL; + +public class FirefighterApplication extends Application { + private static final String VIEW_RESOURCE_PATH = "/view/view.fxml"; + private static final String APP_NAME = "Firefighter simulator"; + private static final int ROW_COUNT = 50; + private static final int COLUMN_COUNT = 50; + private static final int SQUARE_WIDTH = 20; + private static final int SQUARE_HEIGHT = 20; + public static final int INITIAL_FIRE_COUNT = 3; + public static final int INITIAL_FIREFIGHTER_COUNT = 6; + + private Stage primaryStage; + private Parent view; + private void initializePrimaryStage(Stage primaryStage) { + this.primaryStage = primaryStage; + this.primaryStage.setTitle(APP_NAME); + this.primaryStage.setOnCloseRequest(event -> Platform.exit()); + this.primaryStage.setResizable(false); + this.primaryStage.sizeToScene(); + } + + @Override + public void start(Stage primaryStage) throws IOException { + initializePrimaryStage(primaryStage); + initializeView(); + showScene(); + } + + private void initializeView() throws IOException { + FXMLLoader loader = new FXMLLoader(); + URL location = FirefighterApplication.class.getResource(VIEW_RESOURCE_PATH); + loader.setLocation(location); + view = loader.load(); + Controller controller = loader.getController(); + controller.initialize(SQUARE_WIDTH, SQUARE_HEIGHT, COLUMN_COUNT, ROW_COUNT, + INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); + } + + private void showScene() { + Scene scene = new Scene(view); + primaryStage.setScene(scene); + primaryStage.show(); + } +} diff --git a/src/main/java/Grid.java b/src/main/java/Grid.java deleted file mode 100644 index 23fb50d..0000000 --- a/src/main/java/Grid.java +++ /dev/null @@ -1,60 +0,0 @@ -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.input.MouseEvent; -import javafx.scene.paint.Color; - -public class Grid extends Canvas{ - int width, height, colCount, rowCount; - Model model; - - - public Grid(int width, int height, int colCount, int rowCount) { - super(width,height); - this.width = width; - this.height = height; - this.colCount = colCount; - this.rowCount = rowCount; - setFocusTraversable(true); - setOnMousePressed(this::mousePressed); - model = new Model(this); - model.initialisation(3,8); - } - - public void restart(MouseEvent mouseEvent){ - model = new Model(this); - model.initialisation(3,6); - getGraphicsContext2D().clearRect(0,0,width,height); - repaint(); - } - private void mousePressed(MouseEvent mouseEvent) { - model.activation(); - repaint(); - /*double x = mouseEvent.getX(); - double y = mouseEvent.getY(); - model.click((int)x*rowCount/height,(int)y*colCount/width);*/ - } - - void repaint(){ - for(int col=0; col<colCount; col++) - getGraphicsContext2D().strokeLine(0, col*width/colCount,height, col*width/colCount); - for(int row=0; row<rowCount;row++) - getGraphicsContext2D().strokeLine(row*height/rowCount,0,row*height/rowCount,width); - - } - - void paint(int row, int col){ - getGraphicsContext2D().setFill(Color.WHITE); - getGraphicsContext2D().fillRect(row*height/rowCount,col*width/colCount,height/rowCount,width/colCount); - } - - public void paintFF(int row, int col) { - getGraphicsContext2D().setFill(Color.BLUE); - getGraphicsContext2D().fillRect(row*height/rowCount,col*width/colCount,height/rowCount,width/colCount); - } - - public void paintFire(int row, int col) { - getGraphicsContext2D().setFill(Color.RED); - getGraphicsContext2D().fillRect(row*height/rowCount,col*width/colCount,height/rowCount,width/colCount); - } - -} \ No newline at end of file diff --git a/src/main/java/Model.java b/src/main/java/Model.java deleted file mode 100644 index f23d0d1..0000000 --- a/src/main/java/Model.java +++ /dev/null @@ -1,105 +0,0 @@ -import java.util.*; - - -public class Model { - Grid grid; - int colCount, rowCount; - List<Position> firefighters = new ArrayList<>(); - Set<Position> fires = new HashSet<>(); - List<Position> ffNewPositions; - int step = 0; - - public Model(Grid grid) { - this.grid = grid; - colCount = grid.colCount; - rowCount = grid.rowCount; - } - - - public void initialisation(int fireNumber, int fireFighterNumber){ - for(int index=0; index<fireNumber;index++) - fires.add(randomPosition()); - for(int index=0; index<fireFighterNumber;index++) - firefighters.add(randomPosition()); - } - - private Position randomPosition() { - return new Position((int) (Math.random()*rowCount), (int) (Math.random()*colCount)); - } - - - public void activation(){ - ffNewPositions = new ArrayList<>(); - for(Position ff : firefighters){ - Position newPosition = activateFirefighter(ff); - grid.paint(ff.row,ff.col); - grid.paintFF(newPosition.row, newPosition.col); - ffNewPositions.add(newPosition); - } - firefighters = ffNewPositions; - if(step%2==0){ - List<Position> newFires = new ArrayList<>(); - for(Position fire : fires){ - newFires.addAll(activateFire(fire)); - } - for(Position newFire : newFires) - grid.paintFire(newFire.row, newFire.col); - - fires.addAll(newFires);} - step++; - - } - - private List<Position> activateFire(Position position) { - return next(position); - } - - - - private Position activateFirefighter(Position position) { - Position randomPosition = aStepTowardFire(position); - //next(position).get((int) (Math.random()*next(position).size())); - List<Position> nextFires = next(randomPosition).stream().filter(fires::contains).toList(); - extinguish(randomPosition); - for (Position fire : nextFires) - extinguish(fire); - return randomPosition; - } - - private void extinguish(Position position) { - fires.remove(position); - grid.paint(position.row, position.col); - } - - private List<Position> next(Position position){ - List<Position> list = new ArrayList<>(); - if(position.row>0) list.add(new Position(position.row-1, position.col)); - if(position.col>0) list.add(new Position(position.row, position.col-1)); - if(position.row<rowCount-1) list.add(new Position(position.row+1, position.col)); - if(position.col<colCount-1) list.add(new Position(position.row, position.col+1)); - return list; - } - - private Position aStepTowardFire(Position position){ - Queue<Position> toVisit = new LinkedList<>(); - Set<Position> seen = new HashSet<>(); - HashMap<Position,Position> firstMove = new HashMap<>(); - toVisit.addAll(next(position)); - for(Position initialMove : toVisit) - firstMove.put(initialMove,initialMove); - while(!toVisit.isEmpty()){ - Position current = toVisit.poll(); - if(fires.contains(current)) - return firstMove.get(current); - for(Position adjacent : next(current)){ - if(seen.contains(adjacent)) continue; - toVisit.add(adjacent); - seen.add(adjacent); - firstMove.put(adjacent, firstMove.get(current)); - } - } - return position; - } - - public record Position(int row, int col){} -} \ No newline at end of file diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java new file mode 100644 index 0000000..16e9b0d --- /dev/null +++ b/src/main/java/controller/Controller.java @@ -0,0 +1,126 @@ +package controller; + +import javafx.animation.Animation; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.ToggleGroup; +import javafx.util.Duration; +import javafx.util.Pair; +import model.Board; +import model.ModelElement; +import model.FirefighterBoard; +import model.Position; +import view.FirefighterGrid; +import view.ViewElement; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Objects.requireNonNull; + +public class Controller { + + public static final int PERIOD_IN_MILLISECONDS = 50; + @FXML + private Button restartButton; + @FXML + private ToggleButton pauseToggleButton; + @FXML + private ToggleButton playToggleButton; + @FXML + private FirefighterGrid grid; + private Timeline timeline; + private Board<List<ModelElement>> board; + + @FXML + private void initialize() { + initializePlayAndPauseToggleButtons(); + initializeTimeline(); + } + + private void initializePlayAndPauseToggleButtons() { + ToggleGroup toggleGroup = new PersistentToggleGroup(); + toggleGroup.getToggles().addAll(playToggleButton, pauseToggleButton); + pauseToggleButton.setSelected(true); + } + + private void setModel(FirefighterBoard firefighterBoard) { + this.board = requireNonNull(firefighterBoard, "model is null"); + } + + private void updateBoard(){ + List<Position> updatedPositions = board.updateToNextGeneration(); + List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>(); + for(Position updatedPosition : updatedPositions){ + List<ModelElement> squareState = board.getState(updatedPosition); + ViewElement viewElement = getViewElement(squareState); + updatedSquares.add(new Pair<>(updatedPosition, viewElement)); + } + grid.repaint(updatedSquares); + } + + private void repaintBoard(){ + int columnCount = board.columnCount(); + int rowCount = board.rowCount(); + ViewElement[][] viewElements = new ViewElement[rowCount][columnCount]; + for(int column = 0; column < columnCount; column++) + for(int row = 0; row < rowCount; row++) + viewElements[row][column] = getViewElement(board.getState(new Position(row, column))); + grid.repaint(viewElements); + } + + private ViewElement getViewElement(List<ModelElement> squareState) { + if(squareState.contains(ModelElement.FIREFIGHTER)){ + return ViewElement.FIREFIGHTER; + } + if (squareState.contains(ModelElement.FIRE)){ + return ViewElement.FIRE; + } + return ViewElement.EMPTY; + } + + private void initializeTimeline() { + Duration duration = new Duration(Controller.PERIOD_IN_MILLISECONDS); + EventHandler<ActionEvent> eventHandler = + event -> updateBoard(); + KeyFrame keyFrame = new KeyFrame(duration, eventHandler); + timeline = new Timeline(keyFrame); + timeline.setCycleCount(Animation.INDEFINITE); + } + + public void play() { + timeline.play(); + } + + public void pause() { + timeline.pause(); + } + + public void pauseToggleButtonAction(ActionEvent actionEvent) { + this.pause(); + } + + public void playToggleButtonAction(ActionEvent actionEvent) { + this.play(); + } + + public void restartButtonAction(ActionEvent actionEvent) { + this.pause(); + board.reset(); + pauseToggleButton.setSelected(true); + repaintBoard(); + } + + public void initialize(int squareWidth, int squareHeight, int columnCount, + int rowCount, int initialFireCount, int initialFirefighterCount) { + grid.initialize(squareWidth, squareHeight, columnCount, rowCount); + this.setModel(new FirefighterBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount)); + repaintBoard(); + } + +} \ No newline at end of file diff --git a/src/main/java/controller/PersistentToggleGroup.java b/src/main/java/controller/PersistentToggleGroup.java new file mode 100644 index 0000000..7c2c4b5 --- /dev/null +++ b/src/main/java/controller/PersistentToggleGroup.java @@ -0,0 +1,34 @@ +package controller; + +import javafx.collections.ListChangeListener.Change; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.ToggleGroup; +import javafx.scene.input.MouseEvent; + +/** + * An extension of {@link ToggleGroup} that ensures that a {@link Toggle} in a group must always be + * selected. + * + */ +class PersistentToggleGroup extends ToggleGroup { + + /** + * Creates a new {@code PersistentToggleGroup}. + */ + PersistentToggleGroup() { + getToggles().addListener((Change<? extends Toggle> change) -> { + while (change.next()) { + for (Toggle toggle : change.getAddedSubList()) { + ToggleButton toggleButton = (ToggleButton) toggle; + toggleButton.addEventFilter(MouseEvent.MOUSE_RELEASED, mouseEvent -> { + if (toggleButton.equals(getSelectedToggle())) { + mouseEvent.consume(); + } + }); + } + } + }); + } + +} diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java new file mode 100644 index 0000000..5e24f47 --- /dev/null +++ b/src/main/java/model/Board.java @@ -0,0 +1,11 @@ +package model; + +import java.util.List; + +public interface Board<S> { + S getState(Position position); + int rowCount(); + int columnCount(); + List<Position> updateToNextGeneration(); + void reset(); +} diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java new file mode 100644 index 0000000..2586fe8 --- /dev/null +++ b/src/main/java/model/FirefighterBoard.java @@ -0,0 +1,134 @@ +package model; + +import java.util.*; + + +public class FirefighterBoard implements Board<List<ModelElement>> { + private final int columnCount; + private final int rowCount; + private final int initialFireCount; + private final int initialFirefighterCount; + List<Position> firefighterPositions; + Set<Position> firePositions; + List<Position> firefighterNewPositions; + int step = 0; + + public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.initialFireCount = initialFireCount; + this.initialFirefighterCount = initialFirefighterCount; + initializeElements(); + } + + public void initializeElements() { + firefighterPositions = new ArrayList<>(); + firePositions = new HashSet<>(); + for (int index = 0; index < initialFireCount; index++) + firePositions.add(randomPosition()); + for (int index = 0; index < initialFirefighterCount; index++) + firefighterPositions.add(randomPosition()); + } + + private Position randomPosition() { + return new Position((int) (Math.random() * rowCount), (int) (Math.random() * columnCount)); + } + + @Override + public List<ModelElement> getState(Position position) { + List<ModelElement> result = new ArrayList<>(); + for(Position firefighterPosition : firefighterPositions) + if (firefighterPosition.equals(position)) + result.add(ModelElement.FIREFIGHTER); + if(firePositions.contains(position)) + result.add(ModelElement.FIRE); + return result; + } + + @Override + public int rowCount() { + return rowCount; + } + + @Override + public int columnCount() { + return columnCount; + } + + public List<Position> updateToNextGeneration() { + List<Position> result = activateFirefighters(); + result.addAll(activateFires()); + step++; + return result; + } + + private List<Position> activateFires() { + List<Position> result = new ArrayList<>(); + if (step % 2 == 0) { + List<Position> newFirePositions = new ArrayList<>(); + for (Position fire : firePositions) { + newFirePositions.addAll(neighbors(fire)); + } + firePositions.addAll(newFirePositions); + result.addAll(newFirePositions); + } + return result; + + } + + private List<Position> activateFirefighters() { + List<Position> result = new ArrayList<>(); + firefighterNewPositions = new ArrayList<>(); + for (Position firefighterPosition : firefighterPositions) { + Position newFirefighterPosition = neighborClosestToFire(firefighterPosition); + result.add(firefighterPosition); + result.add(newFirefighterPosition); + firefighterNewPositions.add(newFirefighterPosition); + extinguish(newFirefighterPosition); + List<Position> neighborFirePositions = neighbors(newFirefighterPosition).stream().filter(firePositions::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + result.addAll(firePositions); + } + firefighterPositions = firefighterNewPositions; + return result; + } + + @Override + public void reset() { + initializeElements(); + } + + private void extinguish(Position position) { + firePositions.remove(position); + } + + private List<Position> neighbors(Position position) { + List<Position> list = new ArrayList<>(); + if (position.row() > 0) list.add(new Position(position.row() - 1, position.column())); + if (position.column() > 0) list.add(new Position(position.row(), position.column() - 1)); + if (position.row() < rowCount - 1) list.add(new Position(position.row() + 1, position.column())); + if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1)); + return list; + } + + private Position neighborClosestToFire(Position position) { + Set<Position> seen = new HashSet<>(); + HashMap<Position, Position> firstMove = new HashMap<>(); + Queue<Position> toVisit = new LinkedList<>(neighbors(position)); + for (Position initialMove : toVisit) + firstMove.put(initialMove, initialMove); + while (!toVisit.isEmpty()) { + Position current = toVisit.poll(); + if (firePositions.contains(current)) + return firstMove.get(current); + for (Position adjacent : neighbors(current)) { + if (seen.contains(adjacent)) continue; + toVisit.add(adjacent); + seen.add(adjacent); + firstMove.put(adjacent, firstMove.get(current)); + } + } + return position; + } +} \ No newline at end of file diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java new file mode 100644 index 0000000..759eee5 --- /dev/null +++ b/src/main/java/model/ModelElement.java @@ -0,0 +1,5 @@ +package model; + +public enum ModelElement { + FIREFIGHTER, FIRE +} diff --git a/src/main/java/model/Position.java b/src/main/java/model/Position.java new file mode 100644 index 0000000..08c95ad --- /dev/null +++ b/src/main/java/model/Position.java @@ -0,0 +1,5 @@ +package model; + +public record Position(int row, int column) { + +} diff --git a/src/main/java/view/FirefighterGrid.java b/src/main/java/view/FirefighterGrid.java new file mode 100644 index 0000000..085ad2c --- /dev/null +++ b/src/main/java/view/FirefighterGrid.java @@ -0,0 +1,73 @@ +package view; + +import javafx.scene.canvas.Canvas; +import javafx.scene.paint.Color; +import javafx.util.Pair; +import model.Position; + +import java.util.List; + +public class FirefighterGrid extends Canvas implements Grid<ViewElement>{ + + private void paintElementAtPosition(ViewElement element, Position position) { + paintSquare(position.row(), position.column(), element.color); + } + + private int squareWidth; + private int squareHeight; + private int columnCount; + private int rowCount; + + @Override + public void repaint(List<Pair<Position, ViewElement>> positionedElements) { + for(Pair<Position, ViewElement> pair : positionedElements){ + paintElementAtPosition(pair.getValue(), pair.getKey()); + } + paintLines(); + } + + @Override + public void repaint(ViewElement[][] elements) { + for(int column = 0; column < columnCount; column++) + for(int row = 0; row < rowCount; row++){ + paintElementAtPosition(elements[row][column], new Position(row, column)); + } + paintLines(); + } + + public int getColumnCount() { + return columnCount; + } + + public int getRowCount() { + return rowCount; + } + + public FirefighterGrid(){ + } + + public void initialize(int squareWidth, + int squareHeight, + int columnCount, + int rowCount) { + this.squareWidth = squareWidth; + this.squareHeight = squareHeight; + this.columnCount = columnCount; + this.rowCount = rowCount; + } + + private void paintLines(){ + for(int column=0; column<columnCount; column++) + getGraphicsContext2D().strokeLine(0, column*squareHeight, getWidth(), column*squareWidth); + for(int row=0; row<rowCount;row++) + getGraphicsContext2D().strokeLine(row*squareHeight, 0,row*squareHeight, getHeight()); + } + + private void paintSquare(int row, int column, Color color){ + getGraphicsContext2D().setFill(color); + getGraphicsContext2D().fillRect(row*squareHeight,column*squareWidth,squareHeight,squareWidth); + } + + + +} \ No newline at end of file diff --git a/src/main/java/view/Grid.java b/src/main/java/view/Grid.java new file mode 100644 index 0000000..ee8a612 --- /dev/null +++ b/src/main/java/view/Grid.java @@ -0,0 +1,14 @@ +package view; + +import javafx.scene.paint.Color; +import javafx.util.Pair; +import model.Position; + +import java.util.List; + +public interface Grid<E> { + void repaint(List<Pair<Position,E>> elements); + void repaint(E[][] elements); + int getColumnCount(); + int getRowCount(); +} diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java new file mode 100644 index 0000000..ffb7611 --- /dev/null +++ b/src/main/java/view/ViewElement.java @@ -0,0 +1,11 @@ +package view; + +import javafx.scene.paint.Color; + +public enum ViewElement { + FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + final Color color; + ViewElement(Color color) { + this.color = color; + } +} diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css new file mode 100644 index 0000000..46b78aa --- /dev/null +++ b/src/main/resources/view/DarkTheme.css @@ -0,0 +1,142 @@ +.background { + -fx-background-color: #1d1d1d; +} + +.label { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: white; + -fx-opacity: 0.6; +} + +.label-bright { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: white; + -fx-opacity: 1; +} + +.label-header { + -fx-font-size: 32pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-opacity: 1; +} + +.table-view { + -fx-base: #1d1d1d; + -fx-control-inner-background: #1d1d1d; + -fx-background-color: #1d1d1d; + -fx-table-cell-border-color: transparent; + -fx-table-header-border-color: transparent; + -fx-padding: 5; +} + +.table-view .column-header-background { + -fx-background-color: transparent; +} + +.table-view .column-header, .table-view .filler { + -fx-border-width: 0 0 1 0; + -fx-background-color: transparent; + -fx-border-color: + transparent + transparent + derive(-fx-base, 80%) + transparent; + -fx-border-insets: 0 10 1 0; +} + +.table-view .column-header .label { + -fx-font-size: 20pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-alignment: center-left; + -fx-opacity: 1; +} + +.table-view:focused .table-row-cell:filled:focused:selected { + -fx-background-color: -fx-focus-color; +} + +.split-pane:horizontal > .split-pane-divider { + -fx-border-color: transparent #1d1d1d transparent #1d1d1d; + -fx-background-color: transparent, derive(#1d1d1d,20%); +} + +.split-pane { + -fx-padding: 1 0 0 0; +} + +.menu-bar { + -fx-background-color: derive(#1d1d1d,20%); +} + +.context-menu { + -fx-background-color: derive(#1d1d1d,50%); +} + +.menu-bar .label { + -fx-font-size: 14pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-opacity: 0.9; +} + +.menu .left-container { + -fx-background-color: black; +} + +.text-field { + -fx-font-size: 12pt; + -fx-font-family: "Segoe UI Semibold"; +} + +/* + * Metro style Push Button + * Author: Pedro Duque Vieira + * http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/ + */ +.button { + -fx-padding: 5 22 5 22; + -fx-border-color: #e2e2e2; + -fx-border-width: 2; + -fx-background-radius: 0; + -fx-background-color: #1d1d1d; + -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif; + -fx-font-size: 11pt; + -fx-text-fill: #d8d8d8; + -fx-background-insets: 0 0 0 0, 0, 1, 2; +} + +.button:hover { + -fx-background-color: #3a3a3a; +} + +.button:pressed, .button:default:hover:pressed { + -fx-background-color: white; + -fx-text-fill: #1d1d1d; +} + +.button:focused { + -fx-border-color: white, white; + -fx-border-width: 1, 1; + -fx-border-style: solid; + -fx-border-radius: 0, 0; + -fx-border-insets: 1 1 1 1, 0; +} + +.button:disabled, .button:default:disabled { + -fx-opacity: 0.4; + -fx-background-color: #1d1d1d; + -fx-text-fill: white; +} + +.button:default { + -fx-background-color: -fx-focus-color; + -fx-text-fill: #ffffff; +} + +.button:default:hover { + -fx-background-color: derive(-fx-focus-color,30%); +} \ No newline at end of file diff --git a/src/main/resources/view/view.fxml b/src/main/resources/view/view.fxml new file mode 100644 index 0000000..73d4c93 --- /dev/null +++ b/src/main/resources/view/view.fxml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> +<?import view.FirefighterGrid?> + +<?import javafx.scene.control.ToggleButton?> +<HBox styleClass="background" stylesheets="@DarkTheme.css" + xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" + fx:controller="controller.Controller"> + <VBox> + <Button fx:id="restartButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#restartButtonAction" prefHeight="24.0" prefWidth="200.0" + text="Restart"/> + <ToggleButton fx:id="playToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#playToggleButtonAction" prefHeight="24.0" + prefWidth="200.0" styleClass="button" text="Play"/> + <ToggleButton fx:id="pauseToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#pauseToggleButtonAction" prefHeight="24.0" + prefWidth="200.0" styleClass="button" text="Pause"/> + </VBox> + <FirefighterGrid fx:id="grid" width="1000.0" height="1000.0" + xmlns="http://javafx.com/javafx" + xmlns:fx="http://javafx.com/fxml"> + </FirefighterGrid> +</HBox> -- GitLab