Загрузка данных
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<VBox fx:id="mainContainer" alignment="CENTER" spacing="15.0" style="-fx-background-color: #2c3e50; -fx-background-radius: 10;" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demo.HelloController">
<padding>
<Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
</padding>
<TextField fx:id="display" editable="false" alignment="CENTER_RIGHT" prefHeight="60.0" style="-fx-background-color: #ecf0f1; -fx-background-radius: 5; -fx-text-fill: #2c3e50; -fx-padding: 0 15 0 15;">
<font>
<Font name="Segoe UI Bold" size="24.0" />
</font>
</TextField>
<GridPane hgap="10.0" vgap="10.0">
<Button onAction="#onDigitClick" text="7" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="0" GridPane.rowIndex="0" />
<Button onAction="#onDigitClick" text="8" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="1" GridPane.rowIndex="0" />
<Button onAction="#onDigitClick" text="9" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="2" GridPane.rowIndex="0" />
<Button onAction="#onOperatorClick" text="/" prefWidth="60" prefHeight="60" style="-fx-background-color: #f39c12; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="3" GridPane.rowIndex="0" />
<Button onAction="#onDigitClick" text="4" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="0" GridPane.rowIndex="1" />
<Button onAction="#onDigitClick" text="5" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button onAction="#onDigitClick" text="6" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="2" GridPane.rowIndex="1" />
<Button onAction="#onOperatorClick" text="*" prefWidth="60" prefHeight="60" style="-fx-background-color: #f39c12; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<Button onAction="#onDigitClick" text="1" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="0" GridPane.rowIndex="2" />
<Button onAction="#onDigitClick" text="2" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Button onAction="#onDigitClick" text="3" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Button onAction="#onOperatorClick" text="-" prefWidth="60" prefHeight="60" style="-fx-background-color: #f39c12; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="3" GridPane.rowIndex="2" />
<Button onAction="#onDigitClick" text="0" prefWidth="60" prefHeight="60" style="-fx-background-color: #34495e; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="0" GridPane.rowIndex="3" />
<Button onAction="#onClearClick" text="C" prefWidth="60" prefHeight="60" style="-fx-background-color: #e74c3c; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 18;" GridPane.columnIndex="1" GridPane.rowIndex="3" />
package com.example.demo;
import javafx.animation.*;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.SVGPath;
import javafx.util.Duration;
public class HelloController {
@FXML private TextField display;
@FXML private VBox mainContainer;
private double firstNumber = 0;
private String operator = "";
private boolean start = true;
@FXML
protected void onDigitClick(ActionEvent event) {
if (start) {
display.setText("");
start = false;
}
String value = ((Button)event.getSource()).getText();
display.setText(display.getText() + value);
if (display.getText().equals("0092")) {
showLoveAnimation();
}
}
private void showLoveAnimation() {
// Создаем оверлей (слой поверх калькулятора)
StackPane overlay = new StackPane();
overlay.setStyle("-fx-background-color: rgba(44, 62, 80, 0.9); -fx-background-radius: 10;");
overlay.setPrefSize(mainContainer.getWidth(), mainContainer.getHeight());
// Рисуем сердце кодом
SVGPath heart = new SVGPath();
heart.setContent("M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z");
heart.setFill(Color.web("#e74c3c"));
heart.setScaleX(6);
heart.setScaleY(6);
Label label = new Label("Я люблю тебя, Юля!");
label.setStyle("-fx-text-fill: white; -fx-font-size: 22px; -fx-font-weight: bold;");
label.setTranslateY(100);
overlay.getChildren().addAll(heart, label);
// Добавляем в основной контейнер
Pane root = (Pane) mainContainer.getScene().getRoot();
root.getChildren().add(overlay);
// Анимация биения сердца
ScaleTransition pulse = new ScaleTransition(Duration.seconds(0.5), heart);
pulse.setByX(1.2);
pulse.setByY(1.2);
pulse.setCycleCount(8);
pulse.setAutoReverse(true);
// Плавное появление и исчезновение
FadeTransition fadeIn = new FadeTransition(Duration.seconds(0.5), overlay);
fadeIn.setFromValue(0);
fadeIn.setToValue(1);
FadeTransition fadeOut = new FadeTransition(Duration.seconds(1), overlay);
fadeOut.setFromValue(1);
fadeOut.setToValue(0);
fadeOut.setDelay(Duration.seconds(4));
fadeOut.setOnFinished(e -> {
root.getChildren().remove(overlay);
display.setText("");
});
fadeIn.play();
pulse.play();
fadeOut.play();
}
@FXML
protected void onOperatorClick(ActionEvent event) {
String value = ((Button)event.getSource()).getText();
if (!display.getText().isEmpty()) {
firstNumber = Double.parseDouble(display.getText());
operator = value;
start = true;
}
}
@FXML
protected void onClearClick() {
display.setText("");
operator = "";
start = true;
}
@FXML
protected void onResultClick() {
if (operator.isEmpty() || display.getText().isEmpty()) return;
double secondNumber = Double.parseDouble(display.getText());
double result = 0;
switch (operator) {
case "+": result = firstNumber + secondNumber; break;
case "-": result = firstNumber - secondNumber; break;
case "*": result = firstNumber * secondNumber; break;
case "/": result = (secondNumber != 0) ? firstNumber / secondNumber : 0; break;
}
display.setText(String.valueOf(result));
operator = "";
start = true;
}
}