DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Java
  4. How to Integrate JavaFX into a NetBeans Platform Explorer View

How to Integrate JavaFX into a NetBeans Platform Explorer View

Geertjan Wielenga user avatar by
Geertjan Wielenga
·
Apr. 28, 13 · Interview
Like (0)
Save
Tweet
Share
6.37K Views

Join the DZone community and get the full member experience.

Join For Free

In the NetBeans Platform, "explorer view" has a very specific meaning. It is described in some detail here. In summary, an explorer view displays one or more Nodes. (And a Node is a visualization of an Object.) Since all explorer views work with Nodes, changing from one view to another doesn't require the model (i.e., the Node) to be rewritten, unlike in standard Swing where each UI component has its own model. The most popular explorer views are BeanTreeView and OutlineView.

Toni and I worked on creating a custom explorer view based on the Visual Library, all the way back in 2009, as described here. Using those insights, I created a custom explorer view on top of a JavaFX TreeView, as shown here:

Here's how, mostly using code from the TreeView link above. You can copy the class below and paste it into a module and then use it exactly as you use a BeanTreeView. Wherever you're adding "new BeanTreeView()" to a TopComponent, you can now add "new JFXTreeView()". However, two arguments need to be passed in: the ExplorerManager and a String for the display text of the root node.

In the code below, the call "ExplorerManager.find(this)" is very important. What happens here is that the component (which in this case is the JFXPanel) asks its parent (which is in this case the TopComponent where I added it) if it implements ExplorerManager.Provider. If so, the root Node of the ExplorerManager is obtained, from where the child Nodes are obtained, from which the Lookup can be used, etc. So, via the ExplorerManager all the data is available to the JavaFX TreeView.

public class JFXTreeView extends JFXPanel {

    ExplorerManager em;
    private String rootDisplayName;

    public JFXTreeView(ExplorerManager em, String rootDisplayName) {
        this.em = em;
        this.rootDisplayName = rootDisplayName;
    }

    @Override
    public void addNotify() {
        super.addNotify();
        em = ExplorerManager.find(this);
        if (em != null) {
            Node root = em.getRootContext();
            TreeItem<String> rootItem = new TreeItem<String>(rootDisplayName);
            rootItem.setExpanded(true);
            for (Node node : root.getChildren().getNodes()) {
                TreeItem<String> item = new TreeItem<String>(
                   node.getDisplayName());
                rootItem.getChildren().add(item);
            }
            final TreeView<String> treeView = new TreeView<String>(rootItem);
            treeView.setEditable(true);
            treeView.setCellFactory(
                  new Callback<TreeView<String>, 
                  TreeCell<String>>() {
                @Override
                public TreeCell<String> call(TreeView<String> p) {
                    return new TextFieldTreeCellImpl();
                }
            });
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    StackPane root = new StackPane();
                    root.getChildren().add(treeView);
                    Scene scene = new Scene(root, 300, 250);
                    setScene(scene);
                }
            });
        }
    }

    private final class TextFieldTreeCellImpl extends TreeCell<String> {
        private TextField textField;
        @Override
        public void startEdit() {
            super.startEdit();
            if (textField == null) {
                createTextField();
            }
            for (Node node : em.getRootContext().getChildren().getNodes()) {
                if (node.getLookup().lookup(Person.class).getName().
                    equals(textField.getText())) {
                    try {
                        em.setSelectedNodes(new Node[]{node});
                    } catch (PropertyVetoException ex) {
                        Exceptions.printStackTrace(ex);
                    }
                }
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }
        @Override
        public void cancelEdit() {
            super.cancelEdit();
            setText((String) getItem());
            setGraphic(getTreeItem().getGraphic());
        }
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(getString());
                    setGraphic(getTreeItem().getGraphic());
                }
            }
        }
        private void createTextField() {
            textField = new TextField(getString());
            textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
                @Override
                public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(textField.getText());
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }

}

Note: Take note of the "startEdit" method, where the selected node in the ExplorerManager is changed when the double-click on an item in the tree takes place. In that way, the selected Node always matches an item in the JavaFX TreeView, so that other parts of the application, such as the Properties Window and Actions, are updated automatically whenever the user clicks a different item. That's the way the JavaFX world can interact with the NetBeans Platform world, via the ExplorerManager, which is the controler of the Node hierarchy.

Finally, the next topic I'm working on, but that could take more time, is the window system, that is, replacing the Swing tabbed pane with a JavaFX equivalent.

JavaFX NetBeans

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Solving the Kubernetes Security Puzzle
  • HTTP vs Messaging for Microservices Communications
  • Custom Validators in Quarkus
  • Monolithic First

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: