An AnchorPane
is similar to a BorderPane
(see my previous post JavaFX 2.0 Layout Panes - BorderPane) as it also provides several areas or regions for your nodes.
In contrast to a BorderPane
, an AnchorPane
provides only four different regions: Left, Right, Bottom and Top (a BorderPane
additionally provides a center region).
There are several more major differences between the two panes:
-
In an
AnchorPane
you can anchor multiple nodes to one area (in aBorderPane
you can only set one node to each area). -
In an
AnchorPane
you can anchor one single node to multiple areas, i.e. anchoring aButton
to the left and the top of theAnchorPane
, whereas in aBorderPane
every node can only be applied to one area. -
In an
AnchorPane
you can specify the offset to the anchor. -
A
BorderPane
provides instance methods to populate each area (i.e.setCenter(Node node)
,setRight(Node node)
, ...). AnAnchorPane
offers static methods likeAnchorPane.setTopAnchor(Node node, Double offset)
that are applied directly to aNode
. -
In a
BorderPane
each child will grow and shrink with its parent depending on the area it is applied to. In anAnchorPane
children will only be resized/stretched if they are anchored to opposite sides of the pane. For example if aButton
is anchored to the left and the right anchor of anAnchorPane
, theButton
will be stretched horizontally.
Please take a look at this first simple example:
AnchorPane – Example 1
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; import javafx.stage.Stage; /** * Created on: 16.06.2012 * @author Sebastian Damm */ public class AnchorPaneExample extends Application { private final String LABEL_STYLE = "-fx-font: 20pt Cambria; " + "-fx-text-fill: white; " + "-fx-effect: dropshadow(one-pass-box, black, 10, 0, 3, 3);"; @Override public void start(Stage primaryStage) throws Exception { AnchorPane root = new AnchorPane(); Scene scene = new Scene(root, 400, 200, Color.ROYALBLUE); Label lb1 = new Label("Top Anchor"); lb1.setStyle(LABEL_STYLE); AnchorPane.setTopAnchor(lb1, 10d); AnchorPane.setLeftAnchor(lb1, 150d); Label lb2 = new Label("Right Anchor"); lb2.setStyle(LABEL_STYLE); AnchorPane.setRightAnchor(lb2, 10d); AnchorPane.setTopAnchor(lb2, 85d); Label lb3 = new Label("Bottom Anchor"); lb3.setStyle(LABEL_STYLE); AnchorPane.setBottomAnchor(lb3, 10d); AnchorPane.setLeftAnchor(lb3, 138d); Label lb4 = new Label("Left Anchor"); lb4.setStyle(LABEL_STYLE); AnchorPane.setLeftAnchor(lb4, 10d); AnchorPane.setTopAnchor(lb4, 85d); root.getChildren().addAll(lb1, lb2, lb3, lb4); primaryStage.setTitle("AnchorPaneExample 1"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { Application.launch(args); } }
For this first example we just create some Labels
, apply some custom style (a dedicated post about css styling in an external css file will be posted once the series about layout panes is done) and anchor them at two anchors. The last step is to add all labels to the collection of childrens of the AnchorPane
. Otherwise, the applied anchors won´t have any effect.
Your application should look like this now:
If you resize your window, it should look like one of the following two pictures:
You can see, that all labels maintain their position based on the anchors, they were applied to and the given offset.
In the next small example you will see the 'stretching' of the child nodes i mentioned at the beginning of this blog post:
AnchorPane – Example 2: Stretching child nodes
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.stage.Stage; /** * Created on: 16.06.2012 * @author Sebastian Damm */ public class AnchorPaneExample2 extends Application { @Override public void start(Stage primaryStage) throws Exception { AnchorPane root = new AnchorPane(); Scene scene = new Scene(root, 400, 200, Color.ROYALBLUE); Button b1 = new Button("Button 1"); AnchorPane.setTopAnchor(b1, 10d); AnchorPane.setLeftAnchor(b1, 20d); AnchorPane.setRightAnchor(b1, 20d); Button b2 = new Button("Button 2"); AnchorPane.setTopAnchor(b2, 50d); AnchorPane.setBottomAnchor(b2, 20d); AnchorPane.setLeftAnchor(b2, 170d); root.getChildren().addAll(b1, b2); primaryStage.setTitle("AnchorPaneExample 2 - Stretching child nodes"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { Application.launch(args); } }
This example contains two buttons, that are anchored to opposite sides of the AnchorPane
(the third anchor is only applied to prevent an overlay of the two buttons). In order to keep the specified offset, the AnchorPane
will stretch the Node
, as long as it is a resizable Node
. In the case of a non-resizable Node
, only the top and the left anchor will be considered.
This code should result in something like this:
By resizing the window, the buttons should be stretched like in the following two screenshots:
So, these are the basics of the AnchorPane
. Generally, i like a BorderPane
more, but i think thats also up to personal preferences, because you can create the same layout in both panes. But in my experience, most layouts could be realized faster and with less code in a BorderPane
.
Nice tutorial. Thank you!
ReplyDeletethank you. you've been the most helpful site i've found so far.
ReplyDeleteReplica Audemars Piguet Watches, combining elegant style and cutting-edge technology, a variety of styles of Replica Audemars Piguet royal oak Watches, the pointer walks between your exclusive taste style.
ReplyDelete