JavaFX, HelloWorld — продолжение

от автора

HelloWorld из примера, предложенного Oracle в «Getting Started with JavaFX», на ПК с Windows. Развитие простейшего приложения до окна ввода логина и пароля. По-прежнему с использованием командной строки с приоткрытием недоговоренностей туториала, в котором приведен код этого приложения.

В предыдущем посте получилось завести пример из первого раздела Getting Started with JavaFX.

HelloWorld.java

package helloworld;   import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage;   public class HelloWorld extends Application {     public static void main(String[] args) {         launch(args);     }          @Override     public void start(Stage primaryStage) {         primaryStage.setTitle("Hello World!");         Button btn = new Button();         btn.setText("Say 'Hello World'");         btn.setOnAction(new EventHandler<ActionEvent>() {               @Override             public void handle(ActionEvent event) {                 System.out.println("Hello World!");             }         });                  StackPane root = new StackPane();         root.getChildren().add(btn);         primaryStage.setScene(new Scene(root, 300, 250));         primaryStage.show();     } } 

Пример был скомпилирован, запущен, упакован в jar и запущен из jar с помощью командной строки.

Командная строка

@"C:\Program Files\Java\jdk1.7.0_40\bin\javac" -d out -classpath "C:\Program Files\Java\jre7\lib\jfxrt.jar" src\helloworld\HelloWorld.java @"C:\Program Files\Java\jdk1.7.0_40\bin\java" -classpath "C:\Program Files\Java\jre7\lib\jfxrt.jar;.\out" helloworld.HelloWorld @"C:\Program Files\Java\jdk1.7.0_40\bin\javafxpackager" -createjar -appclass helloworld.HelloWorld -srcdir .\out -outfile HelloWorld -v @"C:\Program Files\Java\jre7\bin\java.exe" -jar HelloWorld.jar @pause 

Каждая команда для удобства была спрятана в файл .cmd. Забавно, но наглядно. Продолжим использовать эти команды.

Во втором разделе предлагается сделать форму ввода логина и пароля, с блэкдже элементами управления. Попробуем развить имеющийся пример, оставив как есть пакет и класс &mdash helloworld.HelloWorld. jfxpub-get_started предлагает создать новый проект в NetBeans. Однако, пропустим первые три пункта из «Create the Project», а четвертый, замену тела метода «start» кодом из примера 2-1, применим к имеющемуся у нас файлу HelloWorld.java:

    @Override 	public void start(Stage primaryStage) { 	    primaryStage.setTitle("JavaFX Welcome");          	    primaryStage.show(); 	} 

Задача сводится к удалению строк с 18 по 29 и замене заголовка primaryStage. В таком виде файл откомпилируется и запустится, но такая ерунда получится, ничего интересного. Далее туториал предлагает использовать GridPane layout, потому что оно позволяет создавать столбцы и строки для размещения элементов управления, и это вроде как удобно. Послушаемся, и добавим код перед primaryStage.show():

	    GridPane grid = new GridPane(); 	    grid.setAlignment(Pos.CENTER); 	    grid.setHgap(10); 	    grid.setVgap(10); 	    grid.setPadding(new Insets(25, 25, 25, 25)); 	    Scene scene = new Scene(grid, 300, 275); 	    primaryStage.setScene(scene) 

А вот это уже не откомпилируется:

Ошибки компиляции

src\helloworld\HelloWorld.java:18: error: cannot find symbol 		GridPane grid = new GridPane(); 		^   symbol:   class GridPane   location: class HelloWorld src\helloworld\HelloWorld.java:18: error: cannot find symbol 		GridPane grid = new GridPane(); 		                    ^   symbol:   class GridPane   location: class HelloWorld src\helloworld\HelloWorld.java:19: error: cannot find symbol 		grid.setAlignment(Pos.CENTER); 		                  ^   symbol:   variable Pos   location: class HelloWorld src\helloworld\HelloWorld.java:22: error: cannot find symbol 		grid.setPadding(new Insets(25, 25, 25, 25)); 		                    ^   symbol:   class Insets   location: class HelloWorld 4 errors 

Итого: не найдены классы GridPane, Pos и Insets. А где их искать? Я тоже не знал. Но на сайте Oracle нашел вот такой «справочник». Из него ясно, что

 GridPane - Class in javafx.scene.layout     GridPane lays out its children within a flexible grid of rows and columns. Pos - Enum in javafx.geometry     A set of values for describing vertical and horizontal positioning and alignment. Insets - Class in javafx.geometry     A set of inside offsets for the 4 side of a rectangular area 

Это значит, что надо добавить строчки импорта:

import javafx.scene.layout.GridPane; import javafx.geometry.*; 

Теперь файл откомпилируется и запустится, но все еще ничего интересного. Продолжим наполнять по рекомендациям туториала. Добавим код с элементами управления после строчки, устанавливающей свойство Padding таблицы grid, то есть, перед Scene scene = new Scene(grid, 300, 275).

