I created this to learn about creating custom controls using Region. I did not do any testing of the Control, and it is limited to displaying Java only. I didn't need this for any reason other than learning. That is why I didn't put much into it.
I know I could have used a RichText control to do this in pure Java/JavaFx, but I would have spent a lot of time getting the functions of the node correct and less time figuring out how to create a custom node using Region.
I couldn't find good JavaFX resources on this. I had to look at one of HanSolo's nodes to figure things out. https://github.com/HanSolo
What are the criticisms related to creating custom JavaFX nodes using Region or any other coding criticisms?
https://github.com/sedj601/CodeView
CodeView
import java.net.URISyntaxException;
import javafx.scene.layout.Region;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
/**
*
* @author sedj601
*/
public class CodeView extends Region
{
private String prismCssLocation;
private String primsJavascriptLocation;
private CodeLanguage codeLanguage;
private String code;
private String htmlString =
"""
<!DOCTYPE html>
<html>
<head>
<link href="%s" rel="stylesheet" type="text/css"/>
<script src="%s" type="text/javascript"></script>
</head>
<body>
<div style="height: 100%%; overflow: auto;">
<pre>
<code class="%s">
%s
</code>
</pre>
</div>
</body>
</html>
""";
public enum CodeLanguage
{
//todo - add support for other languages.
JAVA("language-java");
private final String jsCode;
private CodeLanguage(String jsCode)
{
this.jsCode = jsCode;
}
public String getJsCode()
{
return this.jsCode;
}
}
private final WebView webView = new WebView();
private static final double PREFERRED_WIDTH = 500;
private static final double PREFERRED_HEIGHT = 500;
private static final double MINIMUM_WIDTH = 400;
private static final double MINIMUM_HEIGHT = 400;
private static final double MAXIMUM_WIDTH = Double.MAX_VALUE;
private static final double MAXIMUM_HEIGHT = Double.MAX_VALUE;
private double width;
private double height;
public CodeView(String code, CodeLanguage codeLanguage)
{
try
{
this.prismCssLocation = getClass().getResource("prism.css").toURI().toString();
this.primsJavascriptLocation = getClass().getResource("prism.js").toURI().toString();
this.code = code;
this.codeLanguage = codeLanguage;
String htmlString2 = this.htmlString.formatted(prismCssLocation, primsJavascriptLocation, this.codeLanguage.getJsCode(), this.code);
initGraphics(htmlString2);
registerListeners();
}
catch (URISyntaxException ex)
{
System.out.println(ex.toString());
}
}
private void initGraphics(String htmlString2)
{
if (Double.compare(getPrefWidth(), 0.0) <= 0 || Double.compare(getPrefHeight(), 0.0) <= 0 || Double.compare(getWidth(), 0.0) <= 0 || Double.compare(getHeight(), 0.0) <= 0)
{
if (getPrefWidth() > 0 && getPrefHeight() > 0)
{
setPrefSize(getPrefWidth(), getPrefHeight());
}
else
{
setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
}
}
WebEngine engine = webView.getEngine();
engine.setJavaScriptEnabled(true);
engine.loadContent(htmlString2);
webView.setMinSize(MINIMUM_WIDTH, MINIMUM_HEIGHT);
webView.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
webView.setMaxSize(MAXIMUM_WIDTH, MAXIMUM_HEIGHT);
getChildren().setAll(webView);
}
// ******************** Methods *******************************************
@Override protected double computeMinWidth(final double HEIGHT) { return MINIMUM_WIDTH; }
@Override protected double computeMinHeight(final double WIDTH) { return MINIMUM_HEIGHT; }
@Override protected double computePrefWidth(final double HEIGHT) { return super.computePrefWidth(HEIGHT); }
@Override protected double computePrefHeight(final double WIDTH) { return super.computePrefHeight(WIDTH); }
@Override protected double computeMaxWidth(final double HEIGHT) { return MAXIMUM_WIDTH; }
@Override protected double computeMaxHeight(final double WIDTH) { return MAXIMUM_HEIGHT; }
// ******************** Listeners *******************************************
private void registerListeners()
{
widthProperty().addListener(o -> resize());
heightProperty().addListener(o -> resize());
}
// ******************** Resizing ******************************************
private void resize()
{
width = getWidth() - getInsets().getLeft() - getInsets().getRight();
height = getHeight() - getInsets().getTop() - getInsets().getBottom();
if (width > 0 && height > 0)
{
webView.setPrefWidth(width);
webView.setPrefHeight(height);
}
}
}
Main
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application
{
@Override
public void start(Stage primaryStage)
{
String javaString2 =
"""
/*Hello World.java*/
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
""";
CodeView codeView = new CodeView(javaString2, CodeView.CodeLanguage.JAVA);
VBox.setVgrow(codeView, Priority.ALWAYS);
VBox root = new VBox(new StackPane(new Label("CodeView Test")), codeView);
Scene scene = new Scene(root, 500, 500);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch();
}
}
root.setStyle("-fx-background-colo**r**: green");missing r \$\endgroup\$