JavaFX FadeTransition conflicting with CSS -fx-opacity - css

Im building a custom composite UI Control in JavaFX with a button, that should fade in from 0 to 0.1 opacity if hovering somewhere over the Control. If hovering over the button itself, opacity should change to 1.0, which can easily be achieved via CSS.
Here the FadeTransition:
// unfortunately, animations cannot be defined in CSS yet
FadeTransition fadeInButton =
new FadeTransition(Duration.millis(300), settingsButton);
fadeInButton.setFromValue(0);
fadeInButton.setToValue(0.1);
And here the CSS for the button:
.settings-button {
-fx-background-image: url("settings_32_inactive.png");
-fx-background-repeat: no-repeat;
-fx-background-position: center center;
-fx-opacity: 0; /* button shall be initially invisible, will be faded in */
}
.settings-button:hover {
-fx-background-image: url("settings_32.png");
-fx-opacity: 1.0; /* why is this ignored if used together with animations? */
}
Both animation and CSS properties work great separately. Unfortunately, in combination, the animation seems to override the -fx-opacity property in the CSS file. Any ideas how to make both animation and CSS properties work together?

There is no way to have css over API call, see next topic: JavaFX: Cannot set font size programmatically after font being set by CSS
But you can do next trick:
Have button with opacity 0.1 unhovered and 1 if hovered
Put button into Pane and animate this pane from 0 to 1
See next css:
/*Button*/
.b1 { -fx-opacity: 0.1; }
.b1:hover { -fx-opacity: 1.0; }
/*Pane*/
.p1 {
-fx-border-color: red;
-fx-opacity: 0;
}
and code:
public class OpacityCss extends Application {
private static final Duration DURATION = Duration.millis(300);
#Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
pane.getStyleClass().add("p1");
pane.setMinSize(100, 100);
pane.setMaxSize(100, 100);
final Button btn = new Button("Fading Button");
btn.getStyleClass().add("b1");
pane.getChildren().add(btn);
final FadeTransition fade = new FadeTransition(DURATION, pane);
fade.setAutoReverse(true);
fade.setFromValue(0);
fade.setToValue(1);
pane.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
fade.setCycleCount(1); // this way autoreverse wouldn't kick
fade.playFromStart();
}
});
pane.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
fade.setCycleCount(2); // starting from autoreverse
fade.playFrom(DURATION);
}
});
StackPane root = new StackPane();
root.getChildren().addAll(pane);
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().add(getClass().getResource("/css/btn.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) { launch(); }
}

Related

JavaFX Change ScrollBar width from a ScrollPane

How can you change the width of a ScrollBar from a ScrollPane to a certain value of px? I looked at JavaFX 2.1 Change ScrollPane Scrollbar size but simply setting the font size to X px doesn't seem to work properly. I did some tests with big values and the width wasn't what I set it to be (ex: for a value of 50px the ScrollBar had width of 56px, for a value of 88px it had width of 96px, for a value of 40px it had width of 44px, for a value of 30px it had width of 33px, so no relation between then).
I need a solution that works from java code and not from a CSS file as I need to be able to dynamically set the value.
There were other suggestions to use .lookupAll but from what I understand you should avoid using that.
Code for setting width and colors:
scrollPane.setStyle("colorScrollBar: rgba(" + A function that returns RBGA + ");"
+ " colorScrollBarButton: rgba(" + A function that returns RBGA + ");"
+ " -fx-font-size: " + 30 + "px;");
Here is the CSS file I used to change the ScrollBar (to make it transparent, to change the colors and remove some margins):
.scroll-bar {
-fx-background-color: colorScrollBar;
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-bar .thumb {
-fx-background-color: colorScrollBarButton;
}
.scroll-bar > .increment-button > .increment-arrow,
.scroll-bar > .decrement-button > .decrement-arrow {
-fx-background-color: colorScrollBarButton;
}
.scroll-bar > .increment-button:hover,
.scroll-bar > .decrement-button:hover {
-fx-background-color: colorScrollBar;
}
.scroll-pane > .viewport {
-fx-background-color: transparent;
}
.scroll-pane {
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane:focused {
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane .corner {
-fx-background-insets: 0;
-fx-padding: 0;
}
This works for me.
private ScrollPane scrollPane;
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Circle content = new Circle(2000);
scrollPane = new ScrollPane(content);
Slider sizeSldr = new Slider(8, 80, 14);
root.setTop(sizeSldr);
root.setCenter(scrollPane);
sizeSldr.valueProperty().addListener((observable, oldValue, newValue) -> {
setScrollBarWidth(newValue.doubleValue());
});
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("ScrollBar Width");
primaryStage.setScene(scene);
primaryStage.show();
}
void setScrollBarWidth(double width) {
scrollPane.setStyle("-fx-font-size: %3.3fpx".formatted(width));
}
public static void main(String[] args) {
launch(args);
}
}
The solution I came with is to create a custom ScrollBar and use that to scroll the ScrollPane. Here is an example how to create one and bind it to the ScrollPane:
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(paneElements); //The pane that will have the nodes
scrollPane.setLayoutX(20);
scrollPane.setLayoutY(20);
scrollPane.setPrefWidth(stage.getWidth() - 40); //This was my use case, do what you need here
scrollPane.setPrefHeight(stage.getHeight() - 66); //This was my use case, do what you need here
scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setStyle("colorScrollBar: rgba(" + I am using a function that returns RGBA + ");"
+ " colorScrollBarButton: rgba(" + I am using a function that returns RGBA + ");");
pane.getChildren().add(scrollPane);
ScrollBar scrollBarVertical = new ScrollBar();
scrollBarVertical.setLayoutX(stage.getWidth() - 20)); //Use what you need
scrollBarVertical.setLayoutY(20); //Use what you need
scrollBarVertical.setPrefHeight(stage.getHeight() - 66); //Use what you need
scrollBarVertical.setMinWidth(0); //I set it to 0 because if you need to use low values, it wasn't using values lower then 16 in prefWidth in my case
scrollBarVertical.setPrefWidth(prefWidth * 0.75)); //Use what you need
scrollBarVertical.setOrientation(Orientation.VERTICAL);
scrollBarVertical.setMin(scrollPane.getVmin());
scrollBarVertical.setMax(scrollPane.getVmax());
scrollBarVertical.valueProperty().bindBidirectional(scrollPane.vvalueProperty());
scrollBarVertical.setStyle("colorScrollBar: rgba(" + I am using a function that returns RGBA + ");"
+ " colorScrollBarButton: rgba(" + I am using a function that returns RGBA + ");");
pane.getChildren().add(scrollBarVertical);
Once in the Scene, you can query the ScrollBars using:
ScrollBar vsb = (ScrollBar) scrollPane.queryAccessibleAttribute(
AccessibleAttribute.VERTICAL_SCROLLBAR);
ScrollBar hsb = (ScrollBar) scrollPane.queryAccessibleAttribute(
AccessibleAttribute.HORIZONTAL_SCROLLBAR);
vsb.setPrefWidth(40);
hsb.setPrefHeight(40);

