dcscenebuilder's Introduction
dcscenebuilder's People
dcscenebuilder's Issues
Added HBox, Label and Textfield
Added ControllerGenType -> ON_ACTION_IMPL
Fixed the package folder generation
Class: BaseGenerateHandler
public IFolder getFolder(IFolder folder, String[] basePackage) {
IFolder currentFolder = null;
for (String pack : basePackage) {
if (currentFolder != null) {
currentFolder = currentFolder.getFolder(pack);
} else {
currentFolder = folder.getFolder(pack);
try {
currentFolder.create(true, true, null);
} catch (CoreException e) {
e.printStackTrace();
}
}
}
return currentFolder;
}
Added ControllerImplTemplate
class ControllerImplTemplate implements IGenerator {
StringBuffer onActionBuffer = new StringBuffer
ControllerFieldInitializer onActionInitializer = new ControllerFieldInitializer(ControllerGenType.ON_ACTION_IMPL)
override gen(EmfModel t) '''
package «t.basePackage».controller;
import javafx.event.*;
import javafx.fxml.*;
import javafx.scene.control.*;
public class «t.name.toFirstUpper»Controller extends Base«t.name.toFirstUpper»Controller{
«t.root.initField»
«onActionBuffer.toString»
}
'''
def void getInitField(ENode node) {
if(node!==null){
onActionBuffer.append = '''«onActionInitializer.doSwitch(node)»'''
if (node instanceof EBorderPane) {
node.left.initField
node.right.initField
node.top.initField
node.bottom.initField
node.center.initField
} else {
node.children.forEach[e|e.initField]
}
}
}
}
Including cell factory to example
Button Click for example controller class
-
init listener on VBox in Application
button.setOnAction("onButtonClicked"); -
Example Controller class
public void onButtonClicked(ActionEvent e) {
Node node = DIPlatform.getInstance(FxmlRenderer.class).findNodeBy("BUTTON1");
if (e.getSource()==node) {
Button button = (Button) node;
System.out.println("Clicked!"+e);
}
}
Node size initializsation
Added String ^id to ENode
Change EmfModel controls to root
contains ENode[0..1] root
Fxml Renderer Start Class
package de.dc.fxml2emf.model;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FxmlRendererTest extends Application{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
FxmlRenderer renderer = new FxmlRenderer();
EBorderPane eRoot = ModelFactory.eINSTANCE.createEBorderPane();
eRoot.setLeft(createVBox());
eRoot.setRight(createButton("Right Button"));
eRoot.setTop(createButton("Top Button"));
eRoot.setBottom(createButton("Bottom Button"));
for (int j = 0; j < 10; j++) {
eRoot.getChildren().add(createButton("Button "+j));
}
Parent root = (Parent) renderer.doSwitch(eRoot);
primaryStage.setScene(new Scene(root, 1000, 700));
primaryStage.show();
}
private ENode createVBox() {
EVBox vbox = ModelFactory.eINSTANCE.createEVBox();
vbox.setSpacing(5);
vbox.setMaxHeight(Double.MAX_VALUE);
vbox.setMaxWidth(Double.MAX_VALUE);
for (int i = 0; i < 10 ; i++) {
EButton button = ModelFactory.eINSTANCE.createEButton();
button.setText("Button "+i);
vbox.getChildren().add(button);
}
return vbox;
}
private EButton createButton(String text) {
EButton leftButton = ModelFactory.eINSTANCE.createEButton();
leftButton.setText(text);
leftButton.setMaxHeight(Double.MAX_VALUE);
leftButton.setMaxWidth(Double.MAX_VALUE);
return leftButton;
}
}
FxmlRenderer
package de.dc.fxml2emf.model;
import static java.util.Objects.nonNull;
import de.dc.fxml2emf.model.util.ModelSwitch;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
public class FxmlRenderer extends ModelSwitch{
@Override
public Node caseEBorderPane(EBorderPane object) {
BorderPane node = new BorderPane();
node.setLayoutX(object.getLayoutX());
node.setLayoutY(object.getLayoutY());
if (nonNull(object.getLeft())) {
node.setLeft(doSwitch(object.getLeft()));
}
if (nonNull(object.getRight())) {
node.setRight(doSwitch(object.getRight()));
}
if (nonNull(object.getTop())) {
node.setTop(doSwitch(object.getTop()));
}
if (nonNull(object.getBottom())) {
node.setBottom(doSwitch(object.getBottom()));
}
object.getChildren().forEach(e->{
Node current = doSwitch(e);
node.getChildren().add(current);
});
return node;
}
@Override
public Node caseEVBox(EVBox object) {
VBox node = new VBox();
node.setSpacing(object.getSpacing());
node.setMaxHeight(object.getMaxHeight());
node.setMaxWidth(object.getMaxWidth());
object.getChildren().forEach(e->{
Node current = doSwitch(e);
node.getChildren().add(current);
});
return node;
}
@Override
public Node caseEButton(EButton object) {
Button node = new Button();
node.setText(object.getText());
node.setMaxHeight(object.getMaxHeight());
node.setMaxWidth(object.getMaxWidth());
return node;
}
}
Context menu for Controller Impl Generation
Fxml 2 Emf Meta Model
@ecore(nsURI="http://www.frateranatis.org/fxml2emf")
@genmodel(multipleEditorPages="false",
creationIcons="false",
editDirectory="/de.dc.fxml2emf.model.edit/src-gen",
editorDirectory="/de.dc.fxml2emf.model.editor/src-gen",
richClientPlatform="true",
codeFormatting="true",
importerID="org.eclipse.emf.importer.ecore",
runtimePlatform="RCP",
fileExtensions="fxml2emf",
tableProviders="true", dataTypeConverters="true")
package de.dc.fxml2emf.model
// https://www.ntu.edu.sg/home/ehchua/programming/java/Javafx1_intro.html
class EmfModel{
String controller
String[0..] styleClass
contains ENode[0..] nodes
}
class Styleable{}
class Skinnable{}
abstract class ENode extends Styleable, Skinnable{
}
class ERegion extends ENode{}
class EGroup extends ENode{}
class EWebView extends ENode{}
abstract class EControl extends ERegion{}
abstract class ELabeled extends EControl{}
class ELabel extends ELabeled{}
abstract class EButtonBase extends ELabeled{}
class EButton extends EButtonBase{}
class ECheckBox extends EButtonBase{}
class EHyperlink extends EButtonBase{}
class EMenuButton extends EButtonBase{}
class EToogleButton extends EButtonBase{}
class ERadioButton extends EToogleButton{}
abstract class EAxis extends ERegion{}
class ECatgeoryAxis extends EAxis{}
class EValueAxis extends EAxis{}
abstract class EChart extends ERegion{}
class EPieChart extends EChart{}
class EXYChart extends EChart{}
class EPane extends ERegion{}
class EStackPane extends EPane{}
class EDialogPane extends EPane{}
class EGridPane extends EPane{}
class EHBox extends EPane{}
class EVBox extends EPane{}
class EFlowPane extends EPane{}
class ETilePane extends EPane{}
class EAnchorPane extends EPane{}
class EBorderPane extends EPane{}
EButton with Event Parameter
@Override
public Node caseEButton(EButton object) {
Button node = new Button();
node.setText(object.getText());
for (Method method : EEvents.class.getDeclaredMethods()) {
if (method.getName().startsWith("get")) {
try {
Object o =method.invoke(object, null);
if (o!=null) {
Method controllerMethod = controller.getMethod(String.valueOf(o), Event.class);
if (controllerMethod!=null) {
Method eventMethod = node.getClass().getMethod(method.getName().replaceFirst("get", "set"), null);
eventMethod.invoke(node, (EventHandler<Event>) event -> {
try {
controllerMethod.invoke(controllerInstance, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
});
}
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}
if (isNotBlank(object.getOnAction())) {
node.setOnAction(e->invokeMethod(object.getOnAction(),e));
}
initSize(object, node);
controlRegistry.put(object.getId(), node);
return node;
}
Controller Template
class ControllerTemplate implements IGenerator{
StringBuffer sb = new StringBuffer
ControllerFieldInitializer fieldInitializer = new ControllerFieldInitializer
override gen(EmfModel t)'''
package «t.basePackage».controller;
public class «t.name.toFirstUpper»Controller{
public void initialize(){}
«t.root.initField»«sb.toString»
}
'''
def void getInitField(ENode node){
if(node!==null){
if(!node.id.isNullOrEmpty){
sb.append = '''«fieldInitializer.doSwitch(node)»'''
}
if(node instanceof EBorderPane){
node.left.initField
node.right.initField
node.top.initField
node.bottom.initField
node.center.initField
}else{
node.children.forEach[e| e.initField]
}
}
}
}
EBorderPane set Center implementation
Fixed GenerateModelClass on exist package
if (root instanceof EmfModel) {
EmfModel emfModel = (EmfModel) root;
IProject project = parent.getProject();
IFolder srcFolder = project.getFolder("src");
IFolder genFolder = getFolder(srcFolder, emfModel.getBasePackage().split("\\.")).getFolder("model");
try {
if (!genFolder.exists()) {
genFolder.create(true, true, null);
}
IFile ifile = genFolder.getFile(emfModel.getName()+".java");
ifile.create(new ByteArrayInputStream("Hello World".getBytes()), IResource.NONE, null);
} catch (CoreException e1) {
e1.printStackTrace();
}
try {
parent.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
e.printStackTrace();
}
}
Invoke with Event Parameter
private void invokeMethod(String name, Event event) {
Method initializeMethod;
try {
initializeMethod = controller.getMethod(name,event.getClass());
initializeMethod.invoke(controllerInstance, event);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
Context Menu for Package Explorer
Added base package for generating
Added BaseGeneratedHandler
public abstract class BaseGenerateHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelectionService selectionService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();
ISelection selection = selectionService.getSelection();
if (selection instanceof TreeSelection) {
TreeSelection ss = (TreeSelection) selection;
Object firstElement = ss.getFirstElement();
if (firstElement instanceof IFile) {
IFile model = (IFile) firstElement;
IFolder parent = (IFolder) model.getParent();
FxmlFile fxmlFile = new FxmlFile();
EObject root = fxmlFile.load(model.getRawLocation().toPortableString());
if (root instanceof EmfModel) {
EmfModel emfModel = (EmfModel) root;
IProject project = parent.getProject();
IFolder srcFolder = project.getFolder("src");
IFolder genFolder = getFolder(srcFolder, getGeneratedPackage(emfModel).split("\\."));
try {
if (!genFolder.exists()) {
genFolder.create(true, true, null);
}
IFile ifile = genFolder.getFile(getGeneratedFileName(emfModel));
ifile.create(new ByteArrayInputStream(getGeneratedContent(emfModel).getBytes()), IResource.NONE, null);
} catch (CoreException e1) {
e1.printStackTrace();
}
try {
genFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
e.printStackTrace();
}
}
}
}
return null;
}
protected abstract String getGeneratedContent(EmfModel model);
protected abstract String getGeneratedFileName(EmfModel model);
protected abstract String getGeneratedPackage(EmfModel model);
public IFolder getFolder(IFolder folder, String[] basePackage) {
IFolder currentFolder = null;
for (String pack : basePackage) {
if (currentFolder!=null) {
currentFolder = currentFolder.getFolder(pack);
}else {
currentFolder = folder.getFolder(pack);
}
}
return currentFolder;
}
}
Separated renderer to extra plugin
Remove invalid thread access on set document
Display.getDefault().asyncExec(()->{
document.set(fxmlText);
});
Changed ControllerTemplate
override gen(EmfModel t) '''
package «t.basePackage».controller;
import javafx.event.*;
import javafx.fxml.*;
import javafx.scene.control.*;
public class Base«t.name.toFirstUpper»Controller{
public void initialize(){}
«t.root.initField»
«fieldBuffer.toString»
«onActionBuffer.toString»
}
'''
Application Example Template
public class PersonApplication extends EmfApplication{
@Override
protected String getJavaFXFilePath() {
return "/HelloApplication.javafx";
}
public static void main(String[] args) {
DIPlatform.add(new PersonModul());
DIPlatform.init();
launch(args);
}
@Override
protected FxmlRenderer getRenderer() {
return DIPlatform.getInstance(FxmlRenderer.class);
}
}
Button Trigger Method
@Override
public Node caseEButton(EButton object) {
Button node = new Button();
node.setText(object.getText());
for (Method method : EEvents.class.getDeclaredMethods()) {
if (method.getName().startsWith("get")) {
try {
Object o =method.invoke(object, null);
if (o!=null) {
Method controllerMethod = controller.getMethod(String.valueOf(o), null);
if (controllerMethod!=null) {
Method eventMethod = node.getClass().getMethod(method.getName().replaceFirst("get", "set"));
eventMethod.invoke(node, (EventHandler<Event>) event -> {
try {
controllerMethod.invoke(controllerInstance, null);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
});
}
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}
if (isNotBlank(object.getOnAction())) {
node.setOnAction(e->invokeMethod(object.getOnAction()));
}
initSize(object, node);
controlRegistry.put(object.getId(), node);
return node;
}
Dynamically populating tableview
Added GenerateControllerImpleHandler
public class GenerateControllerImplHandler extends BaseGenerateHandler {
@Override
protected String getGeneratedContent(EmfModel model) {
return new ControllerImplTemplate().gen(model);
}
@Override
protected String getGeneratedFileName(EmfModel model) {
return model.getName()+"Controller.java";
}
@Override
protected String getGeneratedPackage(EmfModel model) {
return model.getBasePackage()+".controller";
}
}
Controller Field Initializer
public class ControllerFieldInitializer extends MmSwitch{
private static final String FIELD_INIT = "@FXML\\nprotected %s %s;";
@Override
public String caseEBorderPane(EBorderPane object) {
if (!object.getId().isEmpty())return "";
return String.format(FIELD_INIT, "BorderPane", object.getId());
}
@Override
public String caseETableView(ETableView object) {
if (!object.getId().isEmpty())return "";
return String.format(FIELD_INIT, "TableView", object.getId());
}
}
Added JavaFX Text
TableView with cellfactory
Changed ControllerFieldInitializer#ON_ACTION_INIT
private static final String ON_ACTION_INIT = "@FXML\npublic abstract void %s(ActionEvent event);\n\n";
How to read info from FXOMObject
private void browseObject(FXOMObject o) {
if (o instanceof FXOMInstance) {
FXOMInstance instance = (FXOMInstance) o;
Class<?> declaredClass = instance.getDeclaredClass();
// PrefWidth, PrefHeight, Stylesheets
// Here: center and left
Map<PropertyName, FXOMProperty> properties = instance.getProperties();
}
System.out.println(o.getGlueElement());
o.getChildObjects().forEach(this::browseObject);
}
Generate Model Class Handler
public class GenerateModelClassHandler extends AbstractHandler{
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelectionService selectionService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();
ISelection selection = selectionService.getSelection();
if (selection instanceof TreeSelection) {
TreeSelection ss = (TreeSelection) selection;
Object firstElement = ss.getFirstElement();
if (firstElement instanceof IFile) {
IFile model = (IFile) firstElement;
System.out.println(model);
}
}
return null;
}
}
Enhanced FxmlRenderer with Registries
private Map<String, Node> controlRegistry = new HashMap<>();
private Map<String, TableColumn<?,?>> columnsRegistry = new HashMap<>();
@SuppressWarnings("unchecked")
public <T extends Node> T findNodeBy(String id) {
return (T) controlRegistry.get(id);
}
public TableColumn<?,?> findColumnBy(String id) {
return columnsRegistry.get(id);
}
Included Jdt plug-ins
Base EmfApplication
import de.dc.javafx.mm.EmfModel;
import de.dc.javafx.mm.file.FxmlFile;
import de.dc.javafx.mm.renderer.FxmlRenderer;
import de.dc.javafx.mm.renderer.FxmlRendererApplication;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public abstract class EmfApplication extends Application{
protected FxmlFile file = new FxmlFile();
protected FxmlRenderer renderer;
@Override
public void start(Stage primaryStage) throws Exception {
renderer = getRenderer();
Parent root = getRoot(getJavaFXFilePath());
primaryStage.setScene(new Scene(root , getWidth(), getHeight()));
primaryStage.show();
}
protected abstract String getJavaFXFilePath();
private double getHeight() {
return 800;
}
private double getWidth() {
return 1200;
}
protected abstract FxmlRenderer getRenderer();
protected Parent getRoot(String path) {
EmfModel model = file.load(FxmlRendererApplication.class.getResource(path).getFile());
return (Parent) renderer.doSwitch(model);
}
}
Prepare command handlers for generating
Refactored controller initializer
FxmlRenderer case emfmodel
@Override
public Node caseEmfModel(EmfModel object) {
if (object.getController()!=null) {
try {
controller = Class.forName(object.getController());
Object instance = controller.newInstance();
Method initializeMethod = controller.getMethod("initialize");
initializeMethod.invoke(instance,null);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
return doSwitch(object.getRoot());
}
Directly convert javafxl to javafx
Fxml Emf File
Added xtext dsl for javafx mm
Added controller impl to ControllerFieldInitializer
private static final String ON_ACTION_IMPL_INIT = "@OverRide\npublic void %s(ActionEvent event) {}\n\n";
private String init(ENode object) {
switch (type) {
case FIELD:
return initField(object);
case ON_ACTION:
return initOnAction(object);
case ON_ACTION_IMPL:
return initOnActionImpl(object);
default:
return "";
}
}
Create Model skeleton
Minimalistic required plugins to run example
de.dc.javafx.mm;bundle-version="0.1.0",
de.dc.javafx.mm.edit;bundle-version="1.0.0",
com.google.inject;bundle-version="3.0.0",
javax.inject;bundle-version="1.0.0",
org.eclipse.emf.ecore.xmi;bundle-version="2.15.0",
org.apache.commons.lang3;bundle-version="3.1.0"
Convert Xtext dsl to EMF
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelectionService selectionService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();
ISelection selection = selectionService.getSelection();
if (selection instanceof TreeSelection) {
TreeSelection ss = (TreeSelection) selection;
Object firstElement = ss.getFirstElement();
if (firstElement instanceof IFile) {
IFile model = (IFile) firstElement;
System.out.println(model.getRawLocation().toPortableString());
// String exportPath = model.getParent().getRawLocation().toPortableString();
String fileName = model.getName();
Injector injector = new MmDslStandaloneSetup().createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
URI uri = URI.createFileURI(model.getRawLocation().toPortableString());
Resource xtextResource = resourceSet.getResource(uri, true);
EcoreUtil.resolveAll(xtextResource);
Resource xmiResource = resourceSet.createResource(URI.createURI(fileName+".xmi"));
xmiResource.getContents().add(xtextResource.getContents().get(0));
try {
xmiResource.save(null);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
Generate Controller Template
Fxml Example
Changed GenerateControllerHandler
public class GenerateControllerHandler extends BaseGenerateHandler {
@Override
protected String getGeneratedContent(EmfModel model) {
return new ControllerTemplate().gen(model);
}
@Override
protected String getGeneratedFileName(EmfModel model) {
return "Base"+model.getName()+"Controller.java";
}
@Override
protected String getGeneratedPackage(EmfModel model) {
return model.getBasePackage()+".controller";
}
}
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.