I have a HTML editor in a Pane container 355px in width. The editor gets cut on the right side where the width overlaps the containing pane. How can I set the HTML Editor's width to a smaller width than that of the parent container?
Please note that I'm on JavaFx SceneBuilder 2 and dragging the width to something smaller than that of the Parent container just doesn't work.
While on Scene Builder 2.0 the HTML editor can't be resized, this just affects the preview (well, maybe it hiddens some other controls,...). If this is really a problem, instead of adding the HTML editor there, just place a container with a proper fx:id and later on the controller add the editor as a child of that container.
Assuming you have the editor added on your FXML, and the width of your scene is 355px, as you say, the first preview of the application will have the toolbars cut, and there won't be any overflow button until you resize the window. Only then, the toolbars will be resized and the overflows will appear.
To overcome this problems and let the editor be resized right after the application is launched, without the manual resize, the workaround is to find the toolbars of the editor, and resize them.
#FXML private HTMLEditor htmlEditor;
#Override
public void initialize(URL url, ResourceBundle rb) {
Platform.runLater(()->{
htmlEditor.lookupAll("ToolBar")
.forEach(node->((ToolBar)node).setPrefWidth(355));
});
}
Note the hardcoded width value, for the sake of simplicity.
Related
I'm building a JavaFX desktop app using scenebuilder for the UI.
Here i have a tilepane inside of a scrollpane, i couldnt use the "fit to parent" option from the context menu in scene builder, i guess the solution is to give them -fx-id's and bind their width in the controller ?
I dont want to use any values so it all comes together nice when the user resizes the window.
how should i go about doing this?
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.
I need a scaled ImageView with a Canvas overlay, stretched over the parent, with a constant margin on the right hand side. This suggests an AnchorPane with the ImageView and Canvas as children, each with a rightAnchor inset representing the margin.
I need to put the AnchorPane in a ScrollPane. The ScrollPane must, when resized, resize both the ImageView and the Canvas overlay within the AnchorPane, while retaining the margin.
I have tried adding the ImageView and Canvas to the AnchorPane, and adding the AnchorPane to the ScrollPane, with ScrollPane.setFitToWidth(true). When I increase the size of the ScrollPane, all works well - both the ImageView and Canvas expand to fill the ScrollPane, retaining the margin on the right hand side.
However, when I reduce the size of the ScrollPane, the size of the AnchorPane is not reducing, but instead the viewport over the AnchorPane is reducing, with increasing scrollbars.
NB, an ImageView inserted directly into the ScrollPane does work - it rescales both on grow and shrink.
It looks as though ScrollPane.setFitToWidth behaviour differs depending on the container inside the ScrollPane.
Is this correct, and can anyone suggest a solution, please?
Robert
Try adding a listener to one of the ScrollPane's Bounds properties and reduce the AnchorPane's size from there when appropriate.
Solved using Jurgen's answer.
I overrode AnchorPane.computeMinHeight, computePrefHeight and computeMaxHeight to return imageView.minHeight, prefHeight and maxHeight. This ties the anchor pane's height to the imageView's height - which the imageView calculates from its own width.
Then I added a listener to the scrollPane.widthProperty which calls the AnchorPane.setPrefWidth, setMinWidth and setMaxWidth
In this way, the anchor pane is correctly signalling its preferred, minimum and maximum width to the enclosing scrollPane.
I have a JavaFX 2.2 TilePane with several items (children). I've added css so that on mouse hover, the scale of the item is set to 1.2. By default, the order of children defines what node is drawn first and what last. Is there a way to make hovering item be above all others, without resorting to toFront() and making it be the last item (moving it to the end). This question is similar to https://stackoverflow.com/questions/13893514/scaling-children-in-a-flowpane-makes-the-children-clip-eachother (still unanswered).
Screenshot of the issue is located at: http://vladeck.files.wordpress.com/2013/03/javafx_tilepane.png?w=640
Solution / Workaround
Use a GridPane instead of a TilePane.
When the user clicks on an item in the grid, call toFront on the item.
Sample Code
I added the following code to a calculator which is based on a grid layout which looks similar to the tiled layout in your sample screenshot. With the modified application, I experienced no overlapping of buttons of the calculator. Surprising to me, though they looked a little weird, the scaled buttons made the calculator easier to use...
button.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
button.toFront();
button.setScaleX(1.6); button.setScaleY(1.6);
}
});
button.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
button.setScaleX(1); button.setScaleY(1);
}
});
Background
As you note, the overlapping issue is unresolvable in some stock Panes like TilePane. This is because the z-order as well as the relative layout position of a node are both defined by the relative position of the node in the TilePane's child list. In such Panes, you cannot change the z-order and bring it to the front without also moving the node to the last layout position in the TilePane.
A GridPane does not suffer from the same issues as a TilePane because it's child node list order only defines the z-order of it's child nodes, not the layout positioning of those child nodes.
Is there a way (a hack?) to implement my own code of retrieving the children order for drawing when JavaFX repaints TilePanel?
Yes, you could hack the TilePane code if you have the skills.
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!