{"id":264437,"date":"2015-08-27T21:58:02","date_gmt":"2015-08-27T17:58:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=264437"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=264437","title":{"rendered":"\u041a\u0430\u043a \u043f\u043e\u0434\u0440\u0443\u0436\u0438\u0442\u044c JavaFX \u0438 Spring Boot"},"content":{"rendered":"<p>     \t<img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/356\/25b\/6a9\/35625b6a9d1243b6b1998caf7f0b9ef0.png\"\/><br \/>  \u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043a\u0430\u043a Spring Boot, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u0443\u0436\u0435 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0441\u0435\u0431\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043d\u0430 Java. \u041e\u0441\u0432\u0435\u0449\u0430\u044f \u043d\u0435\u043e\u0441\u0432\u0435\u0449\u0435\u043d\u043d\u043e\u0435, \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e Spring Boot \u0438 \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u00ab\u043f\u043b\u044e\u0448\u0435\u043a\u00bb \u0441 JavaFX 2.<\/p>\n<p>  \u0412\u0441\u0435\u0445 \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u044e \u043f\u043e\u0434 \u043a\u0430\u0442 \ud83d\ude09<br \/>  <a name=\"habracut\"><\/a><\/p>\n<h4>\u041f\u0440\u0435\u0430\u0431\u043c\u0443\u043b\u0430<\/h4>\n<p>  Spring Boot \u2014 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0432 \u043b\u0438\u0448\u044c \u0440\u0430\u0437 (<i>\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443!<\/i>). \u042f \u0445\u043e\u0447\u0443 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044c \u0442\u0435\u043c\u0443 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u044f \u043d\u0435\u0433\u043e, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 JavaFX. \u041d\u0443 \u0438 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0443\u0447\u043d\u043e, \u043d\u0430\u043f\u0438\u0448\u0443 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0441 <s>\u0431\u043b\u044d\u043a\u0434\u0436\u0435\u043a\u043e\u043c \u0438&#8230;<\/s> \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043a \u0411\u0414.<\/p>\n<h4>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c<\/h4>\n<p>  \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f Maven \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Spring Boot.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">pom.xml<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;dependencies&gt;     &lt;!-- Spring Boot starter --&gt;     &lt;dependency&gt;         &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;         &lt;artifactId&gt;spring-boot-starter&lt;\/artifactId&gt;     &lt;\/dependency&gt;      &lt;!-- Spring Boot JPA - \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0411\u0414, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e --&gt;     &lt;dependency&gt;         &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;         &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;\/artifactId&gt;     &lt;\/dependency&gt;      &lt;!-- H2 \u0411\u0414 --&gt;     &lt;dependency&gt;         &lt;groupId&gt;com.h2database&lt;\/groupId&gt;         &lt;artifactId&gt;h2&lt;\/artifactId&gt;         &lt;scope&gt;runtime&lt;\/scope&gt;     &lt;\/dependency&gt;      &lt;!-- \u0422\u0435\u0441\u0442\u044b --&gt;     &lt;dependency&gt;         &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;         &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;         &lt;scope&gt;test&lt;\/scope&gt;     &lt;\/dependency&gt; &lt;\/dependencies&gt; <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0412 \u0444\u0430\u0439\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0436\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">application.properties<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code># \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b UI ui.title = Spring Boot - JavaFX  # JMX \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0430 \u0435\u0433\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a spring.jmx.enabled=false  # \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0411\u0414 \u0438 JPA spring.datasource.test-on-borrow=true spring.datasource.validation-query=SELECT 1 spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0410 \u0432\u043e\u0442 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u0441\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0439!<br \/>  \u041d\u0430\u043c <u>\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/u> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c Spring \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0432 UI \u043f\u043e\u0442\u043e\u043a\u0435 (\u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0435, \u0447\u0442\u043e \u0438 JavaFX). \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c Spring \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0437 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 JavaFX \u043a\u043b\u0430\u0441\u0441\u0430. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">AbstractJavaFxApplicationSupport.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package ru.habrahabr;  import javafx.application.Application; import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext;  public abstract class AbstractJavaFxApplicationSupport extends Application {      private static String[] savedArgs;      protected ConfigurableApplicationContext context;      @Override     public void init() throws Exception {         context = SpringApplication.run(getClass(), savedArgs);         context.getAutowireCapableBeanFactory().autowireBean(this);     }      @Override     public void stop() throws Exception {         super.stop();         context.close();     }      protected static void launchApp(Class&lt;? extends AbstractJavaFxApplicationSupport&gt; clazz, String[] args) {         AbstractJavaFxApplicationSupport.savedArgs = args;         Application.launch(clazz, args);     } } <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0425\u043e\u0447\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <i>init()<\/i>.<br \/>  \u0418\u043c\u0435\u043d\u043d\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 JavaFX \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e Spring \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430:  <\/p>\n<pre><code class=\"java\">context = SpringApplication.run(getClass(), savedArgs); <\/code><\/pre>\n<p>  \u041d\u0443 \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0431\u0438\u043d\u0430\u043c\u0438:  <\/p>\n<pre><code class=\"java\">context.getAutowireCapableBeanFactory().autowireBean(this); <\/code><\/pre>\n<p>  \u041d\u0430\u0441\u043b\u0435\u0434\u0443\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435, \u0443\u043a\u0430\u0436\u0435\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e JavaFX \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u0443\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c DI \u0438 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u00ab\u043f\u043b\u044e\u0448\u043a\u0438\u00bb \u0441\u043f\u0440\u0438\u043d\u0433\u0430:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Application.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">@Lazy @SpringBootApplication public class Application extends AbstractJavaFxApplicationSupport {      @Value(&quot;${ui.title:JavaFX \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435}&quot;)\/\/     private String windowTitle;      @Autowired     private ControllersConfig.View view;      @Override     public void start(Stage stage) throws Exception {         stage.setTitle(windowTitle);         stage.setScene(new Scene(view.getParent()));         stage.setResizable(true);         stage.centerOnScreen();         stage.show();     }      public static void main(String[] args) {         launchApp(Application.class, args);     }  } <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u041d\u0443 \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443. <br \/>  JavaFX \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043a\u043e\u0434 (controller) \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (view), \u043f\u0440\u0438\u0447\u0435\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 XML \u0432\u0438\u0434\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c *.fxml. \u0414\u043b\u044f \u0441\u0430\u043c\u043e\u0439 \u0432\u044c\u044e\u0445\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 UI \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u2014 <a href=\"http:\/\/www.oracle.com\/technetwork\/java\/javase\/downloads\/javafxscenebuilder-info-2157684.html\">Scene Builder<\/a>.<br \/>  \u0423 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (view):  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">main.fxml<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;  &lt;?import javafx.geometry.Insets?&gt; &lt;?import javafx.scene.control.*?&gt; &lt;?import javafx.scene.layout.*?&gt; &lt;AnchorPane maxHeight=&quot;-Infinity&quot; maxWidth=&quot;-Infinity&quot; minHeight=&quot;-Infinity&quot; minWidth=&quot;-Infinity&quot; prefHeight=&quot;284.0&quot; prefWidth=&quot;405.0&quot; xmlns=&quot;http:\/\/javafx.com\/javafx\/8&quot; xmlns:fx=&quot;http:\/\/javafx.com\/fxml\/1&quot; fx:controller=&quot;ru.habrahabr.ui.MainController&quot;&gt;    &lt;children&gt;       &lt;TableView fx:id=&quot;table&quot; editable=&quot;true&quot; prefHeight=&quot;200.0&quot; prefWidth=&quot;405.0&quot; tableMenuButtonVisible=&quot;true&quot; AnchorPane.bottomAnchor=&quot;50.0&quot; AnchorPane.leftAnchor=&quot;0.0&quot; AnchorPane.rightAnchor=&quot;0.0&quot; AnchorPane.topAnchor=&quot;0.0&quot;&gt;           &lt;columnResizePolicy&gt;&lt;TableView fx:constant=&quot;CONSTRAINED_RESIZE_POLICY&quot; \/&gt;&lt;\/columnResizePolicy&gt;       &lt;\/TableView&gt;       &lt;HBox alignment=&quot;CENTER&quot; layoutX=&quot;21.0&quot; layoutY=&quot;207.0&quot; prefHeight=&quot;50.0&quot; prefWidth=&quot;300.0&quot; AnchorPane.bottomAnchor=&quot;0.0&quot; AnchorPane.leftAnchor=&quot;10.0&quot; AnchorPane.rightAnchor=&quot;10.0&quot;&gt;          &lt;children&gt;             &lt;TextField fx:id=&quot;txtName&quot; promptText=&quot;\u0418\u043c\u044f&quot;&gt;                &lt;HBox.margin&gt;                   &lt;Insets right=&quot;3.0&quot; \/&gt;                &lt;\/HBox.margin&gt;             &lt;\/TextField&gt;             &lt;TextField fx:id=&quot;txtPhone&quot; promptText=&quot;\u0422\u0435\u043b\u0435\u0444\u043e\u043d&quot;&gt;                &lt;HBox.margin&gt;                   &lt;Insets right=&quot;3.0&quot; \/&gt;                &lt;\/HBox.margin&gt;             &lt;\/TextField&gt;             &lt;TextField fx:id=&quot;txtEmail&quot; promptText=&quot;E-mail&quot;&gt;                &lt;HBox.margin&gt;                   &lt;Insets right=&quot;3.0&quot; \/&gt;                &lt;\/HBox.margin&gt;             &lt;\/TextField&gt;             &lt;Button minWidth=&quot;-Infinity&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#addContact&quot; text=&quot;\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c&quot; \/&gt;          &lt;\/children&gt;       &lt;\/HBox&gt;    &lt;\/children&gt; &lt;\/AnchorPane&gt; <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u041b\u0438\u0441\u0442\u0438\u043d\u0433 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0442\u0440\u0443\u0434\u043d\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439, \u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0443 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <i>fx:controller=\u00abru.habrahabr.ui.MainController\u00bb<\/i>. \u041e\u043d \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u043a\u0430\u043a\u043e\u0439 \u043a\u043b\u0430\u0441\u0441-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0410 \u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <i>fx:id=\u00abtxtEmail\u00bb<\/i> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u043a \u043a\u0430\u043a\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044e. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043a\u0430\u043a \u0440\u0430\u0437-\u0442\u0430\u043a\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0440\u0443\u0436\u0438\u0442\u044c \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043e\u0442 JavaFX (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439  @FXML) \u0438 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u043e\u0442 \u0441\u043f\u0440\u0438\u043d\u0433\u0430. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 FXML \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a, \u0442\u043e \u0441\u043f\u0440\u0438\u043d\u0433 \u043d\u0435 \u0443\u0437\u043d\u0430\u0435\u0442 \u043e \u043d\u043e\u0432\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435, \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0432\u043e\u0438\u0445 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0439.<br \/>  \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0430\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">MainController.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package ru.habrahabr.ui;  import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import ru.habrahabr.entity.Contact; import ru.habrahabr.service.ContactService;  import javax.annotation.PostConstruct; import java.util.List;  public class MainController {      \/\/ \u0418\u043d\u044a\u0435\u043a\u0446\u0438\u0438 Spring     @Autowired private ContactService contactService;      \/\/ \u0418\u043d\u044a\u0435\u043a\u0446\u0438\u0438 JavaFX     @FXML private TableView&lt;Contact&gt; table;     @FXML private TextField txtName;     @FXML private TextField txtPhone;     @FXML private TextField txtEmail;      \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435     private ObservableList&lt;Contact&gt; data;      \/**      * \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043e\u0442 JavaFX.      * \u041c\u0435\u0442\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a FXML \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u043b \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u043f\u043e\u043b\u0435\u0439.      *      * \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 &lt;b&gt;\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e&lt;\/b&gt; \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c &quot;initialize&quot;,      * \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u0435\u0442\u043e\u0434 \u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f.      *      * \u0422\u0430\u043a\u0436\u0435 \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0435\u0449\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0431\u0438\u043d\u044b \u0441\u043f\u0440\u0438\u043d\u0433\u0430      * \u0438 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434,      * \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 @PostConstruct.      * \u041a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u043c, \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e,       * \u043a\u0430\u043a \u0438\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u044b \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438.      * {@link MainController#init()}      *\/     @FXML     public void initialize() {     }      \/**      * \u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0443\u0436\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u044b \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438.      *\/     @PostConstruct     public void init() {         List&lt;Contact&gt; contacts = contactService.findAll();         data = FXCollections.observableArrayList(contacts);          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u044b \u043a \u0442\u0430\u0431\u043b\u0438\u0446\u0435         TableColumn&lt;Contact, String&gt; idColumn = new TableColumn&lt;&gt;(&quot;ID&quot;);         idColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;id&quot;));          TableColumn&lt;Contact, String&gt; nameColumn = new TableColumn&lt;&gt;(&quot;\u0418\u043c\u044f&quot;);         nameColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;name&quot;));          TableColumn&lt;Contact, String&gt; phoneColumn = new TableColumn&lt;&gt;(&quot;\u0422\u0435\u043b\u0435\u0444\u043e\u043d&quot;);         phoneColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;phone&quot;));          TableColumn&lt;Contact, String&gt; emailColumn = new TableColumn&lt;&gt;(&quot;E-mail&quot;);         emailColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;email&quot;));          table.getColumns().setAll(idColumn, nameColumn, phoneColumn, emailColumn);          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443         table.setItems(data);     }      \/**      * \u041c\u0435\u0442\u043e\u0434, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 &quot;\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c&quot;.      * \u041f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043a\u043d\u043e\u043f\u043a\u0435 \u0432 FXML \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f.      *\/     @FXML     public void addContact() {         Contact contact = new Contact(txtName.getText(), txtPhone.getText(), txtEmail.getText());         contactService.save(contact);         data.add(contact);          \/\/ \u0447\u0438\u0441\u0442\u0438\u043c \u043f\u043e\u043b\u044f         txtName.setText(&quot;&quot;);         txtPhone.setText(&quot;&quot;);         txtEmail.setText(&quot;&quot;);     } } <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c Spring \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0438 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0432 \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c\u043e\u043c \u0435\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0435. \u0410 \u0441\u0435\u043a\u0440\u0435\u0442 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432 \u0435\u0449\u0435 \u043e\u0434\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Spring Boot:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">ConfigurationControllers.java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">@Configuration public class ConfigurationControllers {      @Bean(name = &quot;mainView&quot;)     public View getMainView() throws IOException {         return loadView(&quot;fxml\/main.fxml&quot;);     }      \/**      * \u0418\u043c\u0435\u043d\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0441\u043f\u0440\u0438\u043d\u0433\u0430,      * \u0438 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438.      *\/     @Bean     public MainController getMainController() throws IOException {         return (MainController) getMainView().getController();     }      \/**      * \u0421\u0430\u043c\u044b\u0439 \u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c FXML \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a.      * \u041a\u0430\u043a \u0440\u0430\u0437-\u0442\u0430\u043a\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u043e\u0431\u044a\u0435\u043a\u0442-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440,      * \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u044b \u0432\u0441\u0435 FXML \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0438 \u0432\u044b\u0437\u0432\u0430\u043d \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430.      *\/     protected View loadView(String url) throws IOException {         InputStream fxmlStream = null;         try {             fxmlStream = getClass().getClassLoader().getResourceAsStream(url);             FXMLLoader loader = new FXMLLoader();             loader.load(fxmlStream);             return new View(loader.getRoot(), loader.getController());         } finally {             if (fxmlStream != null) {                 fxmlStream.close();             }         }     }      \/**      * \u041a\u043b\u0430\u0441\u0441 - \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0430: \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043c\u044b \u043e\u0431\u044f\u0437\u0430\u043d\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0438\u043d\u0430,      * \u0430 view - \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0442\u043e\u0447\u043a\u0435 \u0432\u0445\u043e\u0434\u0430 {@link Application}.      *\/     public class View {         private Parent view;         private Object controller;          public View(Parent view, Object controller) {             this.view = view;             this.controller = controller;         }          public Parent getView() {             return view;         }          public void setView(Parent view) {             this.view = view;         }          public Object getController() {             return controller;         }          public void setController(Object controller) {             this.controller = controller;         }     }  } <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0412\u043e\u0442 \u0438 \u0432\u0441\u0435, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 JavaFX \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e Spring Boot \u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u0432\u0441\u0435 \u0435\u0433\u043e \u043a\u043e\u043b\u043e\u0441\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/2a4\/2c2\/7ef\/2a42c27efd2447ff87d910e6b7005ae5.jpg\"\/><\/p>\n<p>  \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438: <a href=\"https:\/\/github.com\/ruslanys\/fish-springboot-javafx\">https:\/\/github.com\/ruslanys\/fish-springboot-javafx<\/a><\/p>\n<p>  P.S. \u0411\u0443\u0434\u0443 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u043f\u043e\u0441\u0442. \u0411\u0443\u0434\u0443 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0435\u043d \u0437\u0430 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438 \u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.     \t<\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/265511\/\"> http:\/\/habrahabr.ru\/post\/265511\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>     \t<img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/356\/25b\/6a9\/35625b6a9d1243b6b1998caf7f0b9ef0.png\"\/><br \/>  \u041d\u0435 \u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043a\u0430\u043a Spring Boot, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u0443\u0436\u0435 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0441\u0435\u0431\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043d\u0430 Java. \u041e\u0441\u0432\u0435\u0449\u0430\u044f \u043d\u0435\u043e\u0441\u0432\u0435\u0449\u0435\u043d\u043d\u043e\u0435, \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e Spring Boot \u0438 \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u00ab\u043f\u043b\u044e\u0448\u0435\u043a\u00bb \u0441 JavaFX 2.<\/p>\n<p>  \u0412\u0441\u0435\u0445 \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u044e \u043f\u043e\u0434 \u043a\u0430\u0442 \ud83d\ude09  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-264437","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/264437","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=264437"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/264437\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=264437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=264437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=264437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}