我想在 javafx StackPane 面板中显示 graphstream 图表。我知道网络和本页中有一些类似的问题,但我得到了不同的输出和错误。
我的代码位于以下函数中:
void cargaGrafico() {
SingleGraph graph = aula.getSociogramas().get(currentSocio).getRelaPos().getGraph();
FxViewer v = new FxViewer(graph,FxViewer.ThreadingModel.GRAPH_IN_GUI_THREAD);
v.enableAutoLayout();
FxViewPanel panel = (FxViewPanel)v.addDefaultView(false, new FxGraphRenderer());
spGraficos.getChildren().add(panel);
}
其中 spGraficos 是 javafx StackPane。 当我运行代码时,我在面板中得到一个非常小的图形,不是交互式的,并且该图形似乎在不同的线程中运行,因为我收到以下异常:
Exception in thread "Thread-2" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-2
at javafx.graphics@22-ea/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:294)
at javafx.graphics@22-ea/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:475)
at javafx.graphics@22-ea/javafx.animation.Animation.play(Animation.java:990)
at [email protected]/org.graphstream.ui.fx_viewer.FxViewer.lambda$init$1(FxViewer.java:220)
at java.base/java.lang.Thread.run(Thread.java:1570)e here
我也在寻找 graphstream 邮件列表,但它似乎不再存在了。 预先感谢
我不知道图流,但你有
ThreadingModel.GRAPH_IN_GUI_THREAD
。堆栈跟踪显示您不在 GUI 线程上。要在 GUI 线程上运行代码,请使用 Platform.runLater
。如果您仍然遇到问题,请提供一个最小的可重现示例。
我尝试使用 GraphStream JavaFX 示例教程应用程序,它对我来说效果很好(JavaFX 22.0.2、Java 21、OS X - Intel 14.5)。 我使用了示例代码中的默认线程模型
FxViewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD
。
我尝试根据 https://github.com/graphstream/gs-ui-javafx/tree/master 上的说明创建一个项目,它对我来说效果很好。
使用的图标来自这里:
图表代码来自此处并进行修改:
修改很小,与图标的资源加载有关,以便它可以在模块化环境中工作,进行清理以使用 lamdas,删除未使用的代码并设置记录的系统属性以通过 JavaFX 路由图形流。
请参阅原始链接以获取版权信息。
示例代码输出4张图,我这里只展示一张。
package org.example.graphstream;
import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.MultiGraph;
import org.graphstream.ui.fx_viewer.FxDefaultView;
import org.graphstream.ui.fx_viewer.FxViewer;
import org.graphstream.ui.view.Viewer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.stage.Stage;
import java.util.Objects;
public class TutorialDiagrams extends Application {
public static final String URL_IMAGE = Objects.requireNonNull(TutorialDiagrams.class.getResource("/org/graphstream/ui/viewer_fx/test/data/icon.png")).toString();
public static void main(String[] args) {
System.setProperty("org.graphstream.ui", "javafx");
launch(args);
}
public void start(Stage primaryStage) {
Scene scene1 = diagram1("diagram1", styleSheet1);
Scene scene2 = diagram1b("diagram1b", styleSheet1);
Scene scene3 = diagram2("diagram2", styleSheet1);
Scene scene4 = diagram3("diagram3", styleSheet2);
primaryStage.setScene(scene1);
primaryStage.setOnCloseRequest(t -> Platform.exit());
primaryStage.show();
Stage stage2 = new Stage();
stage2.setX(primaryStage.getX() + primaryStage.getWidth());
stage2.setY(primaryStage.getY());
stage2.setScene(scene2);
stage2.setOnCloseRequest(t -> Platform.exit());
stage2.show();
Stage stage3 = new Stage();
stage3.setX(primaryStage.getX());
stage3.setY(primaryStage.getY() + primaryStage.getY());
stage3.setScene(scene3);
stage3.setOnCloseRequest(t -> Platform.exit());
stage3.show();
Stage stage4 = new Stage();
stage4.setX(primaryStage.getX() + primaryStage.getWidth());
stage4.setY(primaryStage.getY() + primaryStage.getY());
stage4.setScene(scene4);
stage4.setOnCloseRequest(t -> Platform.exit());
stage4.show();
}
public Scene diagram(Graph graph, String style, String title, int width, int height) {
graph.setAttribute("ui.quality");
graph.setAttribute("ui.antialias");
graph.setAttribute("ui.stylesheet", style);
graph.setAttribute("ui.screenshot", title+".png");
Viewer viewer = new FxViewer( graph, FxViewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD );
FxDefaultView view = (FxDefaultView) viewer.addDefaultView(true);
view.resize(width, height);
return new Scene(view, width, height, true, SceneAntialiasing.DISABLED);
}
public Scene diagram1(String title, String styleSheet) {
MultiGraph graph = new MultiGraph(title);
Scene s = diagram(graph, styleSheet, title, 500, 250);
Node G = graph.addNode("Graph");
Node V = graph.addNode("Viewer");
Edge E = graph.addEdge("G->V", "Graph", "Viewer", true);
G.setAttribute("xyz", new double[] {0, 0, 0});
V.setAttribute("xyz", new double[] {1, 0, 0});
G.setAttribute("ui.label", "Graph");
V.setAttribute("ui.label", "Viewer");
return s ;
}
public Scene diagram1b(String title, String styleSheet) {
MultiGraph graph = new MultiGraph(title);
Scene s = diagram(graph, styleSheet, title, 500, 370);
Node G = graph.addNode("Graph");
Node V = graph.addNode("Viewer");
Node B1 = graph.addNode("bidon1");
Node B2 = graph.addNode("bidon2");
graph.addEdge("G->bidon1", "Graph", "bidon1", true);
graph.addEdge("bidon1->V", "bidon1", "Viewer", true);
graph.addEdge("V->bidon2", "Viewer", "bidon2", true);
graph.addEdge("bidon2->G", "bidon2", "Graph", true);
G.setAttribute("xyz", new double[]{0, 0, 0});
B1.setAttribute("xyz", new double[]{0, 0.5, 0});
V.setAttribute("xyz", new double[]{1, 0.5, 0});
B2.setAttribute("xyz", new double[]{1, 0, 0});
G.setAttribute("ui.label", "Graph");
V.setAttribute("ui.label", "Viewer");
B1.setAttribute("ui.class", "invisible");
B2.setAttribute("ui.class", "invisible");
return s;
}
public Scene diagram2(String title, String styleSheet) {
MultiGraph graph = new MultiGraph(title);
Scene s = diagram(graph, styleSheet, title, 500, 250);
Node G = graph.addNode("Graph");
Node P = graph.addNode("Pipe");
Node V = graph.addNode("Viewer");
graph.addEdge("G->P", "Graph", "Pipe", true);
graph.addEdge("P->V", "Pipe", "Viewer", true);
G.setAttribute("xyz", new double[] {0, 0, 0});
P.setAttribute("xyz", new double[] {1, 0, 0});
V.setAttribute("xyz", new double[] {2, 0, 0});
G.setAttribute("ui.label", "Graph");
P.setAttribute("ui.label", "Pipe");
V.setAttribute("ui.label", "Viewer");
return s;
}
public Scene diagram3(String title, String styleSheet) {
MultiGraph graph = new MultiGraph(title);
Scene s = diagram(graph, styleSheet, title, 800, 500);
Node G = graph.addNode("Graph");
Node V = graph.addNode("Viewer");
Node P1 = graph.addNode("GtoV");
Node P2 = graph.addNode("VtoG");
graph.addEdge("G->GtoV", "Graph", "GtoV", true);
graph.addEdge("GtoV->V", "GtoV", "Viewer", true);
graph.addEdge("VtoG<-V", "Viewer", "VtoG", true);
graph.addEdge("G<-VtoG", "VtoG", "Graph", true);
G.setAttribute("ui.label", "Graph");
P1.setAttribute("ui.label", "Pipe");
P2.setAttribute("ui.label", "ViewerPipe");
V.setAttribute("ui.label", "Viewer");
G.setAttribute("xyz", new double[] {-2, 0, 0});
P1.setAttribute("xyz", new double[] {-1, 1.4, 0});
P2.setAttribute("xyz", new double[] { 1, -1.4, 0});
V.setAttribute("xyz", new double[] { 2, 0, 0});
return s;
}
public String styleSheet1 =
"graph {"+
" padding: 90px;"+
"}"+
"node {"+
" size: 128px;"+
" shape: box;"+
" fill-mode: image-scaled;"+
" fill-image: url('"+URL_IMAGE+"');"+
" text-alignment: under;"+
" text-color: #DDD;"+
" text-background-mode: rounded-box;"+
" text-background-color: #333;"+
" text-padding: 4px;"+
"}"+
"node#Pipe {"+
" fill-image: url('"+URL_IMAGE+"');"+
"}"+
"node#Viewer {"+
" fill-image: url('"+URL_IMAGE+"');"+
"}"+
"node.invisible {"+
" fill-mode: plain;"+
" fill-color: #0000;"+
"}"+
"edge {"+
" size: 4px;"+
" fill-color: #979797;"+
" arrow-shape: none;"+
"}";
public String styleSheet2 =
"graph {"+
" padding: 90px;"+
"}"+
"node {"+
" size: 128px;"+
" shape: box;"+
" fill-mode: image-scaled;"+
" fill-image: url('"+URL_IMAGE+"');"+
" text-alignment: under;"+
" text-color: #DDD;"+
" text-background-mode: rounded-box;"+
" text-background-color: #333;"+
" text-padding: 4px;"+
"}"+
"node#Graph {"+
" fill-image: url('"+URL_IMAGE+"');"+
"}"+
"node#Viewer {"+
" fill-image: url('"+URL_IMAGE+"');"+
"}"+
"node#VtoG {"+
" fill-image: url('"+URL_IMAGE+"');"+
"}"+
"edge {"+
" size: 4px;"+
" fill-color: #979797;"+
" shape: L-square-line;"+
" arrow-size: 25px, 10px;"+
" arrow-shape: none;"+
"}";
}
模块信息.java
module org.example.graphstream {
requires javafx.controls;
requires javafx.swing;
requires gs.core;
requires gs.ui.javafx;
exports org.example.graphstream;
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>graph-stream</artifactId>
<version>1.0-SNAPSHOT</version>
<name>graph-stream</name>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>22.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>22.0.2</version>
</dependency>
<dependency>
<groupId>org.graphstream</groupId>
<artifactId>gs-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.graphstream</groupId>
<artifactId>gs-ui-javafx</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
</project>