Issue
I don't understand how to style a separator. I don't understand the documentation of javafx css styling website - more specifically how to use substructure (in this case line).
This is how I create my Seperator:
Separator separator = new Separator(Orientation.HORIZONTAL);
separator.setStyle("-fx-fill: white; -fx-background-color: white; -fx-border-color: null;");
The -fx-fill: white;
and -fx-border-color: null;
don't do anything. This is how it looks with this styling:
This is how it looks without styling:
And I want it to look like just one line.
I have the same problem with vertical separators:
Separator separator = new Separator(Orientation.VERTICAL);
separator.setStyle("-fx-background-color: white; -fx-border-color: null;");
The -fx-border-color: null;
again doesn't do anything. This is how it looks with this styling:
This is how it looks without styling:
And I want it to look like just one line.
my main code:
import java.io.FileNotFoundException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Slider;
import javafx.scene.effect.BoxBlur;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Visualisation extends Application {
private static final int GRID_SIZE = 40;
private static CheckBox checkBox;
private static double zoomFactor = 1;
private static VBox settings = new VBox();
private static AtomicInteger delay = new AtomicInteger(250);
private static AtomicBoolean isPaused = new AtomicBoolean(true);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws FileNotFoundException {
StackPane root = new StackPane();
root.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, javafx.geometry.Insets.EMPTY)));
Scene scene = new Scene(root, 400, 400);
Group content = new Group();
root.getChildren().add(content);
root.getChildren().add(new Separator(Orientation.HORIZONTAL)); // here I can set horizontal or vertical Seperator
// root.getChildren().add(new Separator(Orientation.VERTICAL));
setupSettings(root, stage, content);
makeZoomable(scene, content);
makeKeyPresses(stage, scene, content);
scene.widthProperty().addListener(e -> resetSize(scene, content));
scene.heightProperty().addListener(e -> resetSize(scene, content));
stage.setScene(scene);
stage.setTitle("Visualisation");
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
stage.show();
}
private void makeZoomable(Scene scene, Group content) {
scene.setOnScroll((ScrollEvent event) -> {
double deltaY = event.getDeltaY();
if (deltaY > 0) {
zoomFactor += 0.01;
} else {
zoomFactor -= 0.01;
if (zoomFactor <= 0) {
zoomFactor = 0.01;
}
}
updateTransforms(content);
});
}
private void setupSettings(StackPane root, Stage stage, Group content) {
checkBox = new CheckBox("Fullscreen");
checkBox.setStyle("-fx-text-fill: WHITE; -fx-font-size: 20; -fx-font-weight: bold");
checkBox.fire();
checkBox.selectedProperty().addListener((observable, oldValue, newValue) -> {
if (stage.isFullScreen()) {
stage.setFullScreen(false);
} else {
stage.setFullScreen(true);
}
});
Text label = new Text("Speed slider");
label.setStyle("-fx-fill: WHITE; -fx-font-size: 20");
Slider slider = new Slider(10, 1000, delay.get());
slider.setBlockIncrement(100);
slider.setSnapToTicks(true);
slider.valueProperty().addListener((observable, oldValue, newValue) -> delay.set(newValue.intValue()));
VBox speedControler = new VBox();
speedControler.setAlignment(Pos.CENTER);
speedControler.getChildren().addAll(label, slider);
Button button1 = new Button("Back");
button1.setOnAction(e -> openCloseSettings(content));
Button button2 = new Button("Exit");
button2.setOnAction(e -> System.exit(0));
HBox buttons = new HBox();
buttons.setAlignment(Pos.CENTER);
buttons.getChildren().addAll(button1, button2);
buttons.setSpacing(30);
settings.setAlignment(Pos.CENTER);
settings.setMaxWidth(Math.min(root.getWidth(), root.getHeight()));
settings.getChildren().addAll(checkBox, speedControler, buttons);
settings.setVisible(false);
settings.setSpacing(30);
root.getChildren().add(settings);
}
private void makeKeyPresses(Stage stage, Scene scene, Group content) {
scene.setOnKeyPressed(event -> {
switch (event.getCode()) {
case SPACE:
if (!settings.isVisible()) {
isPaused.set(!isPaused.get());
}
break;
case F5:
checkBox.fire();
break;
case ESCAPE:
openCloseSettings(content);
break;
default:
break;
}
});
}
private static void resetSize(Scene scene, Group root) {
boolean isPausedRemember = isPaused.get();
isPaused.set(true);
root.setLayoutX((scene.getWidth() - root.prefWidth(-1)) / 2);
root.setLayoutY((scene.getHeight() - root.prefHeight(-1)) / 2);
double scaleX = scene.getWidth() / root.getBoundsInLocal().getWidth();
double scaleY = scene.getHeight() / root.getBoundsInLocal().getHeight();
zoomFactor = Math.min(scaleX, scaleY) - 0.01;
updateTransforms(root);
isPaused.set(isPausedRemember);
}
private static void updateTransforms(Group root) {
root.setScaleX(zoomFactor);
root.setScaleY(zoomFactor);
}
private void openCloseSettings(Group content) {
if (settings.isVisible()) {
content.setEffect(null);
settings.setVisible(false);
} else {
isPaused.set(true);
BoxBlur blur = new BoxBlur(20, 20, 2);
content.setEffect(blur);
settings.setVisible(true);
}
}
}
This is how it looks with horizontal separator:
This is how it looks with vertical separator:
This is how it looks with both separators:
I want it to look like just one line (same color and width of 1; in case of horizontal it looks like 1 gray line 1 white line and 1 black line and in vertical case it looks like 1 gray line 1 white line and 1 gray line all together width of 3 in both cases) in both cases.
One thing I am noticing too is that maybe horizontal separator is centered (maybe) if you count the third black line, but vertical definitely is not. I have no idea why. I am confused about this because my scene gets centered on the elements that are placed/added to the Group content
.
The answer with setStyle()
is almost perfect but it has one problem - the shadow still exists and thats why the gap remains:
Solution
Default Separator Style
The default styling for the Separator
can be found in the modena.css
file which is located in the javafx-controls
jar of your JavaFX distribution.
It is this:
.separator:horizontal .line {
-fx-border-color: -fx-text-box-border transparent transparent transparent,
-fx-shadow-highlight-color transparent transparent transparent;
-fx-border-insets: 0, 1 0 0 0;
}
.separator:vertical .line {
-fx-border-color: transparent transparent transparent -fx-shadow-highlight-color,
transparent transparent transparent -fx-text-box-border;
-fx-border-width: 3, 1;
-fx-border-insets: 0, 0 0 0 1;
}
To change the style, you define a custom style sheet and apply that.
The default separators are rendered as borders with insets, so they don't take up layout space but do render to the screen.
For the horizontal separator, a line of height 1 is rendered to the screen in -fx-text-box-border
color, and a second line of height 1 is rendered to the screen just under it in -fx-shadow-highlight-color
to provide a 3D style look, when rendered against the default background color. So a horizontal separator is 2 pixels high.
Similarly, for the vertical separator, a line of width 1 is rendered to the screen in -fx-text-box-border
color, and a second line of width 1 is rendered to the screen on both sides in -fx-shadow-highlight-color
to provide a 3D style look, when rendered against the default background color. So a vertical separator is 3 pixels wide.
Example: Modifying the Default Separator Style
Information about the example:
- Custom-styled separators remove the faint shadow line painted for the separator which provides a faux 3D effect.
- The example changes the color of the lines in the separator.
- There are thin separators and fat separators demonstrated.
- For the fat separator styling, we replace the border setting with a background setting.
- Fat separators adjust the preferred width to match our requirements. In this example, this is done in CSS, but you could set the preferred sizes in Java code or FXML if you wish instead.
- We use linear gradients to style the fat separators, as a further example of how the style of separators can be customized.
The example uses an inline CSS style sheet to style the separators, for convenience, but you can style them using an external CSS style sheet instead.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Separator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SeparatorStylingApp extends Application {
private static final String CSS =
"""
data:text/css,
.styled-separator.separator:horizontal .line {
-fx-border-color: red transparent transparent transparent,
transparent transparent transparent transparent;
-fx-border-insets: 0, 1 0 0 0;
}
.styled-separator.separator:vertical .line {
-fx-border-color: transparent transparent transparent transparent,
transparent transparent transparent lawngreen;
-fx-border-width: 3, 1;
-fx-border-insets: 0, 0 0 0 1;
}
.fat.styled-separator.separator:horizontal .line {
-fx-border-color: null;
-fx-background-color: linear-gradient(to right, papayawhip, crimson);
-fx-pref-height: 5px;
}
.fat.styled-separator.separator:vertical .line {
-fx-border-color: null;
-fx-background-color: linear-gradient(to top, darkgreen, palegreen);
-fx-pref-width: 5px;
}
""";
@Override
public void start(Stage stage) {
Separators separators = getSeparators(null);
Separators fatSeparators = getSeparators("fat");
VBox layout = new VBox(
10,
separators.plainSeparator(),
separators.styledSeparator(),
separators.verticalSeparators(),
fatSeparators.plainSeparator(),
fatSeparators.styledSeparator(),
fatSeparators.verticalSeparators()
);
layout.setPadding(new Insets(10));
Scene scene = new Scene(layout);
scene.getStylesheets().add(CSS);
stage.setScene(scene);
stage.show();
}
private static Separators getSeparators(String additionalStyleClass) {
Separator plainSeparator = new Separator();
Separator styledSeparator = new Separator();
styledSeparator.getStyleClass().add("styled-separator");
if (additionalStyleClass != null) {
styledSeparator.getStyleClass().add(additionalStyleClass);
}
Separator plainVerticalSeparator = new Separator(Orientation.VERTICAL);
Separator styledVerticalSeparator = new Separator(Orientation.VERTICAL);
styledVerticalSeparator.getStyleClass().add("styled-separator");
if (additionalStyleClass != null) {
styledVerticalSeparator.getStyleClass().add(additionalStyleClass);
}
HBox verticalSeparators = new HBox(
30,
plainVerticalSeparator,
styledVerticalSeparator
);
verticalSeparators.setPadding(new Insets(0, 20, 0, 20));
verticalSeparators.setPrefHeight(50);
return new Separators(plainSeparator, styledSeparator, verticalSeparators);
}
private record Separators(
Separator plainSeparator,
Separator styledSeparator,
HBox verticalSeparators
) {}
public static void main(String[] args) {
launch(args);
}
}
setStyle
alternative
You can adjust some styling via setStyle
, but not with as much flexibility.
In general, using a CSS stylesheet as demonstrated earlier in this method is the preferred and most flexible method to configure custom styles.
You can adjust the lookup-up color values to color the line a different value, but that is about all you can do.
separator.setStyle("-fx-text-box-border: blue; -fx-shadow-highlight-color: transparent");`
Answered By - jewelsea
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.