在javaFX中运行swing应用程序

我有一个在Swing上完美运行的代码,但我想将它集成到javaFX上。 我知道我必须使用SwingNode,但代码在javaFX中不起作用。 这是我用的librarie的.jar: http : //forge.scilab.org/index.php/p/jlatexmath/downloads/694/

这是摆动的结果: 在此处输入图像描述

这是Swing中的代码:

import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; public class LatexExample extends JFrame implements ActionListener { private JTextArea latexSource; private JButton btnRender; private JPanel drawingArea; public LatexExample() { this.setTitle("JLatexMath Example"); this.setSize(500, 500); Container content = this.getContentPane(); content.setLayout(new GridLayout(2, 1)); this.latexSource = new JTextArea(); JPanel editorArea = new JPanel(); editorArea.setLayout(new BorderLayout()); editorArea.add(new JScrollPane(this.latexSource),BorderLayout.CENTER); editorArea.add(btnRender = new JButton("Render"),BorderLayout.SOUTH); content.add(editorArea); content.add(this.drawingArea = new JPanel()); this.btnRender.addActionListener(this); this.latexSource.setText("x=\\frac{-b \\pm \\sqrt {b^2-4ac}}{2a}"); } public void render() { try { // get the text String latex = this.latexSource.getText(); // create a formula TeXFormula formula = new TeXFormula(latex); // render the formla to an icon of the same size as the formula. TeXIcon icon = formula .createTeXIcon(TeXConstants.STYLE_DISPLAY, 20); // insert a border icon.setInsets(new Insets(5, 5, 5, 5)); // now create an actual image of the rendered equation BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); g2.setColor(Color.white); g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight()); JLabel jl = new JLabel(); jl.setForeground(new Color(0, 0, 0)); icon.paintIcon(jl, g2, 0, 0); // at this point the image is created, you could also save it with ImageIO // now draw it to the screen Graphics g = drawingArea.getGraphics(); g.drawImage(image,0,0,null); } catch (Exception ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.INFORMATION_MESSAGE); } } public static void main(String[] args) { LatexExample frame = new LatexExample(); frame.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { if( e.getSource()==this.btnRender ) { render(); } } } 

这是JavaFX版本(不会出现任何工作):

 private void createAndSetSwingContent() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { // get the text String latex = "x=\\frac{-b \\pm \\sqrt {b^2-4ac}}{2a}"; // create a formula TeXFormula formula = new TeXFormula(latex); // render the formla to an icon of the same size as the formula. TeXIcon icon = formula .createTeXIcon(TeXConstants.STYLE_DISPLAY, 20); // insert a border icon.setInsets(new Insets(5, 5, 5, 5)); // now create an actual image of the rendered equation final BufferedImage images = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = images.createGraphics(); g2.setColor(Color.white); g2.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight()); label.setForeground(new Color(0, 0, 0)); icon.paintIcon(label, g2, 0, 0); // at this point the image is created, you could also save it with ImageIO panel = new JPanel(){ @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); super.paintComponent(g); g.drawImage(images, 0, 0, null); } }; swingNode.setContent(label); swingNode.setContent(panel); } catch (Exception ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.INFORMATION_MESSAGE); } } }); } 

您应该能够使用FXGraphics2D将此输出呈现给JavaFX Canvas并完全消除Swing。 我修改了一个示例程序来生成此输出(它是一个小型JavaFX应用程序):

JavaFX中示例程序的输出

不幸的是,将TeXIcon直接绘制到FXGraphics2D实例并不能提供良好的输出(很可能是由于TextLayout渲染中的问题,我还无法追踪其来源),而是首先绘制到图像(就像你做的那样)在你的例子中)然后将图像绘制到JavaFX Canvas似乎工作正常。

 /* ================= * FXGraphics2DDemo3 * ================= * * Copyright (c) 2014, Object Refinery Limited. * All rights reserved. * * http://www.jfree.org/fxgraphics2d/index.html * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of the Object Refinery Limited nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL OBJECT REFINERY LIMITED BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ package org.jfree.fx.demo; import static javafx.application.Application.launch; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import javax.swing.JLabel; import org.jfree.fx.FXGraphics2D; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; /** * http://stackoverflow.com/questions/25027060/running-swing-application-in-javafx */ public class FXGraphics2DDemo3 extends Application { static class MyCanvas extends Canvas { private FXGraphics2D g2; private TeXIcon icon; public MyCanvas() { this.g2 = new FXGraphics2D(getGraphicsContext2D()); // create a formula TeXFormula formula = new TeXFormula("x=\\frac{-b \\pm \\sqrt {b^2-4ac}}{2a}"); // render the formla to an icon of the same size as the formula. this.icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20); // Redraw canvas when size changes. widthProperty().addListener(evt -> draw()); heightProperty().addListener(evt -> draw()); } private void draw() { double width = getWidth(); double height = getHeight(); getGraphicsContext2D().clearRect(0, 0, width, height); // ideally it should be possible to draw directly to the FXGraphics2D // instance without creating an image first...but this does not generate // good output //this.icon.paintIcon(new JLabel(), g2, 50, 50); // now create an actual image of the rendered equation BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D gg = image.createGraphics(); gg.setColor(Color.WHITE); gg.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight()); JLabel jl = new JLabel(); jl.setForeground(new Color(0, 0, 0)); icon.paintIcon(jl, gg, 0, 0); // at this point the image is created, you could also save it with ImageIO this.g2.drawImage(image, 0, 0, null); } @Override public boolean isResizable() { return true; } @Override public double prefWidth(double height) { return getWidth(); } @Override public double prefHeight(double width) { return getHeight(); } } @Override public void start(Stage stage) throws Exception { MyCanvas canvas = new MyCanvas(); StackPane stackPane = new StackPane(); stackPane.getChildren().add(canvas); // Bind canvas size to stack pane size. canvas.widthProperty().bind( stackPane.widthProperty()); canvas.heightProperty().bind( stackPane.heightProperty()); stage.setScene(new Scene(stackPane)); stage.setTitle("FXGraphics2DDemo3.java"); stage.setWidth(700); stage.setHeight(390); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 

编辑:这是一个直接绘制方程的程序的修订版本(为了使这项工作有必要预加载JLatexMath jar文件中包含的所需字体,以便JavaFX可以使用它们):

 /* ================= * FXGraphics2DDemo3 * ================= * * Copyright (c) 2014, Object Refinery Limited. * All rights reserved. * * http://www.jfree.org/fxgraphics2d/index.html * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of the Object Refinery Limited nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL OBJECT REFINERY LIMITED BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ package org.jfree.fx.demo; import static javafx.application.Application.launch; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import org.jfree.fx.FXGraphics2D; import org.scilab.forge.jlatexmath.Box; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; /** * http://stackoverflow.com/questions/25027060/running-swing-application-in-javafx */ public class FXGraphics2DDemo3 extends Application { static class MyCanvas extends Canvas { private FXGraphics2D g2; private Box box; public MyCanvas() { this.g2 = new FXGraphics2D(getGraphicsContext2D()); this.g2.scale(20, 20); // create a formula TeXFormula formula = new TeXFormula("x=\\frac{-b \\pm \\sqrt {b^2-4ac}}{2a}"); TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 20); // the 'Box' seems to be the thing we can draw directly to Graphics2D this.box = icon.getBox(); // Redraw canvas when size changes. widthProperty().addListener(evt -> draw()); heightProperty().addListener(evt -> draw()); } private void draw() { double width = getWidth(); double height = getHeight(); getGraphicsContext2D().clearRect(0, 0, width, height); this.box.draw(g2, 1, 5); } @Override public boolean isResizable() { return true; } @Override public double prefWidth(double height) { return getWidth(); } @Override public double prefHeight(double width) { return getHeight(); } } @Override public void start(Stage stage) throws Exception { javafx.scene.text.Font.loadFont(FXGraphics2DDemo3.class.getResourceAsStream("/org/scilab/forge/jlatexmath/fonts/base/jlm_cmmi10.ttf"), 1); javafx.scene.text.Font.loadFont(FXGraphics2DDemo3.class.getResourceAsStream("/org/scilab/forge/jlatexmath/fonts/maths/jlm_cmsy10.ttf"), 1); javafx.scene.text.Font.loadFont(FXGraphics2DDemo3.class.getResourceAsStream("/org/scilab/forge/jlatexmath/fonts/latin/jlm_cmr10.ttf"), 1); MyCanvas canvas = new MyCanvas(); StackPane stackPane = new StackPane(); stackPane.getChildren().add(canvas); // Bind canvas size to stack pane size. canvas.widthProperty().bind( stackPane.widthProperty()); canvas.heightProperty().bind( stackPane.heightProperty()); stage.setScene(new Scene(stackPane)); stage.setTitle("FXGraphics2DDemo3.java"); stage.setWidth(700); stage.setHeight(390); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 

如果你不介意它以特定的大小进行栅格化,你可以在javafx.embed.swing使用SwingFXUtils.toFXImage静态方法:

  TeXFormula tex = new TeXFormula("a + b \\cdot x"); java.awt.Image awtImage = tex.createBufferedImage(TeXConstants.STYLE_TEXT, 12, java.awt.Color.BLACK, null); Image fxImage = SwingFXUtils.toFXImage((BufferedImage) awtImage, null); ImageView view = new ImageView(fxImage); 

fxImage实例也可以传递给Labeled.setGraphic方法,以便在某些控件(例如按钮)中使用。

现在有一个jlatexmath到javafx的端口,在https://github.com/bitstormGER/jlatexmathfx 。 除了github页面上提出的一些小问题外,它运行良好。 该项目似乎不活跃,但通过重新实现LateXMathSkin类可以轻松解决问题。 希望这会省去一些麻烦。

JavaFX的下一个版本支持MathML:

  • Java 8 Update 192中包含JavaFX 8 Update 192
  • JavaFX 11。

只需使用WebView控件和MathML并使用以下命令设置HTML内容:

   x =    b  ±    b 2   4 a c     2 a     

点击链接Java Early Access Download即可获得对这些版本的早期访问权限。