why i can not resize a button in javafx with css

I'm trying to resize a button but it doesn't work.
the css file is linked to file properly. (the color of button changes)
public void start(Stage primaryStage) throws Exception {
VBox root = new VBox();
Button btn = new Button("s");
root.getChildren().addAll(btn);
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add("Style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
css file
.button {
-fx-width: 250px;
-fx-background-color: red;
}
also i cannot set spacing for vbox.(it dosent work)
Try this for setting width of all buttons:
.button {
-fx-min-width: 20px;
-fx-max-width: 20px;
-fx-pref-width: 20px;
}
Choose the property you want to set (max, min, pref, or all of them).
Its the same for height, just replace width with height.
To set spacing for VBox, according to this Oracle post you can do it using:
.vbox {
-fx-spacing: 10;
}

how do i integrate CSS in javafx project?

I'm trying to integrate background and button styles in my quiz project.
But I can't reach the CSS.
I have following stylesheet(mainstyle.css):
.root{
-fx-background-image: url("/afbeeldingen/Achtergrond/background_image.jpg");
-fx-background-repeat:stretch;
-fx-background-size: 600 1000;
-fx-background-position: center center;
-fx-effect: dropshadow(three-pass-box,black,30,0.5,0,0);
}
.Button {
-fx-font-size: 48;
-fx-background-color: blue;
-fx-font-weight: bold;
-fx-border-width: 2;
-fx-border-radius: 10;
-fx-padding: 5 20 5 20;
}
.choice-box{-fx-background-color: yellow;
}
And the following implementation in de Quizapp
public class QuizApp extends Application {
#Override
public void start(Stage primaryStage) {
Lijst model = new Lijst();
QuizView view = new QuizView();
QuizPresenter presenter = new QuizPresenter(model,view);
Scene scene = new Scene(view);
scene.getStylesheets().add(this.getClass().getResource("mainStyle.css").toExternalForm());
primaryStage.setTitle("LANDENQUIZ");
primaryStage.setScene(scene);
primaryStage.setWidth(1000);
primaryStage.setHeight(600);
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
But I can't see a background image or other style...

Change the color of the Scrollbar corner in WebView

I'm working with JavaFX 8 on Windows 10. In a WebView with a dark background, I can see the light grey corner when the scrollbars are visible. WebView"manages scrolling automatically." I already tried this, as well as other selectors:
.corner {
-fx-background-color: black;
}
And also
.corner {
-fx-background-color: black;
}
.scroll-bar > .corner {
-fx-background-color: black;
}
.scroll-pane > .corner {
-fx-background-color: black;
}
.scroll-bar .corner {
-fx-background-color: black;
}
.scroll-pane .corner {
-fx-background-color: black;
}
.web-view .scroll-bar .corner {
-fx-background-color: black;
}
.web-view .scroll-pane .corner {
-fx-background-color: black;
}
But it doesn't work. So what could I do?
Example code: Main class
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<html><body><pre>This is a very very very very very very long string </pre><b>test</b><p>1</p><p>2</p><p>3</p></body></html>");
webEngine.setUserStyleSheetLocation("data:,body { background: black; color: white; } ");
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(webView);
webView.setStyle("-fx-background-color:black;");
root.setStyle("-fx-background-color:black;");
root.getStylesheets().add("style.css");
primaryStage.setTitle("JavaFX Test");
primaryStage.setScene(new Scene(root, 300, 150));
primaryStage.show();
}
}
style.css
.scroll-bar .track {
-fx-background-color: black;
}
.scroll-bar .thumb {
-fx-background-color: brown;
}
.corner {
-fx-background-color: black;
}
This also has an awful behavior where the scrollbars only appear when I hover with the mouse, but nevermind. This doesn't happen in my main application. I just want to change the color of the grey square in the corner.
I am unable to reproduce the effect on Mac OS X v10.13.6 with Java v1.8.0_201. Because WebView "manages scrolling automatically" and JavaFX uses WebKit, #Pagbo suggests using -webkit-scrollbar-corner, as suggested here. In another context, #DVarga suggests using -fx-background-color, as shown here. As the effect may be platform/version dependent, I've added a complete example and screenshot for reference. In particular, the lower-right corner is overlain by the vertical scrollbar's decrement button. Stretching the window to hide the vertical scrollbar reveals the horizontal scrollbar's increment button. The corner is always occupied by a scrollbar button or black.
Main.java
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<html><body><pre>"
+ "This is a very very very very very very long string<br>"
+ System.getProperty("os.name") + " v"
+ System.getProperty("os.version") + "; Java v"
+ System.getProperty("java.version")
+ "</pre><b>test</b><p>1</p><p>2</p><p>3</p></body></html>");
webEngine.setUserStyleSheetLocation("data: ,body "
+ "{ background: black; color: white; } "
+ "::-webkit-scrollbar-corner { background: #0c0c0c; } ");
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(webView);
webView.setStyle("-fx-background-color:black;");
root.setStyle("-fx-background-color:black;");
root.getStylesheets().add("style.css");
primaryStage.setTitle("JavaFX Test");
primaryStage.setScene(new Scene(root, 300, 150));
primaryStage.show();
}
}
style.css
.scroll-bar .track {
-fx-background-color: black;
}
.scroll-bar .thumb {
-fx-background-color: brown;
}
.corner {
-fx-background-color: black;
}

