Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8267645 | 8u321 | Kumar Abhishek | P3 | Resolved | Fixed | b01 |
JDK-8262860 | jfx11.0.11 | Abhinay Agarwal | P3 | Closed | Fixed |
Both DialogPane and ContextMenu have a child node with a style-class `graphic-container`. This leads to a corner case where an unwanted style is applied to ContextMenu when it is shown on a DialogPane.
To reproduce:
* Show a Dialog without a Header
* Show a ContextMenu with a MenuItem that has a Graphic Node
* Observe the alignment and spacing of the MenuItem Graphic Node relative to the MenuItem Label text
The same can be reproduced by running the following sample:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class DialogPaneContextMenuCSSBug extends Application {
public static final Image IMAGE = new Image("https://i.imgur.com/qE8IbBz.png");
@Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("JavaFX");
final Button btnHeader = new Button("Header Dialog");
btnHeader.setOnAction(e -> createDialog(primaryStage, DialogPaneType.HEADER_NODE).showAndWait());
final Button btnHeaderText = new Button("Header Text Dialog");
btnHeaderText.setOnAction(e -> createDialog(primaryStage, DialogPaneType.HEADER_TEXT).showAndWait());
final Button btnNoHeader = new Button("No Header Dialog");
btnNoHeader.setOnAction(e -> createDialog(primaryStage, DialogPaneType.NONE).showAndWait());
FlowPane root = new FlowPane(btnHeader, btnHeaderText, btnNoHeader);
root.setHgap(10);
root.setVgap(10);
root.setAlignment(Pos.CENTER);
final Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
// scene.getStylesheets().add(createStyleSheet());
primaryStage.show();
}
private ContextMenu createContextMenu() {
final MenuItem menuItem = new MenuItem("Menu Item Text", new ImageView(IMAGE));
return new ContextMenu(menuItem);
}
private Dialog<String> createDialog(final Stage primaryStage, DialogPaneType dialogPaneType) {
final Dialog<String> dialog = new Dialog<>();
dialog.initOwner(primaryStage);
final DialogPane dialogPane = new DialogPane();
dialog.setOnCloseRequest(e -> dialog.close());
final Label label = new Label("Right click me for context menu");
final ContextMenu contextMenu = createContextMenu();
label.setContextMenu(contextMenu);
switch (dialogPaneType) {
case HEADER_NODE -> dialogPane.setHeader(new Label("Header"));
case HEADER_TEXT -> dialogPane.setHeaderText("Header Text");
}
dialogPane.setGraphic(new ImageView(IMAGE));
dialogPane.setContent(label);
dialogPane.getButtonTypes().add(ButtonType.CANCEL);
dialog.setDialogPane(dialogPane);
return dialog;
}
private enum DialogPaneType {
HEADER_NODE,
HEADER_TEXT,
NONE
}
/** */
/* Stylesheet related code */
/* */
private String createStyleSheet() {
Path tempFile = null;
try {
tempFile = Files.createTempFile("", "");
Files.writeString(tempFile, STYLE_SHEET);
} catch (IOException e) {
e.printStackTrace();
}
return tempFile.toUri().toString();
}
private static String STYLE_SHEET =
"""
.dialog-pane:no-header .graphic-container {
-fx-padding: 0em 0.333em 0em 0em;
}
.dialog-pane:no-header > * > .graphic-container {
-fx-padding: 0.833em 0 0 0.833em;
}
""";
}
Fix
-------
The following style in modena.css should be updated:
```
.dialog-pane:no-header .graphic-container {
-fx-padding: 0em 0.333em 0em 0em;
}
```
to
```
.dialog-pane:no-header > * > .graphic-container {
-fx-padding: 0em 0.333em 0em 0em;
}
```
Workaround
-----------------
The above CSS should be added to Application
To reproduce:
* Show a Dialog without a Header
* Show a ContextMenu with a MenuItem that has a Graphic Node
* Observe the alignment and spacing of the MenuItem Graphic Node relative to the MenuItem Label text
The same can be reproduced by running the following sample:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class DialogPaneContextMenuCSSBug extends Application {
public static final Image IMAGE = new Image("https://i.imgur.com/qE8IbBz.png");
@Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("JavaFX");
final Button btnHeader = new Button("Header Dialog");
btnHeader.setOnAction(e -> createDialog(primaryStage, DialogPaneType.HEADER_NODE).showAndWait());
final Button btnHeaderText = new Button("Header Text Dialog");
btnHeaderText.setOnAction(e -> createDialog(primaryStage, DialogPaneType.HEADER_TEXT).showAndWait());
final Button btnNoHeader = new Button("No Header Dialog");
btnNoHeader.setOnAction(e -> createDialog(primaryStage, DialogPaneType.NONE).showAndWait());
FlowPane root = new FlowPane(btnHeader, btnHeaderText, btnNoHeader);
root.setHgap(10);
root.setVgap(10);
root.setAlignment(Pos.CENTER);
final Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
// scene.getStylesheets().add(createStyleSheet());
primaryStage.show();
}
private ContextMenu createContextMenu() {
final MenuItem menuItem = new MenuItem("Menu Item Text", new ImageView(IMAGE));
return new ContextMenu(menuItem);
}
private Dialog<String> createDialog(final Stage primaryStage, DialogPaneType dialogPaneType) {
final Dialog<String> dialog = new Dialog<>();
dialog.initOwner(primaryStage);
final DialogPane dialogPane = new DialogPane();
dialog.setOnCloseRequest(e -> dialog.close());
final Label label = new Label("Right click me for context menu");
final ContextMenu contextMenu = createContextMenu();
label.setContextMenu(contextMenu);
switch (dialogPaneType) {
case HEADER_NODE -> dialogPane.setHeader(new Label("Header"));
case HEADER_TEXT -> dialogPane.setHeaderText("Header Text");
}
dialogPane.setGraphic(new ImageView(IMAGE));
dialogPane.setContent(label);
dialogPane.getButtonTypes().add(ButtonType.CANCEL);
dialog.setDialogPane(dialogPane);
return dialog;
}
private enum DialogPaneType {
HEADER_NODE,
HEADER_TEXT,
NONE
}
/** */
/* Stylesheet related code */
/* */
private String createStyleSheet() {
Path tempFile = null;
try {
tempFile = Files.createTempFile("", "");
Files.writeString(tempFile, STYLE_SHEET);
} catch (IOException e) {
e.printStackTrace();
}
return tempFile.toUri().toString();
}
private static String STYLE_SHEET =
"""
.dialog-pane:no-header .graphic-container {
-fx-padding: 0em 0.333em 0em 0em;
}
.dialog-pane:no-header > * > .graphic-container {
-fx-padding: 0.833em 0 0 0.833em;
}
""";
}
Fix
-------
The following style in modena.css should be updated:
```
.dialog-pane:no-header .graphic-container {
-fx-padding: 0em 0.333em 0em 0em;
}
```
to
```
.dialog-pane:no-header > * > .graphic-container {
-fx-padding: 0em 0.333em 0em 0em;
}
```
Workaround
-----------------
The above CSS should be added to Application
- backported by
-
JDK-8267645 Incorrect CSS applied to ContextMenu on DialogPane
- Resolved
-
JDK-8262860 Incorrect CSS applied to ContextMenu on DialogPane
- Closed