Reputation: 13
Would anyone know how to configure a JavaFX titledPane in such a way that the expansion always takes place in the foreground? As is the case with the expansion of a ComboBox button. When the region of the panel containing the titledPane is smaller than the expansion region, the expansion occurs behind the invaded area. How to do that in front of the invaded region. The sample code shows this scenario. The functionality I wish could be implemented with the use of a comboBox button containing buttons, but I like the effect created in the titledPane expansion and would like to use it alternately. Thank you in advance.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
TitledPane titledPane = new TitledPane();
titledPane.setPrefWidth(180);
titledPane.setBorder(new Border(new BorderStroke(Color.MAGENTA, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(1))));
Button btnSave = new Button();
btnSave.setPrefWidth(180);
btnSave.setText("Save");
btnSave.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
Button btnLeftSend = new Button();
btnLeftSend.setPrefWidth(180);
btnLeftSend.setText("Sent to Left");
btnLeftSend.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
Button btnRightSend = new Button();
btnRightSend.setPrefWidth(180);
btnRightSend.setText("Sent to right");
btnRightSend.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
VBox buttons = new VBox(3);
buttons.setPrefWidth(180);
buttons.getChildren().addAll(btnSave, btnLeftSend, btnRightSend);
titledPane.setAnimated(true);
titledPane.setText("Options");
titledPane.setContent(buttons);
titledPane.setExpanded(false);
Button btnLine1 = new Button();
btnLine1.setPrefWidth(180);
btnLine1.setText("Force expand");
btnLine1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(true);
}
});
HBox line1 = new HBox(5);
line1.setPadding(new Insets(5, 0, 0, 0));
line1.setAlignment(Pos.TOP_CENTER);
line1.setMaxSize(380, 40);
line1.setMinSize(380, 40);
line1.setPrefSize(380, 40);
line1.setBorder(new Border(new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(1))));
line1.getChildren().addAll(btnLine1, titledPane);
Button btnLine2 = new Button();
btnLine2.setPrefWidth(180);
btnLine2.setText("Force shrink");
btnLine2.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
HBox line2 = new HBox(5);
line2.setPadding(new Insets(5, 0, 0, 0));
line2.setAlignment(Pos.TOP_CENTER);
line2.setMaxSize(380, 40);
line2.setMinSize(380, 40);
line2.setPrefSize(380, 40);
line2.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(1))));
line2.getChildren().add(btnLine2);
VBox layout = new VBox(5);
layout.setPadding(new Insets(5));
layout.getChildren().addAll(line1, line2);
Scene scene = new Scene(layout, 390, 160);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
scene.setFill(Color.GHOSTWHITE);
primaryStage.setTitle("Sample code for StackOverFlow");
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 0
Views: 342
Reputation: 13
Many thanks for the reply. I replaced the VBox with GridPane in my application and it worked as I wanted it to. For the purpose of helping other people with the same problem, follow the modified code at the suggestion of James_D.
package application;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
TitledPane titledPane = new TitledPane();
titledPane.setPrefWidth(180);
Button btnSave = new Button();
btnSave.setPrefWidth(180);
btnSave.setText("Save");
btnSave.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
Button btnLeftSend = new Button();
btnLeftSend.setPrefWidth(180);
btnLeftSend.setText("Sent to Left");
btnLeftSend.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
Button btnRightSend = new Button();
btnRightSend.setPrefWidth(180);
btnRightSend.setText("Sent to right");
btnRightSend.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(false);
}
});
VBox buttons = new VBox(3);
buttons.setPrefWidth(180);
buttons.getChildren().addAll(btnSave, btnLeftSend, btnRightSend);
titledPane.setAnimated(true);
titledPane.setText("Options");
titledPane.setContent(buttons);
titledPane.setExpanded(false);
Button btnLine1 = new Button();
btnLine1.setPrefWidth(180);
btnLine1.setText("Force expand");
btnLine1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
titledPane.setExpanded(true);
}
});
HBox line1 = new HBox(5);
line1.setPadding(new Insets(5, 0, 0, 0));
line1.setAlignment(Pos.TOP_CENTER);
line1.setMaxSize(380, 40);
line1.setMinSize(380, 40);
line1.setPrefSize(380, 40);
line1.getChildren().addAll(btnLine1, titledPane);
Button btnDummy = new Button();
btnDummy.setPrefWidth(365);
btnDummy.setText("Anything here. Just an example");
HBox line2 = new HBox(5);
line2.setPadding(new Insets(5, 0, 0, 0));
line2.setAlignment(Pos.TOP_CENTER);
line2.setMaxSize(380, 40);
line2.setMinSize(380, 40);
line2.setPrefSize(380, 40);
line2.getChildren().add(btnDummy);
GridPane layout = new GridPane();
layout.setVgap(5);
layout.setPadding(new Insets(5));
layout.add(line2, 0, 1);
layout.add(line1, 0, 0);
Scene scene = new Scene(layout, 390, 160);
primaryStage.setTitle("Sample code for StackOverFlow");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 0
Reputation: 209330
The z-order of nodes is controlled by the order in which they are added to their parent. If you use a VBox
, of course, this order also determines the position of the node within the VBox
. Consider instead using, for example, a grid pane, so you can control the position independently of the order in which the child nodes are added. Then just add line1
after adding line2
:
// VBox layout = new VBox(5);
// layout.setPadding(new Insets(5));
// layout.getChildren().addAll(line1, line2);
GridPane layout = new GridPane();
layout.setVgap(5);
layout.setPadding(new Insets(5));
layout.add(line2, 0, 1);
layout.add(line1, 0, 0);
Upvotes: 1