Best reference for JavaFX CSS properties & selectors - java

I'm trying to learn JavaFX 2, but I've been stumbling a lot trying to style my application. I've found this document which tries to document controls and the css properties that apply to them. I can't tell if it's incomplete, if I should be using some unknown selectors or JavaFX's CSS support just isn't powerful enough for my needs.
Here are a couple of examples:
How would I change the background color for the area behind a TabPane without coloring every other child component (is there a selector for that, or perhaps a property?)
How would I change the color of non-selected tabs?

Have you tried something like this?
This uses an ID selector as shown in the "Skinning JavaFX Applications with CSS" document. You could also leave off the "#MyTabPane" selector and have it apply to all TabPane's. (It looks like the .tab and .tab-content-area selectors are not discussed in the reference guide. I went to the "caspian.css" file contained in jfxrt.jar file to find them.)
TabExample.css
#MyTabPane .tab {
-fx-background-color: blue;
}
#MyTabPane .tab:selected {
-fx-background-color: red;
}
#MyTabPane .tab-content-area {
-fx-background-color: cyan;
}
#MyTabPane .tab *.tab-label {
-fx-text-fill: white;
}
TabPaneEx.java
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World");
StackPane root = new StackPane();
TabPane pane = new TabPane();
pane.setId(("MyTabPane"));
Tab tab1 = new Tab("ONE");
Tab tab2 = new Tab("TWO");
Tab tab3 = new Tab("THREE");
pane.getTabs().addAll(tab1,tab2,tab3);
Scene scene = new Scene(root, 300, 250);
root.getChildren().add(pane);
scene.getStylesheets().add(
this.getClass().getClassLoader().getResource("tabpaneex/TabExample.css").toString());
primaryStage.setScene(scene);
primaryStage.show();
}

JavaFX CSS Reference Guide
Skinning JavaFX Applications with CSS

Related

How to change styling for disabled ListView in JavaFX?

I'm trying to make a disabled ListView look the same as a non-disabled ListView.
I looked it up and found that you have to set the opacity to 1 and have tried a number of approaches, with and without stylesheets, but none seem to work. I have tried:
listView.setStyle("-fx-opacity: 1.0;");
.listView:disabled {
-fx-opacity: 1.0;
}
.listView .list-cell {
-fx-opacity: 1.0;
}
.listView .list-cell:disabled {
-fx-opacity : 1.0;
}
I have also tried setting the background-color to white but this makes the text invisble for some reason, even though no other color does that. How would I go about doing this? Thanks.
Setting the opacity in the disabled pseudo-class (as you mentioned) should be enough:
.list-view:disabled {
-fx-opacity: 1;
}
just dont forget to add the stylesheet to the Scene:
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
As an example:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
ListView<String> lw = new ListView<>();
lw.setItems(FXCollections.observableArrayList("dog", "cat", "whale"));
lw.setDisable(true);
root.setCenter(lw);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
and the CSS selector is contained in the file application.css and this file placed in the same directory as the Application class file.
Note: If you would like to have the selection also to look like the same, you can define the following selectors also:
.list-cell:disabled,
.list-cell:disabled,
.list-view:disabled {
-fx-opacity: 1;
}

JavaFX - Get Rid of `CustomMenuItem` blue highlight?