JavaFX8 CustomRowFactory ContextMenu background image not entirely visible

I've set the following custom row factory:
treeTblViewFiles.setRowFactory(new Callback<TreeTableView<FileModel>, TreeTableRow<FileModel>>() {
#Override
public TreeTableRow<FileModel> call(TreeTableView<FileModel> treeTableView) {
final TreeTableRow<FileModel> row = new TreeTableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Remove");
removeItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
int currentPlaylistIndex = m_playlists.indexOf(row.getTreeItem().getParent().getValue());
boolean itemRemoved = false;
if (row.getItem().getClass().equals(Song.class)) {
itemRemoved = m_playlists.get(currentPlaylistIndex).getSongs().remove(row.getItem());
m_playlists.get(currentPlaylistIndex).updatePlaylist((Song) row.getItem());
} else if (row.getItem().getClass().equals(Playlist.class)) {
itemRemoved = m_playlists.remove(row.getTreeItem().getValue());
}
TreeItem<FileModel> treeItem = row.getTreeItem();
// may need to check treeItem.getParent() is not null:
treeItem.getParent().getChildren().remove(treeItem);
treeTblViewFiles.getSelectionModel().clearSelection();
if (MyApp.DEBUG) {
System.out.println(m_playlists.size());
if (currentPlaylistIndex > -1) {
System.out.println(m_playlists.get(currentPlaylistIndex).getSongs().size());
}
}
}
});
rowMenu.getItems().add(removeItem);
row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu) null));
return row;
}
});
and in my css I have:
/******************
* ContextMenu
******************/
.context-menu{
-fx-background-color: transparent;
}
.context-menu .menu-item{
-fx-background-image: url("styles/cm_bg.png");
-fx-background-repeat: no-repeat;
-fx-background-position: center;
-fx-background-color: transparent;
}
.context-menu .menu-item .label{
-fx-text-fill: #ababab;
-fx-font-weight: normal;
-fx-font-size: 12pt;
}
The problem is that it doesn't show the entire image(which is 220x40) but only the width that suits the 'Remove' string. The right-most part is cut.
EDIT:
Simplified version(the same result goes for a contextMenu on a Label):
ContextMenu cm = new ContextMenu();
MenuItem mi = new MenuItem("Test");
cm.getItems().addAll(mi);
lblUploader.setContextMenu(cm);
Why is that happening and how to solve it?
Thanks in advance.
Problem solved with the following .css:
.context-menu {
-fx-background-color: transparent;
-fx-min-width: <image_width>;
-fx-min-height: <image_height>;
}
Just remember to set the preferred(or min) sizes.

Resources