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;
}
There are multiple problems (some will break stuff, some are just conventions):
com
directory "src>main>java>com>circles", but your CSS is not.com
is not a good idea.com.example.circles
but it doesn't match the directory you store the java file under: "src>main>java>com>circles".java
directory. Follow the maven standard directory layout (even if you don't use maven)..
instead of #
.javafx.controls
module includes the default modena.css
stylesheet, so, when using CSS it is best to add that module to the module graph.So following that advice, you can get the following output:
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>
Further info on finding resources (do study it):
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.
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.