FXML tutorial (5) – skrypt zewnętrzny
Skrypt nie musi być umieszczony w pliku FXML. Może być skryptem zewnętrznym.
Skrypt outer.groovy
package codes /** * Zwróć uwagę na oznaczenie pakietu. * Ten plik zostanie automatycznie (i zawsze) skompilowany do * pliku outer.class */ def showText1() { lab1.setText("Wybrałeś 'Tak'") } def showText2() { lab1.setText("Wybrałeś 'Nie'") } def showText3() { lab1.setText("Wybrałeś 'Anuluj'") }
Plik listing05_fxscript_outer.fxml
<?xml version="1.0" encoding="UTF-8"?> <?language groovy?> <?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.HBox?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.Button?> <VBox xmlns:fx="http://javafx.com/fxml"> <Label fx:id="lab1" text="Twoja decyzja?" /> <HBox fx:id="hbox"> <Button fx:id="but1" text="Tak" onAction="showText1();" /> <Button fx:id="but2" text="Nie" onAction="showText2()" /> <Button fx:id="but3" text="Anuluj" onAction="showText3()" /> </HBox> <fx:script source="../codes/outer.groovy" charset="utf-8"/> </VBox>
Tutaj pojawia się problem przedstawiony na rys. 1.
Atrybut charset
jest prawidłowy i nie sprawia kłopotu przy uruchamianiu kodu.
Klasa Listing05_fxscript_outer.java
Jest to klasa uruchamiająca.
package codes; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.net.URL; public class Listing05_fxscript_outer extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { try { URL fxmlUrl = this.getClass().getClassLoader() .getResource("resources/listing05_fxscript_outer.fxml"); VBox root = fxmlUrl != null ? FXMLLoader.load(fxmlUrl) : new VBox(); Scene scene = new Scene(root, 150, 80); stage.setScene(scene); stage.show(); } catch (Exception e) { e.printStackTrace(); } } }
Po uruchomieniu kodu pojawia się kolejny błąd:
javafx.fxml.LoadException: /C:/Users/Jacek/IdeaProjects/groovylang/out/production/fxmlgroovyscript/resources/listing05_fxscript_outer.fxml:15 at javafx.fxml@19/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707) at javafx.fxml@19/javafx.fxml.FXMLLoader$ScriptElement.processStartElement(FXMLLoader.java:1606) at javafx.fxml@19/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3331) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3287) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3255) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3227) at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3203) at javafx.fxml@19/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3196) at fxmlgroovyscript/codes.Listing05_fxscript_outer.start(Listing05_fxscript_outer.java:20) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847) at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484) at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456) at javafx.graphics@19/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at javafx.graphics@19/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics@19/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184) at java.base/java.lang.Thread.run(Thread.java:1589) Caused by: javafx.fxml.LoadException: /C:/Users/Jacek/IdeaProjects/groovylang/out/production/fxmlgroovyscript/resources/listing05_fxscript_outer.fxml:15 at javafx.fxml@19/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707) at javafx.fxml@19/javafx.fxml.FXMLLoader$ScriptElement.processStartElement(FXMLLoader.java:1577) ... 19 more Caused by: java.io.FileNotFoundException: C:\Users\Jacek\IdeaProjects\groovylang\out\production\fxmlgroovyscript\codes\outer.groovy (Nie można odnaleźć określonego pliku) at java.base/java.io.FileInputStream.open0(Native Method) at java.base/java.io.FileInputStream.open(FileInputStream.java:219) at java.base/java.io.FileInputStream.(FileInputStream.java:158) at java.base/java.io.FileInputStream. (FileInputStream.java:112) at java.base/sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:86) at java.base/sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:189) at java.base/java.net.URL.openStream(URL.java:1162) at javafx.fxml@19/javafx.fxml.FXMLLoader$ScriptElement.processStartElement(FXMLLoader.java:1564) ... 19 more
Problemem jest to, że Groovy oczekuje nieskompilowanego (źródłowego) pliku skryptu w folderze out\production\fxmlgroovyscript\codes\
z plikami skompilowanymi, ale kompilator go tam nie umieszcza. Jeżeli ręcznie przeniesiemy plik źródłowy – kod będzie wykonywany prawidłowo.