JavaFX 2. Обработчик событий Button
В данном уроке мы научимся создавать обработчик событий на кнопки, а именно выполнять какие-то действия после нажатия кнопки.
Шаг 1
Для начало создаем новый JavaFX проект:
и в main.xml добавляем следующее содержимое:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.scene.layout.AnchorPane?> <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="149.0" prefWidth="236.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="sample.Controller"> <children> <Button fx:id="button" layoutX="39.0" layoutY="53.0" mnemonicParsing="false" onAction="#onClickMethod" prefHeight="43.5" prefWidth="159.0" text="Click Me!"/> </children> </AnchorPane>
Выглядеть наше окно будет так:
Шаг 2
Дальше создаем если нет класс Main.java, который будет стартовать наше приложение:
package sample; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); primaryStage.setTitle("Hello World"); primaryStage.setScene(new Scene(root, primaryStage.getWidth(), primaryStage.getHeight())); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
в 13 строке мы указываем созданный нами Scene в первом шаге.
Шаг 3
Теперь заходим в Controller.java и привязываемся к нашей кнопки через аннотацию @FXML по fx.id кнопки:
package sample; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.input.MouseEvent; public class Controller { @FXML private Button button; @FXML public void initialize(){ button.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent mouseEvent) { button.setText("Thanks!"); } }); } }
Метод initialize() будет вызываться как только приложение запустится.
В строке 15 мы добавляем addEventHandler, который будет определять событие и выполнять его.
MouseEvent.MOUSE_CLICKED – указывает, что это событие будет срабатывать при клике на кнопку.
handle(MouseEvent mouseEvent) – в этом методе мы описываем действие, которое выполнится при клике на кнопку.
Шаг 4
Теперь хочу вам показать второй способ, с помощью которого можно сделать обработчик событий, но немного по другому.
Для этого в файл main.fxml для компонента button добавим новый атрибут:
<Button fx:id="button" layoutX="39.0" layoutY="53.0" mnemonicParsing="false" onAction="#onClickMethod" prefHeight="43.5" prefWidth="159.0" text="Click Me!"/>
В строке 3 мы видим, что появился новый атрибут onAction=’#onClickMethod’, который указывает на метод в контролере.
Для того чтобы все работало нам нужно зайти в контролер и добавить туда следующий метод:
package sample; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.input.MouseEvent; public class Controller { @FXML private Button button; @FXML public void onClickMethod(){ button.setText("Thanks!"); } }
В строке 14 мы видим метод, который и будет выполнятся при клике на кнопку, так как мы указали в разметке кнопки onAction для этого метода.
Шаг 5
Что в 3-м, что в 4-м шаге мы просто выполняем обработку события для кнопки просто разными способами.
Давайте запустим и посмотрим на результат:
А что если надо увидеть Controller из Application? (Да, я понимаю, что не стоит этим злоупотреблять, но всё-таки?)
Создать переменную типа Controller и потом все что хочешь в ней делай)
Не похоже, чтобы какой-либо пример работал.
Всё прекрасно работает!!!
Выскакивают исключение
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
at com.sun.javafx.application.LauncherImpl$$Lambda$48/1732398722.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException:
/F:/JavaTutorials/testing/bin/application/sample.fxml:8
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2595)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:104)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:918)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:967)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2701)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2521)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2435)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3208)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
at application.Main.start(Main.java:13)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
at com.sun.javafx.application.LauncherImpl$$Lambda$51/1347463798.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
at com.sun.javafx.application.PlatformImpl$$Lambda$44/1051754451.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1830989796.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
at com.sun.javafx.application.PlatformImpl$$Lambda$45/1775282465.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
… 1 more
Caused by: java.lang.ClassNotFoundException: sample.controller
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:916)
… 27 more
Exception running application application.Main
не пойму как решить данную проблему и с чем это может быть связано) может кто знает??
“Теперь заходим в Controller.java и привязываемся к нашей кнопки через аннотацию @FXML по fx.id кнопки:”
И что? Где в коде указан fx.id ???
Ошибка! В шаге 2 на 15 строчке указан “sample.fxml”! А работаем мы с main.fxml.
На 13ой строчке
Добрый день, первым делом хотел сказать спасибо, материал подан очень сжато, но полноценно – все понятно и просто. Но вот IDEA ни в какую не хочет компилить код. Ругается на onAction=”#onClickMethod” и все тут. Падает с ошибкой
“Caused by: javafx.fxml.LoadException: No controller specified.”
Вот сама строка из sample.fxml
А вот код контролера
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
public class Controller {
@FXML
private Button button1;
@FXML
public void onClickMethod(){
button.setText(“Thanks!”);
}
}
Убираешь onAction=”#onClickMethod” и все работает, но естественно не работает обработка событий =(
Хорошо что автор проект тоже выкладывает, посмотрев код внимательнее заметил что IDE автоматически не генерирует fx:id=”button” и fx:controller=”sample.Controller”, именно отсутствие ссылки на контролер и вызывало ошибку. Так что те кто только начинают знакомиться с JavaFX будьте внимательны) А так же буду благодарен автор, если он добавит в статью эту информацию и акцентирует на этом внимание, как мы знаем читает народ бегло, и перечитывает только при возникновении ошибок – сам такой же)))
Хороший ты человек, 4 часа времени а помог только твой комментарий)от души!
О спасибо тебе большое, целый час сидел и думал в чем проблема, а до этого уже и студию переустановил и JDK обновил )
@FXML
private Button button1;
@FXML
public void onClickMethod(){
button.setText(«Thanks!»);
}
button1 не равно button.set…
Большое человеческое спасибо!!