How to align center Label in JavaFX / FXML? - javafx

How can I center the text of a Label in javafx ? In the .css stylesheet or directly in the fxml.
I tried Label { -fx-text-alignment: center;} in the .css but it does not work. Even in the scene builder it does not work.

You basically have two choices:
Use a layout pane that can center the label, and let the label be its "preferred size" (i.e. just big enough to hold the text), or
Make the label fill the entire width of its container, and set its alignment property to center.
You said in the comments that you're using an AnchorPane as the label's parent. This generally isn't usually a particularly good choice for a layout pane (essentially you have to hardcode the bounds of each control), and you can't center things in it (not without a large amount of work, anyway). So with an anchor pane as parent, you are reduced to choice 2:
label.setMaxWidth(Double.MAX_VALUE);
AnchorPane.setLeftAnchor(label, 0.0);
AnchorPane.setRightAnchor(label, 0.0);
label.setAlignment(Pos.CENTER);
Obviously, all that can be set in FXML too.
In general, though, I would recommend using a more appropriate layout pane and setting the appropriate properties on that layout pane to center the label.

Related

Javafx line connecting two circles in a stackpane [duplicate]

I was learning javafx and came across these two statements which I don't know their difference.
Pane pane = new Pane();
and
StackPane pane = new StackPane();
Can somebody enlighten me about the difference and when to use which?
Both are layouts but the Pane is the basis of all the other layouts, the difference is that the Pane offers a free positioning of nodes, and The StackPane (and other Node with the suffix Pane called Built-in Layout) in return, follow their own logic (Positions/Constraints...). The 'StackPane' for example lays out its children in a back-to-front stack StackPane. This is only superficial and limited information, here's a good tutorial : Layout in JavaFX
The difference between both layouts is positioning of the children and the resizing of resizeable children.
Pane does not do any positioning. The child's layoutX and layoutY are left unmodified. Furthermore resizeable children are resized to their preferred sizes.
StackPane determines the position of children based on the alignment set for the child itself or the one set for the StackPane itself, if no position is set for the child. Resizable children are resized to a size that fits the StackPane's size best (still taking into account max size). Both can be modified by a margin set for individual children...

JavaFX alignment of Label in GridPane

I'm confused as to why setting the Label.setAlignment(Pos.CENTER_RIGHT) does not affect the alignment of a label that is then added into a GridPane? The only way to do it is seemingly through the grid (e.g. ColumnConstraints) or by e.g. adding the Label to a HBox that has right alignment.
Why does setting the alignment of the label to CENTER_RIGHT have no effect? I can see the API says: "Specifies how the text and graphic within the Labeled should be aligned when there is empty space within the Labeled." But how do I get empty space in a label?
TL:DR version: instead of label.setAlignment(Pos.CENTER_RIGHT); use GridPane.setHalignment(label, HPos.RIGHT);.
JavaFX uses a top-down layout. So the scene sizes the root node to the size of the scene, the root node sizes and positions each of its child nodes depending on its layout strategy and the amount of space the scene gave it, each child node then sizes and positions its child nodes depending on its own layout strategy and the amount of space it has available, and so on down the scene graph.
According to the documentation for Label, the alignmentProperty
Specifies how the text and graphic within the Labeled should be aligned when there is empty space within the Labeled.
Of course, the amount of space available to the label is determined by its parent, which in this case is the grid pane. You can of course find out about the grid pane's layout strategy and how to configure it by reading its documentation. In brief, though:
By default, a grid pane will allocate each node its preferred size, and, if the cell it's placed in has additional space, will align the node in the top left of the grid cell. The preferred size for a label is of course the computed size: just big enough to hold its content. Hence you see that simply placing a label into a grid pane and setting alignment on the label will not have any effect, because the label is sized just large enough to hold its content, and there is no extra space to align the text/graphic. You can visualize this by placing a background color or border on the label.
So you could set the alignment on the label to CENTER_RIGHT, and then instruct the grid pane to let the label grow. This needs two things: first, tell the grid pane to let the label fill the width of the cell:
GridPane.setFillWidth(label, true);
and, since the grid pane will also respect the child node's maximum size, and the label by default uses its preferred size as its maximum size, allow the label to grow:
label.setMaxWidth(Double.MAX_VALUE);
Then the label will grow to the size of the cell, and so if you also have
label.setAlignment(Pos.CENTER_RIGHT);
it will align its own content to the right.
A more sensible approach is probably just to tell the grid pane how to align the label in the cell:
GridPane.setHalignment(label, HPos.RIGHT);
Then let the label take on its default size and alignment and everything will work.
You can also use a ColumnConstraints object to set the default alignment for all labels in a particular column, which is by far the more convenient approach if you are building a form.

