0
\$\begingroup\$

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();
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ root.setStyle("-fx-background-colo**r**: green"); missing r \$\endgroup\$ Commented Aug 28 at 10:34
  • 1
    \$\begingroup\$ @JoopEggen, thanks for the catch. I can remove that. I used that to debug an issue I was having with changing the screen size. \$\endgroup\$ Commented Aug 28 at 14:29

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.