Titled pane css settings
Default css of titled pane...change it according your need.
.titled-pane
{
-fx-skin: "com.sun.javafx.scene.control.skin.TitledPaneSkin";
-fx-text-fill: -fx-text-base-color;
}
.titled-pane:focused
{
-fx-text-fill: white;
}
.titled-pane > .title
{
-fx-background-color: -fx-box-border, -fx-inner-border, -fx-body-color;
-fx-background-insets: 0, 1, 2;
-fx-background-radius: 5 5 0 0, 4 4 0 0, 3 3 0 0;
-fx-padding: 0.166667em 0.833333em 0.25em 0.833333em; /* 2 10 3 10 */
}
.titled-pane:focused > .title
{
-fx-color: -fx-focus-color;
}
.titled-pane > .title > .arrow-button
{
-fx-background-color: null;
-fx-background-insets: 0;
-fx-background-radius: 0;
-fx-padding: 0.0em 0.25em 0.0em 0.0em; /* 0 3 0 0 */
}
.titled-pane > .title > .arrow-button .arrow
{
-fx-background-color: -fx-mark-highlight-color, -fx-mark-color;
-fx-background-insets: 1 0 -1 0, 0;
-fx-padding: 0.25em 0.3125em 0.25em 0.3125em; /* 3 3.75 3 3.75 */
-fx-shape: "M 0 0 h 7 l -3.5 4 z";
}
.titled-pane:collapsed > .title > .arrow-button .arrow
{
-fx-rotate: -90;
}
.titled-pane > *.content
{
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-color,-02%), derive(-fx-color,65%) 12%, derive(-fx-color,23%) 88%, derive(-fx-color,50%) 99%, -fx-box-border);
-fx-background-insets: 0, 0 1 1 1;
-fx-padding: 0.167em;
}
.titled-pane:focused > .title > .arrow-button .arrow
{
-fx-background-color: white;
}
Style the title of a javafx TitledPane with css
Even though the documentation claims the .text
node is a Labeled
, it is actually a com.sun.javafx.scene.control.LabeledText
, which is a subclass of Text
.
A Text
has no -fx-text-fill
property, but has a -fx-fill
property (because it is a subclass of Shape
). Consequently, the correct CSS is
.titled-pane > .title
{
-fx-background-color: rgba(0, 60, 136, 0.5);
-fx-border-color: rgba(0, 60, 136, 0.8);
-fx-font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
-fx-font-size: 16px;
-fx-font-weight: bold;
}
.titled-pane > .title > .text
{
-fx-fill: WHITE;
}
Scenic View can be very useful in figuring out these issues.
Java FX TitledPane .title CSS Selector
You can use a lookup to retrieve the element, and then set an inline style:
int padding = ... ;
myTitledPane.lookup(".title").setStyle("-fx-padding: "+padding+"px;");
Note that lookups will only work once the first CSS pass has been made (typically this means the titled pane must be shown on the screen); also inline styles are not usually the best approach. However, if the padding is programmatically determined, this is probably the way you want to do this.
If you do want to do this by manipulating style classes, remember that nodes can have multiple styles. So I would probably do something like
.my-titled-pane > .title {
/* common styles for title, eg */
-fx-background-color: red ;
}
.style-one > .title {
-fx-padding: 10px ;
}
.style-two > .title {
-fx-padding: 12px ;
}
/* etc */
And then in Java
myTitledPane.getStyleClass().add(getSomeCSSStyleClass());
Depending on when this code is invoked, you may need to remove style classes to avoid duplicates, etc.
JavaFX TitledPane changed title background is reset on mouse entered
Setting inline CSS styling takes the priority over from the styles in css file. So applying the background through setStyle will do the trick.
button.setOnAction(event -> {
final Node node = titledPane.lookup(".title");
if (button.isSelected()) {
node.setStyle("-fx-background-color:#00ff11;");
} else {
node.setStyle(null);
}
});
UPDATE:
However, a bit more details on the actual problem. To understand this, you need to first know how the background of .title is defined internally and how the hover styling is set.
Internally in Modena.css below are the styling for the background of .title:
.titled-pane > .title {
-fx-background-color:
linear-gradient(to bottom,
derive(-fx-color,-15%) 95%,
derive(-fx-color,-25%) 100%
),
-fx-inner-border, -fx-body-color;
-fx-background-insets: 0, 1, 2;
-fx-background-radius: 3 3 0 0, 2 2 0 0, 1 1 0 0;
-fx-padding: 0.3333em 0.75em 0.3333em 0.75em; /* 4 9 4 9 */
}
.titled-pane > .title:hover {
-fx-color: -fx-hover-base;
}
If you notice the actual background is derived from -fx-color, -fx-inner-border & -fx-body-color. However -fx-inner-border & -fx-body-color are indeed again derived from -fx-color only.
-fx-inner-border: linear-gradient(to bottom,
ladder(
-fx-color,
derive(-fx-color,30%) 0%,
derive(-fx-color,20%) 40%,
derive(-fx-color,25%) 60%,
derive(-fx-color,55%) 80%,
derive(-fx-color,55%) 90%,
derive(-fx-color,75%) 100%
),
ladder(
-fx-color,
derive(-fx-color,20%) 0%,
derive(-fx-color,10%) 20%,
derive(-fx-color,5%) 40%,
derive(-fx-color,-2%) 60%,
derive(-fx-color,-5%) 100%
));
-fx-body-color: linear-gradient(to bottom,
ladder(
-fx-color,
derive(-fx-color,8%) 75%,
derive(-fx-color,10%) 80%
),
derive(-fx-color,-8%));
In the :hover pseudo state, the -fx-color is changed to -fx-hover-base and the background is updated accordingly. There lies your problem. You are setting only the default background programatically. On mouse over the .title, it still picks the internally CSS file styling (as you have not defined your custom one for hover).
If we manage to update the -fx-color attribute, then it will take care of the corresponding css updates for different pseudo states.
A more correct approach for your requirement will be as below: this way you can still get the nice gradient features of title which are internally defined.
button.setOnAction(event -> {
final Node node = titledPane.lookup(".title");
if (button.isSelected()) {
node.setStyle("-fx-color:#00ff11;");
} else {
node.setStyle(null);
}
});
// In css file
.titled-pane > .title {
-fx-color: -primary-border-color;
-fx-background-insets: 0;
-fx-background-radius: 0 0 0 0;
-fx-padding: 0.2em 0.2em 0.2em 0.2em;
}
UPDATE 2:
Please find below an example for TitledPane inside another TitledPane.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TitledPane;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Set;
public class TitledPaneApplication extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
final VBox root = new VBox();
root.setSpacing(10);
final TitledPane titledPane = new TitledPane();
titledPane.setText("Title");
final String titleBackgroundValue = "#00ff11";
final ToggleButton button = new ToggleButton("Change");
button.setOnAction(event -> {
final Set<Node> node = titledPane.lookupAll(".title");
if (button.isSelected()) {
node.forEach(n->n.setStyle("-fx-color:#00ff11;"));
} else {
node.forEach(n->n.setStyle(null));
}
});
button.setSelected(false);
VBox inner = new VBox();
inner.setSpacing(10);
inner.setPadding(new Insets(10));
final TitledPane innerTP = new TitledPane();
innerTP.setText("Inner Title");
inner.getChildren().addAll(new Label("Inner"),innerTP);
innerTP.setContent(new Button("Dummy Button"));
titledPane.setContent(inner);
root.getChildren().addAll(button,titledPane);
final Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass().getResource("light.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("TestApplication");
primaryStage.show();
}
}
JavaFX TitledPane double border using css file
I found the problem. It was at css
.titled-pane .title,
.titled-pane .content{
...
}
This .titled-pane .content
select all sub-nodes content
of titled-pane
, even sub-nodes of sub-nodes of titled-pane
Structure of this titledPane.setContent(new javafx.scene.control.TextArea("Batman"));
is:
TitledPane -> title
-> content = TextArea -> scroll-pane -> content
So my css change both content
, which result in adding border to scroll-pane -> content
To modify only direct sub-nodes titledpane -> title
and titledpane-> title
, I need to use >
:
.titled-pane > .title,
.titled-pane > .content{
...
}
How can i select TitledPane`s title without CSS in JavaFX?
You should call the lookup()
after the node was added to the stage and after Stage.show()
. For example like this:
@Override
public void start(Stage primaryStage) {
TitledPane root = new TitledPane();
root.setText("Options");
primaryStage.setScene(new Scene(root, 200, 100));
primaryStage.show();
root.lookup(".titled-pane > .title > .text").setStyle("-fx-font-weight: bold;");
}
As you can see you should also use .titled-pane > .title > .text
to get the actual text label (docs).
Related Topics
Wrapping Text Around a Div with CSS
Hover One Element, and Change Another (Without Using JavaScript)
Node + React - Hyphenated CSS Class Names
Top-Left and -Right Corner Rounded in Javafx/Css
How to Give a Font Awesome Icon a Background Color
Radio Button Causes Browser to Jump to the Top
Css: Auto Resize Div to Fit Container Width
Gatsby: Set Background Image with CSS
Using Less, CSS3 Calc() Doesn't Work Correctly
Css: What's a Good Way to Create a Raised Box Effect
Difference Between Baseline of Empty and Non-Empty Inline Blocks
Ie11 Flexbox Preventing Text Wrapping
CSS Superscript Registration Trademark
How to Decode Base64-Encoded Font Information
Hide Check Radio Button with CSS