我有一个在Swing上完美运行的代码,但我想将它集成到javaFX上。 我知道我必须使用SwingNode,但代码在javaFX中不起作用。 这是我使用的图书馆的.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);
}
}
});
}
答案 0 :(得分:6)
您应该能够使用FXGraphics2D将此输出渲染到JavaFX Canvas并完全消除Swing。我修改了一个示例程序来生成此输出(它是一个小型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);
}
}
答案 1 :(得分:5)
如果您不介意以特定大小进行栅格化,则可以使用SwingFXUtils.toFXImage
中的javafx.embed.swing
静态方法:
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
方法,以便在某些控件(例如按钮)中使用。
答案 2 :(得分:1)
现在有一个jlatexmath到javafx的端口,at
https://github.com/bitstormGER/jlatexmathfx。
除了github页面上提出的一些小问题外,它运行良好。该项目看起来并不活跃,但通过重新实施LateXMathSkin
类可以轻松解决问题。希望这会省去一些麻烦。
答案 3 :(得分:0)
JavaFX的下一个版本将支持MathML:
只需使用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,以尽早访问这些版本。