繁体   English   中英

在javaFX中运行swing应用程序

[英]Running swing application in javaFX

我有一个在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内容:

<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>

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

暂无
暂无

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

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