I would like some guidelines on how to implement a slide in transition for a pane when user presses a button, just like Material Design does it for sliding menus.
Th
Finally, I get it done.
They key features are:
Below is a snippet of the source code that controls these effects:
@Override
public void initialize(URL url, ResourceBundle rb) {
...
Rectangle clip = new Rectangle(rootPaneWidth, rootPaneHeight);
rootPane.setClip(clip);
rootPane.getChildren().add(setupShadowPane());
}
private Pane setupShadowPane() {
Pane shadowPane = new Pane();
shadowPane.setStyle(
"-fx-background-color: white;" +
"-fx-effect: dropshadow(gaussian, black, " + shadowSize + ", 0, 0, 0);" +
"-fx-background-insets: " + shadowSize + ";"
);
Rectangle innerBounds = new Rectangle();
Rectangle outerBounds = new Rectangle();
shadowPane.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
innerBounds.relocate(newBounds.getMinX() + shadowSize, newBounds.getMinY() + shadowSize);
innerBounds.setWidth(newBounds.getWidth() - shadowSize * 2);
innerBounds.setHeight(newBounds.getHeight() - shadowSize * 2);
outerBounds.setWidth(newBounds.getWidth());
outerBounds.setHeight(newBounds.getHeight());
Shape clip = Shape.subtract(outerBounds, innerBounds);
shadowPane.setClip(clip);
});
return shadowPane;
}
Slide Menu semi opened
Slide Menu fully opened
Slide Menu closed
I am the author of the example video. I'll repeat the response that I did in the video comments:
"you should think of it as a navigation drawer in android, the navigation drawer in JavaFX would be an AnchorPane with 2 children, first a StackPane that is equivalent to a FrameLayout working as our main content, where transitions of pane are made depending of the chosen item from the left side menu, and ultimately a ListView as our left side menu with a negative translateX that equals to the Listview width. Then when the user presses a button you must play an animation that sest the value of translateX to 0."
You shouldn't use prefWidth() in the interpolate method of the two animations (collapse Panel, expand Pane), because the children don't resize, the margin arrangement is the only constraint that the AnchorPane has.
Check out this example that I did.
https://github.com/marconideveloper/leftsidemenuexample
public class FXMLDocumentController implements Initializable {
@FXML
private Button menu;
@FXML
private AnchorPane navList;
@Override
public void initialize(URL url, ResourceBundle rb) {
//navList.setItems(FXCollections.observableArrayList("Red","Yellow","Blue"));
prepareSlideMenuAnimation();
}
private void prepareSlideMenuAnimation() {
TranslateTransition openNav=new TranslateTransition(new Duration(350), navList);
openNav.setToX(0);
TranslateTransition closeNav=new TranslateTransition(new Duration(350), navList);
menu.setOnAction((ActionEvent evt)->{
if(navList.getTranslateX()!=0){
openNav.play();
}else{
closeNav.setToX(-(navList.getWidth()));
closeNav.play();
}
});
}
}
Here is the fxml:
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" prefWidth="500" prefHeight="500" fx:controller="leftslidemenusample.FXMLDocumentController">
<children>
<ToolBar AnchorPane.topAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" minHeight="56.0" >
<Button text="menu" fx:id="menu" />
</ToolBar>
<StackPane fx:id="mainContent" style="-fx-background-color:rgba(0,0,0,0.30)" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="56.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" >
<children>
</children>
</StackPane>
<AnchorPane fx:id="navList" style="-fx-background-color:white" AnchorPane.topAnchor="56.0" AnchorPane.bottomAnchor="0.0" prefWidth="180.0" translateX="-180" >
<children>
<Label text="left side menu"/>
</children>
</AnchorPane>
</children>
</AnchorPane>