将 mxgraph 集成到 JavaFX 的 fxml 文件中
Integrating mxgraph inside JavaFX's fxml file
我需要制作一个在 JavaFX FXML 文件上生成图形的桌面应用程序。我在 eclipse 中使用 mxGraph 库来构建图形,并使用 Scene Builder 来编辑 FXML 文件,但我无法使图形显示在 FXML 文件中,它仅在我使用 JFrame 时有效。
当我 运行 这样的时候:
public class mxgraphteste extends JFrame{
public mxgraphteste(){
mxGraph grafo = new mxGraph();
Object parent = grafo.getDefaultParent();
Object v1 = grafo.insertVertex(parent, null, "Brazil", 100, 100, 50, 40);
Object v2 = grafo.insertVertex(parent, null, "Soccer", 240, 150, 50, 40);
Object a1 = grafo.insertEdge(parent, null, "loves", v1, v2);
mxGraphComponent graphComponent = new mxGraphComponent(grafo);
getContentPane().add(graphComponent);
}
public static void main(String[] args) {
mxgraphteste frame = new mxgraphteste();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 320);
frame.setVisible(true);
}
}
有效。
但我需要将图表放入其中:
<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.TelaPrincipalController">
<children>
<BorderPane fx:id="borderPane" layoutX="446.0" layoutY="141.0" prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<right>
<Pane fx:id="paineDireita" prefHeight="491.0" prefWidth="126.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="buttonNo" layoutX="37.0" layoutY="179.0" mnemonicParsing="false" onAction="#selecionarNo" text="Nó" />
<Button fx:id="buttonAresta" layoutX="28.0" layoutY="259.0" mnemonicParsing="false" text="Aresta" />
</children>
</Pane>
</right>
<center>
<Pane fx:id="paineCentro" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" /> **~~~~~~~~~~~~~~~~ I NEED IT GO INSIDE THIS PANE ~~~~~~~~~~~~**
</center>
</BorderPane>
</children>
</AnchorPane>
我已经在使用jdk8了。我试着跟随 Oracle's tutorial for Swing Content in JavaFX Applications 但我无法将图形转换为 SwingNode。我为使用 JavaFX 的 Swing 应用程序找到了使用 JFXPanel 的解决方案,但它并没有起到相反的作用。
有谁知道我做错了什么或者我该如何解决这个问题?
谢谢!
我不知道 mxGraph
,所以我假设您的代码对于那部分是正确的。
要将 swing 组件嵌入到 JavaFX 中,您需要将其包装在 SwingNode
中。正如评论中所指出的,您需要在 AWT 事件分派线程上创建 swing 内容。由于 FXMLLoader
在 FX 应用程序线程上运行,您不能直接在 FXML 文件中创建 mxGraph
,并且必须在控制器 class.[=18 中进行部分初始化=]
因此您可以在 FXML 中执行以下操作:
<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.TelaPrincipalController">
<children>
<BorderPane fx:id="borderPane" layoutX="446.0" layoutY="141.0" prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<right>
<Pane fx:id="paineDireita" prefHeight="491.0" prefWidth="126.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="buttonNo" layoutX="37.0" layoutY="179.0" mnemonicParsing="false" onAction="#selecionarNo" text="Nó" />
<Button fx:id="buttonAresta" layoutX="28.0" layoutY="259.0" mnemonicParsing="false" text="Aresta" />
</children>
</Pane>
</right>
<center>
<Pane fx:id="paineCentro" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" >
<SwingNode fx:id="swingComponentWrapper"/>
</Pane>
</center>
</BorderPane>
</children>
</AnchorPane>
现在在你的控制器中你可以做:
public class TelaPrincipalController {
@FXML
private SwingNode swingComponentWrapper ;
public void initialize() {
SwingUtilities.invokeLater(this::createMxGraph);
}
private void createMxGraph() {
mxGraph grafo = new mxGraph();
Object parent = grafo.getDefaultParent();
Object v1 = grafo.insertVertex(parent, null, "Brazil", 100, 100, 50, 40);
Object v2 = grafo.insertVertex(parent, null, "Soccer", 240, 150, 50, 40);
Object a1 = grafo.insertEdge(parent, null, "loves", v1, v2);
mxGraphComponent graphComponent = new mxGraphComponent(grafo);
swingComponentWrapper.setContent(graphComponent);
}
@FXML
private void selecionarNo() {
// ...
}
// etc etc...
}
请注意,SwingNode
仅适用于 轻量级 组件(即由 Swing 管理的组件);如果 mxGraph 使用重量级组件,这可能不起作用。
我需要制作一个在 JavaFX FXML 文件上生成图形的桌面应用程序。我在 eclipse 中使用 mxGraph 库来构建图形,并使用 Scene Builder 来编辑 FXML 文件,但我无法使图形显示在 FXML 文件中,它仅在我使用 JFrame 时有效。 当我 运行 这样的时候:
public class mxgraphteste extends JFrame{
public mxgraphteste(){
mxGraph grafo = new mxGraph();
Object parent = grafo.getDefaultParent();
Object v1 = grafo.insertVertex(parent, null, "Brazil", 100, 100, 50, 40);
Object v2 = grafo.insertVertex(parent, null, "Soccer", 240, 150, 50, 40);
Object a1 = grafo.insertEdge(parent, null, "loves", v1, v2);
mxGraphComponent graphComponent = new mxGraphComponent(grafo);
getContentPane().add(graphComponent);
}
public static void main(String[] args) {
mxgraphteste frame = new mxgraphteste();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 320);
frame.setVisible(true);
}
}
有效。 但我需要将图表放入其中:
<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.TelaPrincipalController">
<children>
<BorderPane fx:id="borderPane" layoutX="446.0" layoutY="141.0" prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<right>
<Pane fx:id="paineDireita" prefHeight="491.0" prefWidth="126.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="buttonNo" layoutX="37.0" layoutY="179.0" mnemonicParsing="false" onAction="#selecionarNo" text="Nó" />
<Button fx:id="buttonAresta" layoutX="28.0" layoutY="259.0" mnemonicParsing="false" text="Aresta" />
</children>
</Pane>
</right>
<center>
<Pane fx:id="paineCentro" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" /> **~~~~~~~~~~~~~~~~ I NEED IT GO INSIDE THIS PANE ~~~~~~~~~~~~**
</center>
</BorderPane>
</children>
</AnchorPane>
我已经在使用jdk8了。我试着跟随 Oracle's tutorial for Swing Content in JavaFX Applications 但我无法将图形转换为 SwingNode。我为使用 JavaFX 的 Swing 应用程序找到了使用 JFXPanel 的解决方案,但它并没有起到相反的作用。 有谁知道我做错了什么或者我该如何解决这个问题? 谢谢!
我不知道 mxGraph
,所以我假设您的代码对于那部分是正确的。
要将 swing 组件嵌入到 JavaFX 中,您需要将其包装在 SwingNode
中。正如评论中所指出的,您需要在 AWT 事件分派线程上创建 swing 内容。由于 FXMLLoader
在 FX 应用程序线程上运行,您不能直接在 FXML 文件中创建 mxGraph
,并且必须在控制器 class.[=18 中进行部分初始化=]
因此您可以在 FXML 中执行以下操作:
<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.TelaPrincipalController">
<children>
<BorderPane fx:id="borderPane" layoutX="446.0" layoutY="141.0" prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<right>
<Pane fx:id="paineDireita" prefHeight="491.0" prefWidth="126.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="buttonNo" layoutX="37.0" layoutY="179.0" mnemonicParsing="false" onAction="#selecionarNo" text="Nó" />
<Button fx:id="buttonAresta" layoutX="28.0" layoutY="259.0" mnemonicParsing="false" text="Aresta" />
</children>
</Pane>
</right>
<center>
<Pane fx:id="paineCentro" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" >
<SwingNode fx:id="swingComponentWrapper"/>
</Pane>
</center>
</BorderPane>
</children>
</AnchorPane>
现在在你的控制器中你可以做:
public class TelaPrincipalController {
@FXML
private SwingNode swingComponentWrapper ;
public void initialize() {
SwingUtilities.invokeLater(this::createMxGraph);
}
private void createMxGraph() {
mxGraph grafo = new mxGraph();
Object parent = grafo.getDefaultParent();
Object v1 = grafo.insertVertex(parent, null, "Brazil", 100, 100, 50, 40);
Object v2 = grafo.insertVertex(parent, null, "Soccer", 240, 150, 50, 40);
Object a1 = grafo.insertEdge(parent, null, "loves", v1, v2);
mxGraphComponent graphComponent = new mxGraphComponent(grafo);
swingComponentWrapper.setContent(graphComponent);
}
@FXML
private void selecionarNo() {
// ...
}
// etc etc...
}
请注意,SwingNode
仅适用于 轻量级 组件(即由 Swing 管理的组件);如果 mxGraph 使用重量级组件,这可能不起作用。