I have been struggling to remove a blue highlight from a ContextMenu implementation when it is hovered over.
private void attachContextMenu() {
CustomMenuItem item = FilterPanel.getInMenuItem(this);
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().add(item);
tableColumn.setContextMenu(contextMenu);
}
With the containing VBox I was able to paint it white and get rid of a majority of the blue flash.
filterVBox.setStyle("-fx-background-color: white;");
But i cannot figure out how to get the CustomerMenuItem to lose the blue border when focused with the mouse.I tried the following but it does not work
CustomMenuItem item = FilterPanel.getInMenuItem(this);
item.setStyle("-fx-text-fill: white;");
Here is the PR if you want the full picture, but does anybody have an idea how I can manipulate that to go away?
I was able to get it to go away by styling every MenuItem for the entire TableView with this CSS. But I'd like to apply it specifically to just that CustomMenuItem.
.menu-item:focused {
-fx-background-color: transparent;
}
Since the blue highlight happens when the ContextMenu gets the focus, you are dealing here with a Pseudoclass. In CSS, a pseudo-class is used to define a specific state of a node. Typical states are hover, selected, focused...
The way to deal with this is by adding a CSS file, where you can easily apply your style settings to any of the possible states.
First, apply a style class to your ContextMenu (so other controls using context menus don't get affected by these settings). For instance, column-filter:
private void attachContextMenu() {
CustomMenuItem item = FilterPanel.getInMenuItem(this);
ContextMenu contextMenu = new ContextMenu();
contextMenu.getStyleClass().add("column-filter");
contextMenu.getItems().add(item);
tableColumn.setContextMenu(contextMenu);
}
Then add the required styling rules to a css file:
style.css
.column-filter .context-menu {
-fx-background-color: white;
}
.column-filter .context-menu:focused {
-fx-background-color: white;
}
.column-filter .custom-menu-item {
-fx-background-color: white;
-fx-padding: 0;
}
.column-filter .custom-menu-item:focused {
-fx-background-color: white;
}
Finally you need to apply this stylesheet to the scene:
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
And you'll get rid of the highlight.

JavaFX Change textcolor of disabled textfield in CSS

I have a texfield in a stage:
#FXML
private TextField tfAdUsername;
tfAdUsername.setPromptText(userName);
tfAdUsername.setDisable(true);
The textcolor is lightgray, i want to change it to black:
.text-field:readonly {
-fx-background-color: #E0E0E2;
-fx-border-color: #94BBDA;
-fx-text-fill: #000000;
}
.text-field:disabled {
-fx-background-color: #E0E0E2;
-fx-border-color: #94BBDA;
-fx-text-fill: #000000;
}
This doesn't change the textcolor. What is the correct CSS Property to use?
The reason why color turns grey on disabling is because of the opacity change. Just try adding the following css to your textfield.
-fx-opacity: 1.0;
Working example (using setStyle() )
public class KeyStroke extends Application {
#Override
public void start(Stage primaryStage) {
Pane root = new Pane();
TextField textField = new TextField("Itachi");
textField.setDisable(true);
textField.setStyle("-fx-opacity: 1.0;");
root.getChildren().add(textField);
Scene scene = new Scene(root, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
For changing the opacity use:
.text-input:disabled {
-fx-opacity: 1.0;
}
in the css file.
To change the textcolor used (after i read the question properly i know this wasn't asked.)
From the modena.css stylesheet:
.root {
/* Used for the inside of text boxes, password boxes, lists, trees, and
* tables. See also -fx-text-inner-color, which should be used as the
* -fx-text-fill value for text painted on top of backgrounds colored
* with -fx-control-inner-background.
*/
-fx-control-inner-background: derive(-fx-base,80%);
/* Version of -fx-control-inner-background for alternative rows */
-fx-control-inner-background-alt: derive(-fx-control-inner-background,-2%);
/* One of these colors will be chosen based upon a ladder calculation
* that uses the brightness of a background color. Instead of using these
* colors directly as -fx-text-fill values, the sections in this file should
* use a derived color to match the background in use. See also:
*
* -fx-text-base-color for text on top of -fx-base, -fx-color, and -fx-body-color
* -fx-text-background-color for text on top of -fx-background
* -fx-text-inner-color for text on top of -fx-control-inner-color
* -fx-selection-bar-text for text on top of -fx-selection-bar
*/
}
.root {
-fx-text-inner-color: #FF01F3;
}
For example:
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
root.setAlignment(Pos.CENTER);
Button btn = new Button();
TextField text= new TextField();
btn.setText("Press me!");
btn.setOnAction((ActionEvent event) -> {
text.setText("Goodbye World");
});
root.getChildren().addAll(btn, text);
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().addAll(getClass().getResource("css.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
And the color of the text in the textfield will be pink?purple?
This is by the way not a means to change the color for each textfield individually, if you change this for the root then all the textfields will use this color instead of the usual black. I don't know how to change the color for one textfield to blue and for another one in the same application to red.

Center tabs in tabpane using CSS

I am trying to center the tabs in a JavaFX TabPane but seem to be unable to achieve the desired result.
Using the CSS reference I am able to target various pieces of the sub-structure of the TabPane control but no matter what I try I am unable to centre the tabs horizontally within the header.
The CSS I have so far is below:
.tab-pane > .tab-header-area > .headers-region {
-fx-border-color: red;
-fx-border-width: 3;
-fx-alignment: CENTER;
}
.tab-pane > .tab-header-area > .tab-header-background {
-fx-border-color: blue;
-fx-border-width: 3;
}
Which gives the following result:
As you can see, the coloured borders show I am correctly selecting the sub-structure of the TabPane but the -fx-alignment property appears to have no effect.
Is it possible to centre the tabs horizontally within the header using CSS and if so which property do I need to set and which part of the sub-structure do I need to target?
Well this not a neat solution, it is more a workaround. Since the sub structure of tabpane consist of stackpanes, these stackpanes align to center by default. But tabs are not aligned to center, which implies there is custom laying out in the skin code. The right solution can be found after reading the tabpane skinning code.
Platform.runLater(new Runnable() {
#Override
public void run() {
final StackPane region = (StackPane) tabPane.lookup(".headers-region");
final StackPane regionTop = (StackPane) tabPane.lookup(".tab-pane:top *.tab-header-area");
regionTop.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
Insets in = regionTop.getPadding();
regionTop.setPadding(new Insets(
in.getTop(),
in.getRight(),
in.getBottom(),
arg2.doubleValue() / 2 - region.getWidth() / 2));
}
});
// force re-layout so the tabs aligned to center at initial state
stage.setWidth(stage.getWidth() + 1);
}
});
The javacode workaround posted by #Uluk Biy didn't work for me.
But this CSS soluton did.

CSS error in JavaFX project

I'm trying to add a background image to my AnchorPane in JavaFX using a stylesheet called Style.css
When I run the program I get the following warning:
WARNING: com.sun.javafx.css.parser.CSSParser declaration CSS Error
parsing in-line style 'AnchorPane' from javafx.scene.Node$22#5c4a9e8e:
Expected COLON at [-1,-1]
My CSS file looks like this:
#AnchorPane{
-fx-background-image:url('penthouse.png');
-fx-background-repeat: no-repeat;
}
.chat{
-fx-background-image:url('penthouse.png');
-fx-background-repeat: no-repeat;
}
#btnSend{
}
#txtMessage{
}
#Figur{
-fx-background-image:url('Figur.png');
}
My Java code looks like this:
public void start(Stage primaryStage) throws Exception {
BorderPane bp = new BorderPane();
bp.setRight(createRightOptionPane());
bp.setBottom(createMessagePane());
bp.setCenter(createVisualChat());
Group root = new Group();
root.getChildren().add(bp);
Scene scene = new Scene(root);
// adding the stylesheet to the scene
scene.getStylesheets().add("Style.css");
primaryStage.setScene(scene);
primaryStage.setWidth(478);
primaryStage.setHeight(433);
primaryStage.setTitle("Chat");
primaryStage.show();
}
private Node createVisualChat() {
AnchorPane chat = new AnchorPane();
// setting the anchorPanes ID to AnchorPane
chat.setStyle("AnchorPane");
return chat;
}
Can anyone tell me what is wrong with this code?
In your code at line
// setting the anchorPanes ID to AnchorPane
chat.setStyle("AnchorPane");
you are setting the style not ID. It should be
chat.setId("AnchorPane");
See Skinning JavaFX Applications with CSS for more details.

Categories