JavaFX Scenebuilder moving elements inside StackPane

I am trying to move things such as buttons and labels that I put inside a StackPane since I want these things to stay centered when minimizing or maximizing windows. When I put everything I want into the StackPane, they all get centered and layered up on each other. How am I able to move these elements around in the StackPane if it's possible or how will I be able to keep everything centered when resizing the window?
You edit their TranslateX and TranslateY properties. for instance
Label label1 = new Label();
label1.setText("0");
label1.TranslateX(-10.0); //<< moves the label 10 pixels to the left.
if you are using Scene Builder you can edit these properties on the right under the "layout" tab.

Flex: adding/removing component from HBox.rawChildren causes horizontalAlign to fail?

I have an HBox displaying a series of canvases. I am removing a child of a canvas and adding it to the rawChildren of the containing HBox, so I can position it, and make it appear to shift outside the bounds of the canvas.
Here is the code from the canvas:
private function onMouseOver(e:MouseEvent):void
{
(this.parent as HBox).rawChildren.addChild(dateLabel);
dateLabel.x = (this.parent as HBox).localToGlobal(new Point(this.x,0)).x - 18;
}
private function onMouseOut(e:MouseEvent):void
{
addChild(dateLabel);
dateLabel.x = 0;
}
It works, but if the containing HBox.horizontalAlign is set to "right", when I add the child back to the Canvas, the HBox stops displaying correctly and puts all the child canvases overlapping on the right. There is no issue if the HBox is aligned "left" tho.
Is this a bug? Is there a work around?
Thanks!!
Is this a bug? Is there a work around?
- John Isaacks
This isn't a bug as such, it's more that you are using a container in an unusual way.
When you use an HBox you are making a decision that all children are laid out in a linear, horizontal arrangement according to the rules of the HBox component.
Explicitly positioning a child is not what HBoxes are about - it's not in their job description.
I would recommend that you have an HBox inside a Canvas. You can add the dateLabel to the HBox when it should be laid out horizontally or move it to the Canvas when you need to set its position and make it look like it's outside the HBox.
When you use rawChildren, you simply bypass the layout mechanism.
You should use addChild or addChildAt directly on the component.

Flex Vertical Scroll bar problem

I have a problem in flex scroll bars. I have a mxml component based on canvas. Inside that I have used a VBox for my form. Above that Vbox I have another canvas just for title.
My form gets longer than normal screen size when the grid inside that is filled with more data. In that case I want a vertical scroll bar just for Vbox in which my form is located. But the whole canvas is getting scrollbar including title canvas. how to solve this problem.
I set vertical scrollbar policy of main canvas to off and inside Vbox's VerticalScrollbarPolicy to on. but that's not working. It is not overriding the property of parent container.
Thanks.
Keep your Form inside a Canvas inside the parent canvas instead of VBox. VBox and HBox are set to grow automatically in the parent container, so if your form grows, your corresponding VBox will grow as well.
You want to overload the "updateDisplayList" function for your parent canvas, and force the height of your form Vbox to be canvasHeight-titleHeight (including padding, space, etc...) so that the VBox never grows larger than the screen. This will solve your problem. Just make sure you check for the existence of the VBox as sometimes the updateDisplayList will be called before it has been instantiated.
Had the same problem myself and decided to take the easy route.
Have the following
App->vbox->[vbox + hbox]
components are dynamically being added to last vbox. Wanted hbox to stay on screen and have scrollbars only in vbox above it(2nd vbox).
Was experiencing the same problem. All containers had scroll policy=off except for last vbox, but when dynamically adding components, when the components filled the vbox > 100%, the outer vbox would start to scroll.
Resolution was simple once I went back to the documentation.
Set scroll policy - horizontal and vert on app and first vbox to off, and also added autoLayout=false. This causes the engine to not resize the components after initialization, ie, they are static sized.
Once I added this property, no more scrollbars except for the inner vbox.
Tada!

Resources