javacssjavafx

Having Trouble Merging my CSS file to my JavaFX File, A couple problems


I am asking for help because I have tried multiple ways to try and get my css file to merge with my JavaFX File, I believe I'm doing it correctly but may be using incorrect syntax in the css or maybe just the wrong functions altogether.

File Format:

JavaFX File is in src/main/java/com/circles

CSS File is in src/main/java/resources/styleSheet.css

Expected Results:

Create A JavaFX Border that holds four circles, the first two being white, and the second two being green and red. The first circle will have two vertical lines next to the left and the right of the circle.

Error:

It's an error on my end and not the IDE, since I am currently being shown an output that only shows three black circles with two very small black lines to my first circle is missing a circle, instead of my expected results.

Any help would be amazing, I will post the code below and I have a couple different examples in that code of how I had tried to get it to work, instead of using the same method for all of them.

package com.example.circles;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class circles extends Application {

    @Override
    public void start(Stage primaryStage) {

        // Pane to hold the shapes

        Pane pane = new Pane();

        // Rectangle Black stroke with transparent fill

        Rectangle rectangle = new Rectangle(50, 50, 700, 400);

        rectangle.getStyleClass().add("border");

        // Circle 1: White fill, black stroke
        Circle circle1 = new Circle(100, 150, 50);
        circle1.setId("white-circle");

        // Circle 2: White fill, black stroke
        Circle circle2 = new Circle(250, 150, 50);
        circle2.setId("white-circle");

        // Circle 3: Red fill
        Circle circle3 = new Circle(400, 150, 50);
        circle3.getStyleClass().add("red-circle");

        // Circle 4: Green fill
        Circle circle4 = new Circle(550, 150, 50);
        circle4.getStyleClass().add("green-circle");

        // Vertical line to the left of Circle 1
        Line leftLine = new Line(50, 100, 50, 200); // x = 50, y1 = 100, y2 = 200
        leftLine.setStrokeWidth(2);
        leftLine.setStyle("-fx-stroke: black;");

        // Vertical line to the right of Circle 1
        Line rightLine = new Line(150, 100, 150, 200); // x = 150, y1 = 100, y2 = 200
        rightLine.setStrokeWidth(2);
        rightLine.setStyle("-fx-stroke: black;");


        // Add all shapes to the pane
        pane.getChildren().addAll(leftLine, rightLine, circle1, circle2, circle3, circle4);


        // Create the scene and link the CSS file
        Scene scene = new Scene(pane, 500, 400);
        scene.getStylesheets().add("styleSheet.css");


        // Set up the stage
        primaryStage.setTitle("Circles");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {

        launch(args);
    }
}

CSS File

/* Rectangle border style */
#border-rectangle {
    -fx-fill: transparent;
    -fx-stroke: black;
    -fx-stroke-width: 2;
}

/* First circle style */
#circle1 {
    -fx-fill: white;
    -fx-stroke: black;
    -fx-stroke-width: 2;
}

/* Second circle style */
#circle2 {
    -fx-fill: white;
    -fx-stroke: black;
    -fx-stroke-width: 2;
}

/* Third circle style */
#circle3 {
    -fx-fill: red;
}

/* Fourth circle style */
#circle4 {
    -fx-fill: green;
}

/* Vertical line style */
#vertical-line {
    -fx-stroke: black;
    -fx-stroke-width: 2;
}

Solution

  • There are multiple problems (some will break stuff, some are just conventions):

    Example

    So following that advice, you can get the following output:

    cirles

    With this example code.

    src/main/java/module-info.java

    module org.example.cicles {
        requires javafx.controls;
        exports org.example.circles;
    }
    

    src/main/java/org/example/circles/CircleApp.java

    package org.example.circles;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Line;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    
    import java.util.Objects;
    
    public class CircleApp extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            // Pane to hold the shapes
            Pane pane = new Pane();
    
            // Rectangle Black stroke with transparent fill
            Rectangle rectangle = new Rectangle(25, 25, 600, 250);
            rectangle.setId("border-rectangle");
    
            // Circle 1: White fill, black stroke
            Circle circle1 = new Circle(100, 150, 50);
            circle1.setId("circle1");
    
            // Circle 2: White fill, black stroke
            Circle circle2 = new Circle(250, 150, 50);
            circle2.setId("circle2");
    
            // Circle 3: Red fill
            Circle circle3 = new Circle(400, 150, 50);
            circle3.setId("circle3");
    
            // Circle 4: Green fill
            Circle circle4 = new Circle(550, 150, 50);
            circle4.setId("circle4");
    
            // Vertical line to the left of Circle 1
            Line leftLine = new Line(50, 100, 50, 200); // x = 50, y1 = 100, y2 = 200
            leftLine.setId("vertical-line");
    
            // Vertical line to the right of Circle 1
            Line rightLine = new Line(150, 100, 150, 200); // x = 150, y1 = 100, y2 = 200
            rightLine.setId("vertical-line");
    
    
            // Add all shapes to the pane
            pane.getChildren().addAll(rectangle, leftLine, rightLine, circle1, circle2, circle3, circle4);
    
    
            // Create the scene and link the CSS file
            Scene scene = new Scene(pane, 650, 300);
            scene.getStylesheets().add(
                    Objects.requireNonNull(
                            CircleApp.class.getResource(
                                    "style-sheet.css"
                            )
                    ).toExternalForm()
            );
    
    
            // Set up the stage
            primaryStage.setTitle("Circles");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    src/main/resources/org/example/circles/style-sheet.css

    /* Rectangle border style */
    #border-rectangle {
        -fx-fill: transparent;
        -fx-stroke: black;
        -fx-stroke-width: 2;
    }
    
    /* First circle style */
    #circle1 {
        -fx-fill: white;
        -fx-stroke: black;
        -fx-stroke-width: 2;
    }
    
    /* Second circle style */
    #circle2 {
        -fx-fill: white;
        -fx-stroke: black;
        -fx-stroke-width: 2;
    }
    
    /* Third circle style */
    #circle3 {
        -fx-fill: red;
    }
    
    /* Fourth circle style */
    #circle4 {
        -fx-fill: green;
    }
    
    /* Vertical line style */
    #vertical-line {
        -fx-stroke: black;
        -fx-stroke-width: 2;
    }
    

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.example.circles</groupId>
        <artifactId>circle-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <name>circle-demo</name>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <javafx.version>23.0.1</javafx.version>
            <java.version>21</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-controls</artifactId>
                <version>${javafx.version}</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.13.0</version>
                    <configuration>
                        <source>${java.version}</source>
                        <target>${java.version}</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    Related

    Further info on finding resources (do study it):

    Unrelated Advice

    Use a build system

    Use Maven or Gradle (Maven may be easier to get started with if you have used neither one). Those build systems will automatically handle building code following the standard directory layout and can interface with your IDE.

    Understand package naming conventions

    Short note on package naming conventions.

    It would be best to use your own namespace such as org.myname.examples or something generic like org.example and place everything in that.

    Using org.example makes it clear you never to intend to publish the code to a central shared repository, and using your own namespace means you could publish to a central shared repository. But for code not published to a repository, it doesn't matter too much.