Добавка к HelloWorld.java

	    Text scenetitle = new Text("Welcome"); 	    scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20)); 	    grid.add(scenetitle, 0, 0, 2, 1); 	    Label userName = new Label("User Name:"); 	    grid.add(userName, 0, 1); 	    TextField userTextField = new TextField(); 	    grid.add(userTextField, 1, 1); 	    Label pw = new Label("Password:"); 	    grid.add(pw, 0, 2); 	    PasswordField pwBox = new PasswordField(); 	    grid.add(pwBox, 1, 2);  	    Button btn = new Button("Sign in"); 	    HBox hbBtn = new HBox(10); 	    hbBtn.setAlignment(Pos.BOTTOM_RIGHT); 	    hbBtn.getChildren().add(btn); 	    grid.add(hbBtn, 1, 4);  	    final Text actiontarget = new Text(); 		    grid.add(actiontarget, 1, 6);  	    btn.setOnAction(new EventHandler<ActionEvent>() { 	      		@Override 		public void handle(ActionEvent e) { 		    actiontarget.setFill(Color.FIREBRICK); 		    actiontarget.setText("Sign in button pressed"); 		} 	    }); 

Получаем длинную простыню ошибок. Но они уже знакомы и понятны. Мы, оказывается, не в курсе, кто такие Text, Font, Label, Color и еще некоторые их друзья. Пороемся в упомянутом справочнике, посмотрим, в каких пакетах их родина. Добавим импорт:

import javafx.scene.text.*; import javafx.scene.control.*; import javafx.scene.paint.*; import javafx.scene.layout.HBox; 

Такое вот у меня здесь произвольное отношение к звездочкам. Пожалуй, лучше поменьше звездочек — чем меньше импорта, тем быстрее загрузится. Наверное. Для учебных целей сойдет и так. Кстати, import javafx.scene.* не импортирует автоматом javafx.scene.text.* и import javafx.scene.paint.*.

Теперь компилируется и работает. Надо коротенько разобрать наделанное:

  • javafx.application.Application — главный класс приложения JavaFX.
  • Его метод start() является точкой входа.
  • Класс Stage — контейнер верхнего уровня для создания пользовательского интерфейса (окно).
  • Класс Scene — контейнер следующего уровня и содержит все элементы.
  • Наша сцена основана на GridPane, которая является как бы таблицей, в ячейках которой можно расположить элементы интерфейса. HGap и VGap определяют зазор между столбцами и строками соответственно. Padding задает зазор между краем таблицы и краем окна, который таблица постарается по возможности выдерживат. Строчка «grid.setGridLinesVisible(true);» покажет таблицу в окне — сделает ее линии видимыми.
  • Интересно, что количество строк и столбцов таблицы не задается ее свойствами. Вместо этого мы располагаем некоторые элементы в определенных ячейках (задавая столбец и строку), а таблица «сама» разрастается до нужного количества. Метод grid.add добавляет элемент (первый параметр) в указанную ячейку (второй и третий параметр — столбец, строка). Можно добавить четвертый и пятый параметры (как при добавлении scenetitle) — сколько столбцов и строк использовать под элемент.
  • Метод main() не является необходимым для приложений JavaFX, если JAR-файл создан с помощью javafxpackager (он внедряет JavaFX Launcher в JAR-файл). Однако, полезно оставить этот метод, чтобы иметь возможность запускать JAR-файл, созданный без JavaFX Launcher, например, в IDE с неполной интеграцией с JavaFX. Опять же, Swing-приложения, включающие код JavaFX, требуют метод main().
  • HBox — это такая специальная панелька, которая позволяет задать выравнивание кнопки, засунутой в эту панельку, отличающимся от остальных элементов — с правого края.
  • Остальное достаточно очевидно из кода.

Осталось раскрасить это все с помощью CSS, нарисовать с помощью FXML и объединить эти буквы вместе в одном приложении.

И еще один интересный момент, которым хотелось бы поделиться напоследок. В прошлом посте я упомянул, что если в коде приложения пакет обозвать package HelloWorld, то в папке ./out создастся папка HelloWorld, программа откомпилируется, но не запустится — не будет найден класс. Поправим обратно регистр символов в названии пакета — все снова заработает, хотя регистр символов папки останется «неправильным». ОС Windows на регистр имени папки совершенно плевать, и пересоздавать или переименовывать ее система не будет. На запуск программы из файла HelloWorld.class это не повлияет. А вот если теперь упаковать в .JAR и попытаться его выполнить — полезут ошибки. В архиве папка будет с неправильным (уже без кавычек) регистром двух символов, и этого достаточно, чтобы не найти главный класс приложения. Придется стереть папку ./out/HelloWorld, заново откомпилировать и создать .jar.

ссылка на оригинал статьи http://habrahabr.ru/post/197690/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *