在javaFX中运行swing应用程序
我有一个可以在Swing上完美工作的代码,但我想在javaFX上集成它。 我知道我必须使用SwingNode,但代码在javaFX中不起作用。 这是我使用的.jar图书馆: 这是swing的结果: 这是Swing中的代码:在javaFX中运行swing应用程序,java,swing,javafx-2,javafx-8,Java,Swing,Javafx 2,Javafx 8,我有一个可以在Swing上完美工作的代码,但我想在javaFX上集成它。 我知道我必须使用SwingNode,但代码在javaFX中不起作用。 这是我使用的.jar图书馆: 这是swing的结果: 这是Swing中的代码: import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIc
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版本(dosen't work nothing Display):
您应该能够使用并完全消除Swing将此输出呈现到JavaFX画布。我修改了一个示例程序以生成此输出(它是一个小型JavaFX应用程序): 不幸的是,将
TeXIcon
直接绘制到FXGraphics2D
实例并不能提供很好的输出(很可能是由于TextLayout呈现中的问题,我还无法跟踪问题的来源),而是先绘制到图像(就像您在示例中所做的那样)然后,将图像绘制到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 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可以使用它们):
如果您不介意将其光栅化为特定的大小,可以使用
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
实例也可以传递给标记为.setGraphic的方法,以便在某些控件(例如按钮)中使用。现在,在
.
除了github页面上提出的一些小问题外,它工作得很好。该项目似乎并不活跃,但通过重新实现LateXMathSkin
类,这些问题很容易解决。希望这能省去一些麻烦 下一个版本的JavaFX支持MathML:
- JavaFX8更新192包含在Java8更新192中
- javafx11
只需使用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>
x
=
−
B
±
B
2.
−
4.
A.
C
2.
A.
按照链接访问这些版本的早期访问。super.paintComponent
作为第一个。代码行在受保护的void paintComponent(Graphics g)`内将减少可能的绘制延迟覆盖getPreferredSize
insidepanel=new JPanel(){
请在将代码转储到我们之前清理您的代码(可疑的f.i.在不使用它的情况下创建graphics2d,将swingnode的内容设置两次…)谢谢你的建议。对于@kleopatra,我很理解第一条评论,但最后一条我不太理解。因为你接受了David的回答,我的隐含假设(与tex图书馆无关的问题)结果证明是错误的-所以我的第二条评论现在是无用的并且被删除了:-)对于所画的图片,如果方程太长,我可以在javafx Scrollpane中添加画布。这个解决方案最终是最适合我的用例的。图像似乎正确地调整了公式的大小,边缘只有很少的空白(这在大多数情况下都是完美的)。这在我的情况下也起了作用。我计划在几个应用程序中使用它,所以我将它放在一个方法中。谢谢!+1
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);
<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>