I want to apply some style on my ContextMenu and MenuItem in a TableView. It works simply : Right Click on the Row and you have the ContextMenu for this row. However the ContextMenu and MenuItem are built like that :
final ContextMenu menu = new ContextMenu();
MenuItem removeitem = new MenuItem("Remove");
I tried to apply a CSS like that :
.table-view .context-menu .menu-item
and many others but with no results.
However It works when I add the style in my code with setStyle but I want to know if we can do it in CSS (I guess yes ...).
If it is the label inside the MenuItem you are trying to style use
.table-view .context-menu .menu-item .label
{
-fx-text-fill: red;
}
The MenuItem itself has no (meaningful?) stylable item s itself, at least the documentation does not list any.
Related
I am working on a Javafx application and I tried to add some Labels, Buttons and Texts, which resizes when the user resizing the Scene. All Nodes are inside a VBox, which itself is inside a StackPane.
My test application:
public class Test extends Application
{
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(final Stage primaryStage)
{
StackPane pane = new StackPane();
VBox box = new VBox();
box.setAlignment(Pos.CENTER);
Label l = new Label("Label");
Text t = new Text("Text");
t.getStyleClass().add("test");
Button b = new Button("Button");
pane.heightProperty().addListener(listener ->
{
double h = pane.getHeight()/5;
l.setFont(Font.font(l.getFont().getFamily(), h));
t.setFont(Font.font(t.getFont().getFamily(), h));
b.setFont(Font.font(b.getFont().getFamily(), h));
});
box.getChildren().addAll(l, t, b);
pane.getChildren().add(box);
primaryStage.setScene(new Scene(pane));
primaryStage.getScene().getStylesheets().add(Path.of("test.css").toUri().toString());
primaryStage.show();
}
}
If I resize the Stage it works as expected. But unfortunately only with pure Java code.
Because after adding my css file, the Labeled controls behave different. While the Text elements continue to change in size, the Labels and Buttons does not change their size anymore.
My css file, which does not work:
.label
{
-fx-text-fill: red;
-fx-font-family: impact;
}
.test
{
-fx-fill: red;
-fx-font-family: impact;
-fx-font-size: 2em;
}
.button
{
-fx-text-fill: red;
-fx-font-size: 2em;
}
I asked myself what I did wrong and have tested different css states. I found out, when I omit font values in css it works, otherwise it does not. Therewhile it does not matter which font value occurs, only one font value is required to miss the behavior.
My css file, which works:
.label
{
-fx-text-fill: red;
//-fx-font-family: impact;
}
.test
{
-fx-fill: red;
-fx-font-family: impact;
-fx-font-size: 2em;
}
.button
{
-fx-text-fill: red;
//-fx-font-size: 2em;
}
1. Question: -has changed, see below-
Do I missunderstand something about css and Javafx, or did I something wrong in my css file or is there a bug?
2. Question: -solved-
Have I to put the font values with java code or is there an other way to add the font?
Thank You for helping!
Update
As recommended I have studying the follow guide:
https://openjfx.io/javadoc/14/javafx.graphics/javafx/scene/doc-files/cssref.html
The JavaFX CSS implementation applies the following order of precedence:
The implementation allows designers to style an application by using style sheets to override property values set from code. For example, a call to rectangle.setFill(Color.YELLOW) can be overridden by an inline‑style or a style from an author stylesheet. This has implications for the cascade; particularly, when does a style from a style sheet override a value set from code? The JavaFX CSS implementation applies the following order of precedence: a style from a user agent style sheet has lower priority than a value set from code, which has lower priority than a Scene or Parent style sheet. Inline styles have highest precedence. Style sheets from a Parent instance are considered to be more specific than those styles from Scene style sheets.
In my case this means, I will use the inline style to make it proper.
thus the 2. Question is solved
But, because of Parent style sheet > value set from code, it also means, all Nodes are not allowed to change theire size, even the Text Node.
Therefore I changed my 1. Question to:
Why does the JavaFX CSS order of precedence differ between Text and Controls
Question 1:
It's not a bug, it's a conflict of priorities. .setFont() has a lower priority than that CSS. Just replace .setFont() to .setStyle() and sample will work as you planned:
l.setStyle("-fx-font-size:" + h + ";");
t.setStyle("-fx-font-size:" + h + ";");
b.setStyle("-fx-font-size:" + h + ";");
Question 2:
Try to keep all about styles in CSS. It's the best practice.
I use this CSS to add icon to menuItem on JavaFX application:
#mniOpen > .label{
-fx-graphic:url(media/open.png);
}
It works, but one problem: my menuItem has a shortcut key (Ctrl+O), so in this item there are two label. In the result, the icon repeats twice for this menuItem:
How can remove the second icon (for Ctrl+O) ?
Using css
#mniOpen > .label{
-fx-graphic: url("media/open.png");
}
#mniOpen .accelerator-text{
-fx-graphic: none;
}
Without using css
Image openIcon = new Image(getClass().getResourceAsStream("media/open.png"));
ImageView openView = new ImageView(openIcon);
openView.setFitWidth(15);
openView.setFitHeight(15);
MenuItem newMenuItem = new MenuItem("Open");
newMenuItem.setGraphic(openView);
newMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.O, KeyCombination.CONTROL_DOWN));
I have a TableView clear.
I have an button1, when I click this I added a row in my tableView and I select the row. This row is in red by the line css :
.table-row-cell:selected {-fx-background-color: red;}
Next, I have a button2, and I would like that when I click on the button2, the background color on my row selected change in blue.
Help me.
Thanks.
add this code into your .css file:
#blue_cell .table-row-cell:selected{
-fx-background-color: blue;
}
then add this into your java file
button2.setOnAction(e -> productsTable.setId("blue_cell"));
You have many ways for changing the values of properties in css from java code.
You can define a look-up color in css and use setStyle() method in java like that :
.table-view {
-selected-color:red;
}
.table-row-cell:selected{
-fx-background-color: -selected-color;
}
Then use setStyle() method :
button2.setOnAction(e -> table.setStyle("-selected-color:blue;"));
I want to change image set on imageview through css while hover it. Imageview is set on button and while hovering the button the background color will change. Now I need to change image too.
You can assign a style-class to your button and then in your style-sheet add a new style :
.my-button {
-fx-graphic: url("abc.png");
}
.my-button:hover {
-fx-graphic: url("xyz.png");
}
where,
abc.png -> Image present on the button
xyz.png -> New Image to be shown on hover
.my-button -> Style Class assigned to the button
I have these buttons with different size:
Image
How I can make all buttons with same with size?
It depends on layout where the button is located. For example, if you add all the buttons into GridPane or BorderPane, you have to specify each button width to correspond to certain variable. In the following example I wrap all buttons inside VBox, set VBox preference width and tie up all buttons minimum width to it:
VBox vBox = new VBox();
vBox.setPrefWidth(100);
Button btn1 = new Button("Short");
Button btn2 = new Button("Super Long Button");
btn1.setMinWidth(vBox.getPrefWidth());
btn2.setMinWidth(vBox.getPrefWidth());
vBox.getChildren().addAll(btn1, btn2);
It is also worth to mention that there are two ways to specify the button size. You can do it in the java code or specify it in javafx .fxml file. The above method is an example for java code implementation.
You can also unclamp a button's maximum dimensions so it will grow to fill the available space (unlike most nodes, by default a button node has it's max size clamped to it's preferred size so it doesn't usually grow to fill available space). An Oracle tutorial on Tips for Sizing and Aligning Nodes explains this in more detail.
VBox vBox = new VBox();
Button btn1 = new Button("Short");
Button btn2 = new Button("Super Long Button");
btn1.setMaxWidth(Double.MAX_VALUE);
btn2.setMaxWidth(Double.MAX_VALUE);
vBox.getChildren().addAll(btn1, btn2);
using css you can override the preferred width of all buttons like
.button {
-fx-pref-width: 200px;
}
or create your own style class for certain button groups and add the style to the button like:
css:
.my-special-button {
-fx-pref-height: 28px;
-fx-pref-width: 200px;
}
and then set the style to your button with either
fxml:
styleClass="my-special-button"
or in java
myButton.getStyleClass().add("my-special-button");