Hi, If you want to take a look at the sources, they are available at http://git.eclipse.org/c/efxclipse/org.eclipse.efxclipse.git/tree/bundles/tooling/org.eclipse.fx.ide.fxml.compiler. Code is written in xtend - don't judge the code yet, I simply want something going.
The process of the conversion looks like this: FXML => Internal Memory Model => Java ^ ^ SaxParser Converter So I think your request to have different languages as output is possible by implementing e.g. a JavaScript converter. For you second request: Yes there's a helper class named ExtendedFXMLLoader which you feed a FXML-Path and which at first tries to load a compiled class and falling back to FXML if not found (see attached sample). The "biggest" problem I have with Controller-Fields and Methods who are NOT public or package private (depends on the location of the FXML relative to its controller) because there I still need to use reflection. Anyone a good idea to get around reflection in case I can't directly access them? For the initial version I'll simply immediately fallback to reflection and we could get smarter later on. I'll expect a first version which supports the most basic stuff to get out in the next few days. Attached you see my current state. You'll notice the most basic things already work: * Simple properties * Sub-Trees including default properties * Static properties * Properties who need to be created through Builders But naturally there's still a lot left to do ;-) Tom On 31.07.13 16:42, Danno Ferrin wrote: > Where is the code base for this converter? Done properly it can also be > written to spit out the generated stubs, as well as output in any > language the user may prefer. A top grade implementation could > integrate with FXMLLoader for a seamless experience ala .bss files. > > On Tuesday, July 30, 2013, Tom Schindl wrote: > > I don't think it is a good idea to use fxml on embedded and mobile, > we are working on a fxml => java converter so you can add it to your > build process. > > Tom > > Von meinem iPhone gesendet > > Am 31.07.2013 um 08:11 schrieb Niklas Therning <nik...@therning.org > <javascript:;>>: > > >>>> after many days trying to really build iOS apps with JavaFX and > RoboVM > >> or > >>>> Avian I’m very frustrated because of the following things: > >>>> > >>>> Based on RoboVM, JavaFX on iOS runs unacceptable slow - I don’t > know > >> the > >>>> reason - maybe it’s the rendering model of JavaFX - maybe it’s the > >>>> currently unoptimized RoboVM > >>>> One big problem of RoboVM is it’s dependence of the Android > library, it > >>>> does not support the OpenJDK. That’s a big reason for many many > >> problems > >>>> when using JavaFX. So currently it’s not possible to use fxml files > >>>> (FXMLoader) because of the missing Stax xml parser and classes like > >>>> XMLInputFactory in the android library… > > > > There's now a compatibility library for the jfx78 backport which > includes > > the missing sun.* classes from OpenJDK [1]. So that will not be a > problem > > when running on RoboVM/Android. Daniel Zwolenski is working on > getting this > > into Maven which will make it nice and easy to develop with > RoboVM+OpenJFX. > > > > FXMLLoader relies an StAX and the Java Scripting API. Those can > both be > > made to work on RoboVM/Android. The POM of the compat project [1] > contains > > optional dependencies on the StAX API and JSR 223 API. For StAX > you'll also > > need a StAX provider [2][3]. For scripting you'll need a JSR 223 > > implementation of the scripting language you're using, like Rhino for > > JavaScript [4][5]. Please note that I haven't tested FXML but it > should > > work (in theory at least ;-) ). Please give it a go. It will be a > great > > blog story if you can make it work on iOS. > > > > As for the performance issues with RoboVM+OpenJFX: those WILL be > addressed! > > You can either wait for it to happen or you can help out. One way > to do > > that would be sample code that exercises the code paths that need > to be > > optimized (e.g. the button rendering you posted about earlier). > Preferably > > the sample should run repeatedly without user interaction. You > should then > > be able to run Apple's Instruments application to profile this > sample. This > > will help us determine what needs to be optimized. > > > > /Niklas > > > > [1] https://github.com/robovm/robovm-jfx78-compat > > [2] https://github.com/FasterXML/aalto-xml > > [3] http://woodstox.codehaus.org/ > > [4] https://developer.mozilla.org/en-US/docs/Rhino > > [5] > > > > https://java.net/projects/scripting/sources/svn/show/trunk/engines/javascript?rev=236 >
package test; import java.io.IOException; import org.eclipse.fx.core.fxml.ExtendedFXMLLoader; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class CompiledTest extends Application { @Override public void start(Stage primaryStage) { ExtendedFXMLLoader l = new ExtendedFXMLLoader(); try { BorderPane p = l.load(getClass().getClassLoader(), "test/Sample.fxml"); Scene s = new Scene(p,300,300); primaryStage.setScene(s); primaryStage.show(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { launch(args); } }
package test; import org.eclipse.fx.core.fxml.FXMLDocument; import java.util.ResourceBundle; import java.lang.*; import javafx.geometry.Insets; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.geometry.InsetsBuilder; public class Sample extends FXMLDocument<BorderPane> { public BorderPane load(ResourceBundle bundle) { BorderPane root = new BorderPane(); { Button e_1 = new Button(); e_1.setText("Hello World"); root.setCenter(e_1); } { HBox e_2 = new HBox(); { Label e_3 = new Label(); e_3.setText("Label 1"); e_3.setMinWidth(100); e_2.getChildren().add(e_3); HBox.setHgrow(e_3,javafx.scene.layout.Priority.ALWAYS); } { Label e_4 = new Label(); e_4.setText("Label 1"); e_2.getChildren().add(e_4); Insets e_5; InsetsBuilder e_5Builder = InsetsBuilder.create(); e_5Builder.bottom(5); e_5 = e_5Builder.build(); HBox.setMargin(e_4,e_5); } { VBox e_6 = new VBox(); { Label e_7 = new Label(); e_7.setText("Def 1"); e_6.getChildren().add(e_7); } { Label e_8 = new Label(); e_8.setText("Def 2"); e_6.getChildren().add(e_8); } e_2.getChildren().add(e_6); } { VBox e_9 = new VBox(); { Label e_10 = new Label(); e_10.setText("Label 1"); e_9.getChildren().add(e_10); VBox.setVgrow(e_10,javafx.scene.layout.Priority.SOMETIMES); } { GridPane e_11 = new GridPane(); { Label e_12 = new Label(); e_12.setText("In Grid 0/0"); e_11.getChildren().add(e_12); GridPane.setColumnIndex(e_12,0); GridPane.setRowIndex(e_12,0); } { Label e_13 = new Label(); e_13.setText("In Grid 0/1"); e_11.getChildren().add(e_13); GridPane.setColumnIndex(e_13,0); GridPane.setRowIndex(e_13,1); } e_9.getChildren().add(e_11); } e_2.getChildren().add(e_9); } root.setBottom(e_2); } return root; } }