Justplayit94 Justplayit94 - 2 months ago 13
CSS Question

JavaFX Buttons grow with one pixel after their neighbor is pressed

I'm making a GUI in JavaFX, and I've stripped the window of the decorations that Windows did and I have made my own controls for

close
,
minimize
, and
maximize
.

The controls work great, but it seems that when I press one of them, it's neighbors change vertical size, increasing it by one or two pixels, as you can see in this image.

enter image description here

Why is this happening?
Im also attaching the code I have so far in the
start()
method.

public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("Menu Example");

MenuBar file = new MenuBar();
file.setId("file");

Menu fileMenu = new Menu("File");
fileMenu.getItems().addAll(
new MenuItem("New File..."),
new MenuItem("Open file..."),
new MenuItem("Save file"));
fileMenu.setId("#fileMenu");

Menu editMenu = new Menu("Edit");
editMenu.getItems().addAll(
new MenuItem("Undo"),
new MenuItem("Redo"),
new MenuItem("Cut"),
new MenuItem("Copy"),
new MenuItem("Paste")
);

Button closeButton = new Button("X");
closeButton.setId("closeButton");
closeButton.setOnAction(event -> {
window.close();
});

Button minimizeButton = new Button("_");
minimizeButton.setId("minimizeButton");
minimizeButton.setOnAction(event -> {
window.setIconified(true);
});

Button maximizeButton = new Button("?");
maximizeButton.setId("maximizeButton");
maximizeButton.setOnAction(event -> {
if(!window.isMaximized())
window.setMaximized(true);
else
window.setMaximized(false);
});

file.getMenus().addAll(
fileMenu,
editMenu
);

HBox.setHgrow(file, Priority.ALWAYS);
HBox.setHgrow(closeButton, Priority.NEVER);
HBox.setHgrow(minimizeButton, Priority.NEVER);
HBox.setHgrow(maximizeButton, Priority.NEVER);
VBox.setVgrow(closeButton, Priority.NEVER);

hBox = new HBox();
buttonBox = new HBox();
buttonBox.getChildren().addAll(minimizeButton, maximizeButton, closeButton);
hBox.getChildren().addAll(file, buttonBox);

layout = new BorderPane();
layout.setTop(hBox);

Scene scene = new Scene(layout, 400, 400);
scene.getStylesheets().add("Viper.css");
window.setScene(scene);
// window.setMaximized(true);
window.initStyle(StageStyle.UNDECORATED);
window.show();
}


This is my stylesheet:

.root{
-fx-background-color: #2D2E32;
-fx-font-size: 11px;
}

#file{
-fx-background-color: #3E3F43;
}

#file .label{
-fx-text-fill: #EAEAEA;
}

.context-menu{
-fx-background-color: #3E3F43;

}

#closeButton, #minimizeButton, #maximizeButton{
-fx-background-radius: 0;
-fx-background-color: #3E3F43;
-fx-text-fill: #ffffff;
-fx-font-weight: bold;
}

#closeButton:hover{
-fx-background-color: #E46458;
}

#minimizeButton:hover{
-fx-background-color: #80B1E0;
}

#maximizeButton:hover{
-fx-background-color: #80E089;
}

Answer

Based on you CSS if you add the following selectors to you stylesheet, the problem will be solved:

#closeButton:armed, #closeButton:focused,
#minimizeButton:armed, #minimizeButton:focused,
#maximizeButton:armed, #maximizeButton:focused { 
    -fx-background-insets: 0 0 -1 0, 0, 1, 2;
}

Reason: The default styleheet modena.css defines the background insets of a button like -fx-background-insets: 0 0 -1 0, 0, 1, 2;, but if the Button is in on of the pseudo-states of focused or armed, the insets modified as -fx-background-insets: -0.2, 1, 2, -1.4, 2.6;.

So actually not the vertical size of the neighbours are changed but the vertical size of the armed or focused Button.

Note: If you create a new CSS class like

.windowbutton:armed, .windowbutton:focused {
    -fx-background-insets: 0 0 -1 0, 0, 1, 2;
}

then in the code you assign this class to each Button:

closeButton.getStyleClass().add("windowbutton"); // Similar to other buttons

the CSS structure will be a little but more clean.

Comments