Skip to main content

Embedding JavaFX Scene Builder 2.0 in NetBeans - Part 3

Posted by sven on July 28, 2014 at 6:23 AM PDT

Tired of JavaFX Scene Builder being run in a separate process? Fed up with no real integration between your favorite IDE and JavaFX Scene Builder? There may be a solution heading towards you. Follow this small series of blog entries to join me on my journey towards an embedded JavaFX Scene Builder in NetBeans.

Welcome back (you did read the first two parts of this series?)!

Ok, having done a bit of magic to Scene Builder 2.0 ea in the first two part of this series, let's go for some more integration. Goal of this part is to get the inspector view, the css panel and the library panel from Scene Builder integrated - looking like this



To achieve this we create a new TopComponent for each panel to show. The major thing is trying to get a reference to the EditorController via the selected Node. The following example code registers a listener so that lookup changes will be propagated to our TopComponent.

    @Override
    public void componentOpened() {
        nodeResult = Utilities.actionsGlobalContext().lookupResult(Node.class);
        LookupListener nodeLkpL = (event) -> {
            final Optional<? extends Node> optionalNode = nodeResult.allInstances().stream().findFirst();
            if (optionalNode.isPresent()) {
                editorControllerResult = optionalNode.get().getLookup().lookupResult(EditorController.class);
                resultChanged(new LookupEvent(editorControllerResult));
            }
        };
        nodeResult.addLookupListener(nodeLkpL);
        nodeLkpL.resultChanged(new LookupEvent(nodeResult));
    }

Now that we are aware of changing EditorControllers - what to do with the EditorController retrieved from the lookup? We use is to create our own special panel via e.g. the LibraryController and add it to the TopComponent. If there is no EditorController anymore, only a message is shown, that there is actually no Scene Builder content availble to which this TopComponent can attach to.

    @Override
    public void resultChanged(LookupEvent le) {   
        final Optional optionalController = editorControllerResult.allInstances().stream().findFirst();
        if (optionalController.isPresent()) {
            Platform.runLater(() -> {
                LibraryPanelController h = new LibraryPanelController(optionalController.get());
                final BorderPane pane = new BorderPane();
                pane.setCenter(h.getPanelRoot());
                Scene scene = new Scene(pane);
                jfxPanel.setScene(scene);
            });
        } else {
            Platform.runLater(() -> {
                Label label = new Label ("No Scene Builder Content");
                BorderPane borderPane = new BorderPane();
                borderPane.setCenter(label);
                Scene scene = new Scene(borderPane);
                jfxPanel.setScene(scene);
            });
        }
    }

All panels we want to show can be implemented using this strategy.
All of them follow the pattern

  • create the according controller
  • call controller.getRootPanel()
  • add the pane to a layout pane
  • add the layout pane as root to the scene

I am sure the code can be improved - just let me know and create a pull request ;-)

Now you ask - can I download this magic plugin somewhere? The answer is simple: Get it from the NetBeans Plugin Portal by downloading it from here or install it via your Plugin Manager from inside NetBeans.

What you will need in addition to the plugin is a fairly recent (latest) JDK8_u20 ea build. There are some issues with DnD and JavaFX-Swing-Integration which have been fixed in latest builds.

Stay tuned for the next part of this series, showing how to get change detection and undo/redo support integrated.