如何为JavaFX SceneBuilder添加LaTeX自定义组件?
Hey there! Since you're just starting out with JavaFX and SceneBuilder, let's walk through turning that LaTeX-drawing code into a reusable component you can easily drag-and-drop in SceneBuilder. I'll keep this straightforward for beginners:
First, make sure you have the required libraries in your project. If you're using Maven, add these to your pom.xml:
<dependencies> <dependency> <groupId>org.scilab.forge</groupId> <artifactId>jlatexmath</artifactId> <version>1.0.7</version> </dependency> <dependency> <groupId>org.jfree</groupId> <artifactId>fxgraphics2d</artifactId> <version>3.0</version> </dependency> </dependencies>
For Gradle, add this to your build.gradle:
dependencies { implementation 'org.scilab.forge:jlatexmath:1.0.7' implementation 'org.jfree:fxgraphics2d:3.0' }
We'll make a custom LatexView class that extends Region (this lets it resize nicely in SceneBuilder). It wraps a Canvas to draw the LaTeX, and exposes editable properties so you can tweak it directly in SceneBuilder:
import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.Region; import org.jfree.fx.FXGraphics2D; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; public class LatexView extends Region { private Canvas canvas; private String latexText = ""; private float fontSize = 16f; public LatexView() { canvas = new Canvas(); getChildren().add(canvas); // Redraw the formula when the component resizes widthProperty().addListener((obs, oldVal, newVal) -> drawLatex()); heightProperty().addListener((obs, oldVal, newVal) -> drawLatex()); } private void drawLatex() { if (latexText.isEmpty()) return; GraphicsContext gc = canvas.getGraphicsContext2D(); FXGraphics2D g2d = new FXGraphics2D(gc); // Clear the canvas before redrawing to avoid overlaps gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); try { TeXFormula formula = new TeXFormula(latexText); // Create an icon from the formula with our desired font size TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, fontSize); // Match the canvas size to the formula's natural size canvas.setWidth(icon.getIconWidth()); canvas.setHeight(icon.getIconHeight()); // Draw the formula centered in the component icon.paintIcon(null, g2d, (getWidth() - icon.getIconWidth()) / 2, (getHeight() - icon.getIconHeight()) / 2); } catch (Exception e) { e.printStackTrace(); // Show an error message if the LaTeX is invalid gc.fillText("Invalid LaTeX: " + latexText, 10, 20); } } // These getters/setters make properties editable in SceneBuilder public String getLatexText() { return latexText; } public void setLatexText(String latexText) { this.latexText = latexText; drawLatex(); } public float getFontSize() { return fontSize; } public void setFontSize(float fontSize) { this.fontSize = fontSize; drawLatex(); } }
- Compile your project to generate the
LatexView.classfile. - Open SceneBuilder, go to Preferences > Libraries > Add Library and select your project's output directory (or a JAR if you package the component).
- Restart SceneBuilder. You'll now see
LatexViewin the Custom section of the Library panel.
Drag LatexView onto your scene, then use the Properties panel to set:
latexText: Your LaTeX formula (remember to escape backslashes with\\in FXML, e.g.,\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi})fontSize: The size of your formula text
Here's an example FXML snippet:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.VBox?> <?import com.yourpackage.LatexView?> <VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"> <children> <LatexView latexText="\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi}" fontSize="20"/> <LatexView latexText="E = mc^2" fontSize="24"/> </children> </VBox>
- If your formula doesn't show up, double-check your dependencies—missing libraries are a common pitfall.
- If the formula is cut off, ensure the
LatexViewcomponent has enough space in your layout (try setting itsprefWidthandprefHeightin SceneBuilder). - Play around with the
TeXConstantsstyle (likeSTYLE_TEXTinstead ofSTYLE_DISPLAY) for different formula formatting.
内容的提问来源于stack exchange,提问作者Ofir

