在 Javafx 中使用 Netbeans 可视化库

Using Netbeans Visual Library in Javafx

我正在尝试在 Javafx 中使用 Net beans Visual Library,我在这里引用示例 https://platform.netbeans.org/graph/examples.html

我特别使用javaone.demo4 包中的DemoGraphscene.java。当我在我的 javafx 项目中使用示例时,我不确定如何显示图形。

这是我在我的控制器中写的 class:

public class GraphicalViewController implements Initializable {

    /**
     * Initializes the controller class.
     */

    @FXML
    private Pane pane1;

    @FXML
    private Label label;

    @Override
    public void initialize(URL url, ResourceBundle rb) {

         // TODO

       GraphScene scene = new DemoGraphScene ();

        String helloNodeID = "Hello";
        String worldNodeID = "World";
        String edge = "edge";

        Widget hello = scene.addNode (helloNodeID);
        Widget world = scene.addNode (worldNodeID);

        scene.addEdge (edge);

        scene.setEdgeSource(edge, helloNodeID);
        scene.setEdgeTarget(edge, worldNodeID);

        hello.setPreferredLocation (new Point (100, 100));
        world.setPreferredLocation (new Point (400, 200));

        pane1.getChildren().add(scene.getView());      

    }    

}

所以我在 pane1.getChildren().add(scene.getView());

行中有(参数不匹配;JComponent 无法转换为 Node)

我是怎么遇到这个问题的?

我这样做了:

SwingNode swingScene = new SwingNode(); 
SwingNode swingScene1 = new SwingNode(); 
swingScene.setContent(new JButton("Click me!")); 
swingScene1.setContent(scene.getView()); 
pane1.getChildren().add(swingScene1); 

当我执行 pane1.getChildren().add(swingScene1) 时,我没有看到任何显示,但 pane1.getChildren().add(swingScene) 确实显示了按钮。

使用 SwingNode

NetBeans 可视化库是基于 Swing 的。如果要在JavaFX中使用,需要wrap the Swing component in a JavaFX node.

@FXML Pane pane1;
. . .
GraphScene scene = new DemoGraphScene();
. . .
SwingNode swingScene = new SwingNode();
swingScene.setContent(scene.getView());
. . .
pane1.getChildren().add(swingScene); 

混乱笔记

特别迷惑,因为visual library works with a scene,JavaFX library 也works scene,但它们是不同库的不同场景,所以需要将Visual Library scene view包裹在一个JavaFX节点中为了在 JavaFX 场景中显示它。

此外,在混合使用 Swing 和 JavaFX 代码时,请确保在 Swing 事件调度线程上执行 Swing 代码,在 JavaFX 应用程序线程上执行 JavaFX 代码 - 否则可能会出现严重错误。

我不太喜欢混合使用 Swing 和 JavaFX,通常我建议如果您想使用 Swing,则编写一个 100% 的 Swing 应用程序,如果您想使用 JavaFX,则编写一个 100% 的 JavaFX 应用程序.

可执行样本

这是一个可执行示例。该示例依赖于源代码:https://platform.netbeans.org/graph/examples.html。要使用它,请从 link 下载示例项目,将下面的示例代码粘贴到 NetBeans 项目并右键单击 运行 它。

import java.awt.Dimension;
import java.awt.Point;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.widget.Widget;

public class FXGraphDemo extends Application {

    @Override
    public void start(final Stage stage) {
        final SwingNode swingNode = new SwingNode();
        createAndSetSwingContent(swingNode);

        Scene scene = new Scene(new Group(swingNode), 400, 300);

        stage.setScene(scene);
        stage.show();
    }

    private void createAndSetSwingContent(final SwingNode swingNode) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final GraphScene graphScene = new DemoGraphScene();

                String helloNodeID = "Hello";
                String worldNodeID = "World";
                String edge = "edge";

                Widget hello = graphScene.addNode (helloNodeID);
                Widget world = graphScene.addNode (worldNodeID);

                graphScene.addEdge (edge);

                graphScene.setEdgeSource(edge, helloNodeID);
                graphScene.setEdgeTarget(edge, worldNodeID);

                hello.setPreferredLocation (new Point (100, 100));
                world.setPreferredLocation (new Point (300, 200));

                final JComponent sceneView = graphScene.createView();

                final JScrollPane panel = new JScrollPane (sceneView);
                panel.getHorizontalScrollBar().setUnitIncrement (32);
                panel.getHorizontalScrollBar().setBlockIncrement (256);
                panel.getVerticalScrollBar().setUnitIncrement (32);
                panel.getVerticalScrollBar().setBlockIncrement (256); 

                panel.setPreferredSize(new Dimension (400, 300));

                swingNode.setContent(panel);
            }
        });
    }    

    public static void main(String[] args) {
        launch(args);
    }
}

警告

样本(通常但不总是)在最初绘制时有问题,它会闪烁黑色一秒钟并在尝试计算矩形时记录 NullPointerExcepton(出于我不知道的原因 - 看起来有点像某处的竞争条件)。不过在那之后,它似乎可以正常显示和工作。要绕过黑色闪光和 NullPointerException,您可以在 JFrame 而不是 SwingNode 中显示图形,但它会在其自己的单独 window 中显示,而不是嵌入到 JavaFX 场景中。

NetBeans 可视化库 JavaFX 端口 https://github.com/theanuradha/visual-library-fx/releases

https://github.com/theanuradha/visual-library-fx/tree/master/org-netbeans-api-visualfx/src/test/java/javaone/demo4

DemoGraphScene scene = new DemoGraphScene();

    String helloNodeID = "Hello";
    String worldNodeID = "World";
    String edge = "edge";

    Widget hello = scene.addNode(helloNodeID);
    Widget world = scene.addNode(worldNodeID);

    scene.addEdge(edge);

    scene.setEdgeSource(edge, helloNodeID);
    scene.setEdgeTarget(edge, worldNodeID);

    hello.setPreferredLocation(new Point(0, 0));
    world.setPreferredLocation(new Point(400, 200));

    final SceneNode sceneView =  scene.createView();