简体   繁体   English

在javaFX中运行swing应用程序

[英]Running swing application in javaFX

I have a code that work perfectly on Swing but I want to integrate it on javaFX. 我有一个在Swing上完美运行的代码,但我想将它集成在javaFX上。 I know that I must use SwingNode but the code dosen't work in javaFX. 我知道我必须使用SwingNode,但代码在javaFX中不起作用。 this is .jar of librarie I use : http://forge.scilab.org/index.php/p/jlatexmath/downloads/694/ 这是我用的librarie的.jar: http//forge.scilab.org/index.php/p/jlatexmath/downloads/694/

this is the result in swing : 这是摆动的结果: 在此输入图像描述

this is the code in Swing : 这是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();
        }

    }
}

and this is JavaFX version (dosen't work nothing appear) : 这是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);
                }
            }

        });
    }

You ought to be able to render this output to a JavaFX Canvas using FXGraphics2D and eliminate Swing completely. 您应该能够使用FXGraphics2D将此输出呈现为JavaFX Canvas并完全消除Swing。 I modified one of the sample programs to produce this output (it is a small JavaFX app): 我修改了一个示例程序来生成此输出(它是一个小型JavaFX应用程序):

JavaFX中示例程序的输出

Unfortunately drawing the TeXIcon directly to the FXGraphics2D instance doesn't give nice output (most likely due to issues in the TextLayout rendering that I haven't been able to trace the source of yet), but drawing to an image first (as you did in your example) then drawing the image to the JavaFX Canvas seems to work fine. 不幸的是,将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);
    }

}

EDIT: here is a revised version of the program that draws the equation directly (to make this work it is necessary to preload the required fonts that are included in the JLatexMath jar file so that JavaFX can use them): 编辑:这是程序的修订版本,直接绘制方程式(为了使这项工作有必要预加载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);
    }

}

If you don't mind it being rasterized at a specifc size, you could use the SwingFXUtils.toFXImage static method in javafx.embed.swing : 如果您不介意以特定大小进行栅格化,则可以在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);

The fxImage instance could also be passed to the Labeled.setGraphic method for use in certain controls (eg buttons). fxImage实例也可以传递给Labeled.setGraphic方法,以便在某些控件(例如按钮)中使用。

There's now a port of jlatexmath to javafx, at https://github.com/bitstormGER/jlatexmathfx . 现在有一个jlatexmath到javafx的端口,在https://github.com/bitstormGER/jlatexmathfx It works well, except for a few minor issues, raised on the github page. 除了github页面上提出的一些小问题外,它运行良好。 The project doesn't seem active, but the issues are easy to solve by re-implementing the LateXMathSkin class. 该项目似乎不活跃,但通过重新实现LateXMathSkin类可以轻松解决问题。 Hope this would save some trouble. 希望这会省去一些麻烦。

The next coming versions of JavaFX support MathML : JavaFX的下一个版本支持MathML:

  • JavaFX 8 Update 192 included in Java 8 Update 192 Java 8 Update 192中包含JavaFX 8 Update 192
  • JavaFX 11. JavaFX 11。

Just use a WebView control and MathML and set HTML Content with : 只需使用WebView控件和MathML并使用以下内容设置HTML内容:

<math display="block"> 
   <mrow> 
      <mi>x</mi> 
      <mo>=</mo> 
      <mfrac> 
         <mrow> 
            <mo>−</mo> 
            <mi>b </mi> 
            <mo>±</mo> 
            <msqrt> 
               <mrow> 
                  <msup> 
                     <mi>b</mi> 
                     <mn>2</mn> 
                  </msup> 
                  <mo>−</mo> 
                  <mn>4</mn> 
                  <mi>a</mi> 
                  <mi>c</mi> 
               </mrow> 
            </msqrt> 
         </mrow> 
         <mrow> 
            <mn>2</mn> 
            <mi>a</mi> 
         </mrow> 
      </mfrac> 
   </mrow>
</math>

Follow the link Java Early Access Download to reach the early access to these versions. 点击链接Java Early Access Download即可获得对这些版本的早期访问权限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM